- 了解过(用过)react或者angular吗,他们有什么区别?
- vue单页面和传统的多页面区别?
- 那首先谈谈你对Vue的理解吧?
- ⭐️ 你刚刚说到了MVVM,能详细说说吗?
- vue是如何实现响应式数据的呢?(响应式数据原理)❗
- 那vue中是如何检测数组变化的呢?
- 那你说说Vue的事件绑定原理吧
- v-model中的实现原理及如何自定义v-model ❗
- 为什么Vue采用异步渲染呢?
- 了解nextTick吗?
- 说说Vue的生命周期吧 ❗
- 父子组件生命周期调用顺序(简单)
- Vue组件通信 ❗
- Vuex 工作原理
- 如何从真实DOM到虚拟DOM
- 用VNode来描述一个DOM结构
- diff算法
- computed、 watch 和 method
- filter的理解和用法
- v-if 和 v-show 区别
- vue常用的修饰符
- vue更新数组时触发视图更新的方法
- v-for中的key的理解?
- v-for和v-if为什么不能连用
- v-html 会导致哪些问题(简单)
- 描述组件渲染和更新过程
- 组件中的data为什么是函数
- 为什么要使用异步组件?
- action 与 mutation 的区别
- 插槽与作用域插槽的区别
- vue中相同逻辑如何抽离
- 谈谈对keep-alive的了解
- vue-router实现懒加载的方式
- Vue性能优化
- 路由
- route和router的区别
- vue-roter的钩子函数
- Vuex
了解过(用过)react或者angular吗,他们有什么区别?
Vue借鉴了angular的模板和数据绑定技术,又借鉴了react的组件化和虚拟 DOM 技术
Vue
轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;
简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
双向数据绑定:保留了angular的特点,在数据操作方面更为简单;
组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势;
视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
虚拟DOM:dom操作是非常耗费性能的, 不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式;
运行速度更快:相比较与react而言,同样是操作虚拟dom,就性能而言,vue存在很大的优势。
React
相同点:
React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用;中心思想相同:一切都是组件,组件实例之间可以嵌套;都提供合理的钩子函数,可以让开发者定制化地去处理需求;都不内置列数AJAX,Route等功能到核心包,而是以插件的方式加载;在组件开发中都支持mixins的特性。
不同点:
React采用的Virtual DOM会对渲染出来的结果做脏检查;Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作Virtual DOM。
Angular
相同点:
都支持指令:内置指令和自定义指令;都支持过滤器:内置过滤器和自定义过滤器;都支持双向数据绑定;都不支持低端浏览器。
不同点:
AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观;在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢;Vue.js使用基于依赖追踪的观察并且使用异步队列更新,所有的数据都是独立触发的。
vue单页面和传统的多页面区别?
单页面应用(SPA)
通俗一点说就是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多应用于pc端。
多页面(MPA)
单页面的优点:
用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小;前后端分离;页面效果会比较炫酷(比如切换页面内容时的专场动画)。
单页面缺点:
不利于seo;导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理);初次加载时耗时多;页面复杂度提高很多。
那首先谈谈你对Vue的理解吧?
关键点: 渐进式 JavaScript 框架、核心库加插件、动态创建用户界面(异步获取后台数据,数据展示在界面)
特点: MVVM 模式;代码简洁体积小,运行效率高,适合移动PC端开发;本身只关注 UI (和 react 相似),可以轻松引入 Vue 插件或其他的第三方库进行开发。
⭐️ 你刚刚说到了MVVM,能详细说说吗?
MVVM 是 Model-View-ViewModel的缩写,即将数据模型与数据表现层通过数据驱动进行分离,从而只需要关系数据模型的开发,而不需要考虑页面的表现,具体说来如下:
Model代表数据模型:主要用于定义数据和操作的业务逻辑。
View代表页面展示组件(即dom展现形式):负责将数据模型转化成UI 展现出来。
ViewModel为model和view之间的桥梁:监听模型数据的改变和控制视图行为、处理用户交互。通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉
在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。
数据绑定到 viewModel 层并自动渲染到页面中,视图变化通知 viewModel 层更新数据。
vue是如何实现响应式数据的呢?(响应式数据原理)❗
Vue2: Object.defineProperty 重新定义 data 中所有的属性, Object.defineProperty 可以使数据的获取与设置增加一个拦截的功能,拦截属性的获取,进行依赖收集。拦截属性的更新操作,进行通知。
具体的过程:首先Vue使用 initData 初始化用户传入的参数,然后使用 new Observer 对数据进行观测,如果数据是一个对象类型就会调用 this.walk(value) 对对象进行处理,内部使用 defineeReactive 循环对象属性定义响应式变化,核心就是使用 Object.defineProperty 重新定义数据
🌸刚刚如果你说了对象的检测,然后又没说清楚数组的处理的话,我就会问下面这个问题:
那vue中是如何检测数组变化的呢?
数组就是使用 object.defineProperty
重新定义数组的每一项,那能引起数组变化的方法我们都是知道的, pop
、push
、 shift
、 unshift
、 splice
、 sort
、 reverse
这七种,只要这些方法执行改了数组内容,我就更新内容就好了,是不是很好理解。
- 是用来函数劫持的方式,重写了数组方法,具体呢就是更改了数组的原型,更改成自己的,用户调数组的一些方法的时候,走的就是自己的方法,然后通知视图去更新。
- 数组里每一项可能是对象,那么我就是会对数组的每一项进行观测,(且只有数组里的对象才能进行观测,观测过的也不会进行观测)
那你说说Vue的事件绑定原理吧
原生 DOM 的绑定:Vue在创建真实DOM时会调用 createElm
,默认会调用 invokeCreateHooks
。会遍历当前平台下相对的属性处理代码,其中就有 updateDOMListeners
方法,内部会传入 add()
方法
组件绑定事件,原生事件,自定义事件;组件绑定之间是通过Vue中自定义的 $on
方法实现的。
(可以理解为:组件的 nativeOnOn
等价于 普通元素on 组件的on会单独处理)
v-model中的实现原理及如何自定义v-model ❗
v-model
可以看成是 value+input
方法的语法糖(组件)。原生的 v-model
,会根据标签的不同生成不同的事件与属性。解析一个指令来。
自定义:自己写 model
属性,里面放上 prop
和 event
👍还行哟~知道响应式数据和数据绑定问完了,接着问问渲染呗:
为什么Vue采用异步渲染呢?
批量异步策略:
Vue 在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成之后,再统一进行视图更新。
Vue 是组件级更新,如果不采用异步更新,那么每次更新数据都会对当前组件进行重新渲染,所以为了性能, Vue 会在本轮数据更新后,在异步更新视图。核心思想 nextTick
。dep.notify()
通知 watcher 进行更新, subs[i].update
依次调用 watcher 的 update
, queueWatcher 将watcher 去重放入队列, nextTick( flushSchedulerQueue )
在下一tick中刷新watcher队列(异步)。
了解nextTick吗?
异步方法,异步渲染最后一步,与JS事件循环联系紧密。主要使用了宏任务微任务(setTimeout、promise那些),定义了一个异步方法,多次调用nextTick会将方法存入队列,通过异步方法清空当前队列。
在vue中理解修改数据后,对应的dom需要一定的时间进行更新,因此为了能够准确的后去更新后的dom,可以采用延迟回调的方法进行更新dom的获取,所以出现了$nextTick来进行延迟回调。即:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
说说Vue的生命周期吧 ❗
总共分为8个阶段,具体为:创建前/后,载入前/后,更新前/后,销毁前/后。
什么时候被调用?
- beforeCreate :实例初始化之后,数据观测之前调用。Vue实例的挂载元素$el和数据对象data都为undefined,还未初始化
- created:实例创建完之后调用。实例完成:数据观测、属性和方法的运算、 watch/event 事件回调。有data,无 $el (data 和 methods都已经被初始化好了,如果要调用 methods 中的方法,或者操作 data 中的数据,最早可以在这个阶段中操作)
- beforeMount:在挂载之前调用,相关 render 函数首次被调用。vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换
- mounted:了被新创建的vm.$el替换,并挂载到实例上去之后调用改钩子。vue实例挂载完成,data.message成功渲染。
- beforeUpdate:数据更新前调用,发生在虚拟DOM重新渲染和打补丁,在这之后会调用改钩子。
- updated:由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用改钩子。
- beforeDestroy:实例销毁前调用,实例仍然可用。
- destroyed:实例销毁之后调用,调用后,Vue实例指示的所有东西都会解绑,所有事件监听器和所有子实例都会被移除。
每个生命周期内部可以做什么?
- created:实例已经创建完成,因为他是最早触发的,所以可以进行一些数据、资源的请求。可操作data和methods
- mounted:实例已经挂载完成,可以进行一些DOM操作。
- beforeUpdate:可以在这个钩子中进一步的更改状态,不会触发重渲染。
- updated:可以执行依赖于DOM的操作,但是要避免更改状态,可能会导致更新无线循环。
- destroyed:可以执行一些优化操作,清空计时器,解除绑定事件。
ajax放在哪个生命周期?:一般放在 mounted 中,保证逻辑统一性,因为生命周期是同步执行的, ajax 是异步执行的。单数服务端渲染 ssr 同一放在 created 中,因为服务端渲染不支持 mounted 方法。
什么时候使用beforeDestroy?:当前页面使用 $on ,需要解绑事件。清楚定时器。解除事件绑定, scroll mousemove 。
父子组件生命周期调用顺序(简单)
渲染顺序:先父后子,完成顺序:先子后父
更新顺序:父更新导致子更新,子更新完成后父
销毁顺序:先父后子,完成顺序:先子后父
Vue组件通信 ❗
- 父子间通信:父亲提供数据通过属性 props传给儿子;儿子通过 $on 绑父亲的事件,再通过 $emit 触发自己的事件(发布订阅)
- 利用父子关系 $parent 、 $children ,
获取父子组件实例的方法。
- 父组件提供数据,子组件注入。 provide 、 inject ,插件用得多。
- ref 获取组件实例,调用组件的属性、方法
- 跨组件通信 Event Bus (Vue.prototype.bus=newVue)其实基于bus = new Vue)其实基于bus=newVue)其实基于on与$emit
- vuex 状态管理实现通信
Vuex 工作原理
- Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
状态自管理应用包含以下几个部分:
- state,驱动应用的数据源;
- view,以声明方式将 state 映射到视图;
- actions,响应在 view 上的用户输入导致的状态变化。下图单向数据流示意图:
vuex,多组件共享状态,因-单向数据流简洁性很容易被破坏:
- 多个视图依赖于同一状态。
- 来自不同视图的行为需要变更同一状态。
如何从真实DOM到虚拟DOM
涉及到Vue中的模板编译原理,主要过程:
- 将模板转换成 ast 树, ast 用对象来描述真实的JS语法(将真实DOM转换成虚拟DOM)
- 优化树
- 将 ast 树生成代码
用VNode来描述一个DOM结构
虚拟节点就是用一个对象来描述一个真实的DOM元素。首先将 template (真实DOM)先转成 ast , ast 树通过 codegen 生成 render 函数, render 函数里的 _c 方法将它转为虚拟dom
diff算法
时间复杂度: 个树的完全 diff 算法是一个时间复杂度为 O(n3) ,vue进行优化转化成 O(n) 。
*理解:
- 最小量更新, key 很重要。这个可以是这个节点的唯一标识,告诉 diff 算法,在更改前后它们是同一个DOM节点
- 扩展 v-for 为什么要有 key ,没有 key 会暴力复用,举例子的话随便说一个比如移动节点或者增加节点(修改DOM),加 key 只会移动减少操作DOM。
- 只有是同一个虚拟节点才会进行精细化比较,否则就是暴力删除旧的,插入新的。
- 只进行同层比较,不会进行跨层比较。
diff算法的优化策略:四种命中查找,四个指针
- 旧前与新前(先比开头,后插入和删除节点的这种情况)
- 旧后与新后(比结尾,前插入或删除的情况)
- 旧前与新后(头与尾比,此种发生了,涉及移动节点,那么新前指向的节点,移动到旧后之后)
- 旧后与新前(尾与头比,此种发生了,涉及移动节点,那么新前指向的节点,移动到旧前之前)
computed、 watch 和 method
computed:默认computed也是一个watcher具备缓存,只有当依赖的数据变化时才会计算, 当数据没有变化时, 它会读取缓存数据。如果一个数据依赖于其他数据,使用 computed。计算属性基于响应式依赖进行缓存。
watch:每次都需要执行函数。 watch 更适用于数据变化时的异步操作。如果需要在某个数据变化时做一些事情,使用watch。
method:只要把方法用到模板上了,每次一变化就会重新渲染视图,性能开销大
总结:
1)计算属性变量在computed中定义,属性监听在data中定义。
2)计算属性是声明式的描述一个值依赖了其他值,依赖的值改变后重新计算结果更新DOM。属性监听的是定义的变量,当定义的值发生变化时,执行相对应的函数。
filter的理解和用法
1)全局过滤器必须写在vue实例创建之前
Vue.filter('testfilter', function (value,text) { // 返回处理后的值
return value+text
})
2)局部写法:在组件实例对象里挂载。
filters: {
changemsg:(val,text)=>{
return val + text
}
}
3)使用方式:只能使用在{{}}和:v-bind中,定义时第一个参数固定为预处理的数,后面的数为调用时传入的参数,调用时参数第一个对应定义时第二个参数,依次往后类推
<h3 :title="test|changemsg(1234)">{{test|changemsg(4567)}}</h3>
//多个过滤器也可以串行使用
<h2>{{name|filter1|filter2|filter3}}</h2>
4)vue-cli项目中注册多个全局过滤器写法:
//1.创建一个单独的文件定义并暴露函数对象
const filter1 = function (val) {
return val + '--1'
}
const filter2 = function (val) {
return val + '--2'
}
const filter3 = function (val) {
return val + '--3'
}
export default {
filter1,
filter2,
filter3
}
//2.导入main.js(在vue实例之前)
import filters from './filter/filter.js'
//3.循环注册过滤器
Object.keys(filters).forEach(key=>{
Vue.filter(key,filters[key])
})
v-if 和 v-show 区别
共同点:都能控制元素的显示和隐藏;
不同点:
不同点:实现本质方法不同,
- v-show本质就是通过控制css中的display设置为none,控制隐藏,只会编译一次。只是切换当前DOM的显示与隐藏
- v-if是动态的向DOM树内添加或者删除DOM元素,若初始值为false,就不会编译了。而且v-if不停的销毁和创建比较消耗性能。如果条件不成立不会渲染当前指令所在节点的DOM元素
如果要频繁切换某节点,使用v-show(切换开销比较小,初始开销较大)。如果不需要频繁切换某节点使用v-if(初始渲染开销较小,切换开销比较大)。
vue常用的修饰符
.stop:等同于JavaScript中的event.stopPropagation(),防止事件冒泡;
.prevent:等同于JavaScript中的event.preventDefault(),防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播);
.capture:与事件冒泡的方向相反,事件捕获由外到内;
.self:只会触发自己范围内的事件,不包含子元素;
.once:只会触发一次。
vue更新数组时触发视图更新的方法
push();pop();shift();unshift();splice();sort();reverse()
v-for中的key的理解?
需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点。主要是为了高效的更新虚拟DOM。
v-for和v-if为什么不能连用
当v-if与v-for一起使用时,v-for具有比v-if更高的优先级,这意味着v-if将分别重复运行于每个v-for循环中。
v-for 会比 v-if 的优先级更高,连用的话会把 v-if 的每个元素都添加一下,造成性能问题。
v-html 会导致哪些问题(简单)
- XSS 攻击
- v-html 会替换标签内部的元素
描述组件渲染和更新过程
渲染组件时,会通过 vue.extend() 方法构建子组件的构造函数,并进行实例化。最终手动调用 $mount() 进行挂载。更新组件时会进行 patchVnode 流程,核心就是 diff 算法。
组件中的data为什么是函数
避免组件中的数据互相影响。同一个组件被复用多次会创建多个实例,如果 data 是一个对象的话,这些实例用的是同一个构造函数。为了保证组件的数据独立,要求每个组件都必须通过 data 函数返回一个对象作为组件的状态。
为什么要使用异步组件?
- 节省打包出的结果,异步组件分开打包,采用jsonp的方式进行加载,有效解决文件过大的问题。
核心就是包组件定义变成一个函数,依赖 import() 语法,可以实现文件的分割加载。
详细的看官方文档:https://cn.vuejs.org/v2/guide/components-dynamic-async.html#%E5%BC%82%E6%AD%A5%E7%BB%84%E4%BB%B6
action 与 mutation 的区别
- mutation 是同步更新, $watch 严格模式下会报错
action 是异步操作,可以获取数据后调用 mutation 提交最终数据
插槽与作用域插槽的区别
插槽:
创建组件虚拟节点时,会将组件儿子的虚拟节点保存起来。当初始化组件时,通过插槽属性将儿子进行分类 {a:[vnode],b[vnode]}
- 渲染组件时会拿对应的 slot 属性的节点进行替换操作。(插槽的作用域为父组件)
作用域插槽:
- 作用域插槽在解析的时候不会作为组件的孩子节点。会解析成函数,当子组件渲染时,会调用此函数进行渲染。
- 普通插槽渲染的作用域是父组件,作用域插槽的渲染作用域是当前子组件。
vue中相同逻辑如何抽离
其实就是考察 vue.mixin 用法,给组件每个生命周期,函数都混入一些公共逻辑。
谈谈对keep-alive的了解
keep-alive 可以实现组件的缓存,当组件切换时不会对当前组件进行卸载。可以使被包含的组件保留状态,或避免重新渲染。
页面第一次进入,钩子的触发顺序:created-> mounted-> activated,退出时触发 deactivated ,当再次进入(前进或者后退)时,只触发activated事件挂载的方法等,只执行一次的放在 mounted 中;组件每次进去执行的方法放在 activated 中;其有几个属性如下:
常用的2个属性 include/exclude ,2个生命周期 activated , deactivated
1)include - 字符串或正则表达式,只有名称匹配的组件会被缓存
2)exclude - 字符串或正则表达式,任何名称匹配的组件都不会被缓存
3)include 和 exclude 的属性允许组件有条件地缓存。二者都可以用“,”分隔字符串、正则表达式、数组。当使用正则或者是数组时,要记得使用v-bind 。
<!-- 逗号分隔字符串,只有组件a与b被缓存。-->
<keep-alive include="a,b">
<component></component>
</keep-alive>
<!-- 正则表达式 (需要使用 v-bind,符合匹配规则的都会被缓存) -->
<keep-alive :include="/a|b/">
<component></component>
</keep-alive>
<!-- Array (需要使用 v-bind,被包含的都会被缓存) -->
<keep-alive :include="['a', 'b']">
<component></component>
</keep-alive>
vue-router实现懒加载的方式
vue异步组件
vue异步组件技术 ==== 异步加载
vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 。但是,这种情况下一个组件生成一个js文件
/* vue异步组件技术 */
{
path: '/home',
name: 'home',
component: resolve => require(['@/components/home'],resolve)
},{
path: '/index',
name: 'Index',
component: resolve => require(['@/components/index'],resolve)
},{
path: '/about',
name: 'about',
component: resolve => require(['@/components/about'],resolve)
}
es提案的import()
// 下面2行代码,没有指定webpackChunkName,每个组件打包成一个js文件。
/* const Home = () => import('@/components/home')
const Index = () => import('@/components/index')
const About = () => import('@/components/about') */
// 下面2行代码,指定了相同的webpackChunkName,会合并打包成一个js文件。把组件按组分块
const Home = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/home')
const Index = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/index')
const About = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/component/about')
{
path: '/about',
component: About
}, {
path: '/index',
component: Index
}, {
path: '/home',
component: Home
}
webpack的require,ensure()
vue-router配置路由,使用webpack的require.ensure技术,也可以实现按需加载。这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。
/* 组件懒加载方案三: webpack提供的require.ensure() */
{
path: '/home',
name: 'home',
component: r => require.ensure([], () => r(require('@/components/home')), 'demo')
}, {
path: '/index',
name: 'Index',
component: r => require.ensure([], () => r(require('@/components/index')), 'demo')
}, {
path: '/about',
name: 'about',
component: r => require.ensure([], () => r(require('@/components/about')), 'demo-01')
}
Vue性能优化
编码优化:
- 事件代理
- keep-alive
- 拆分组件
- key 保证唯一性
- 路由懒加载、异步组件
- 防抖节流
Vue加载性能优化
- 第三方模块按需导入( babel-plugin-component )
- 图片懒加载
用户体验
- app-skeleton 骨架屏
- shellap p壳
- pwa
SEO优化
- 预渲染
路由
vue的路由模式及区别?
hash模式在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;
特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
history模式:history采用HTML5的新特性;
提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。history 模式下,前端的 URL必须和实际向后端发起请求的URL一致,否则会报404错误
route和router的区别
$router
$router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性,常见的有:
1)push:向 history 栈添加一个新的记录,当我们点击浏览器的返回按钮时可以看到之前的页面
this.$router.push({ name: ‘user’, params: { userId: 123 }})
2)go:页面路由跳转 前进或者后退
this.$router.go(-1)
3)replace:push方法会向 history 栈添加一个新的记录,而replace方法是替换当前的页面,不会向 history 栈添加一个新的记录
$route
$route对象表示当前的路由信息,包含了当前URL解析得到的信息。包含当前的路径、参数、query对象等。
- $route.path:字符串,对应当前路由的路径,总是解析为绝对路径,如 “/foo/bar”。
- $route.params:一个 key/value 对象,包含了 动态片段 和 全匹配片段,如果没有路由参数,就是一个空对象。
- $route.query:一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1,则有 $route.query.user == 1,如果没有查询参数,则是个空对象。
- $route.hash:当前路由的 hash 值 (不带#) ,如果没有 hash 值,则为空字符串。
- $route.fullPath:完成解析后的 URL,包含查询参数和 hash 的完整路径。
- $route.matched:数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
- $route.name:当前路径名字
- $route.meta:路由元信息
vue-roter的钩子函数
全局钩子
主要包括 beforeEach
和 aftrEach
,
- beforeEach函数有三个参数:
- to:router即将进入的路由对象
- from:当前导航即将离开的路由
- next:Function,进行管道中的一个钩子,如果执行完了,则导航的状态就是 confirmed (确认的);否则为false,终止导航。
- afterEach函数不用传next()函数这类钩子主要作用于全局,一般用来判断权限,以及以及页面丢失时候需要执行的操作,例如:
单个路由里面的钩子
组件路由
主要包括 beforeRouteEnter
和 beforeRouteUpdate
, beforeRouteLeave
,这几个钩子都是写在组件里面也可以传三个参数(to,from,next),作用与前面类似.
Vuex
vuex的使用
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化,具体包括:
- state:Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。
- getter:state的计算属性,类似vue的计算属性,主要用来过滤一些数据。
- action:actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。可以异步函数调用
- mutation:mutations定义的方法动态修改Vuex 的 store 中的状态或数据
- modules:项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。