了解过(用过)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 重新定义数据
image.png
🌸刚刚如果你说了对象的检测,然后又没说清楚数组的处理的话,我就会问下面这个问题:

那vue中是如何检测数组变化的呢?

数组就是使用 object.defineProperty 重新定义数组的每一项,那能引起数组变化的方法我们都是知道的, poppushshiftunshiftsplicesortreverse 这七种,只要这些方法执行改了数组内容,我就更新内容就好了,是不是很好理解。

  1. 是用来函数劫持的方式,重写了数组方法,具体呢就是更改了数组的原型,更改成自己的,用户调数组的一些方法的时候,走的就是自己的方法,然后通知视图去更新。
  2. 数组里每一项可能是对象,那么我就是会对数组的每一项进行观测,(且只有数组里的对象才能进行观测,观测过的也不会进行观测)

vue3:改用 proxy ,可直接监听对象数组的变化

那你说说Vue的事件绑定原理吧

原生 DOM 的绑定:Vue在创建真实DOM时会调用 createElm ,默认会调用 invokeCreateHooks 。会遍历当前平台下相对的属性处理代码,其中就有 updateDOMListeners 方法,内部会传入 add() 方法
组件绑定事件,原生事件,自定义事件;组件绑定之间是通过Vue中自定义的 $on 方法实现的。
(可以理解为:组件的 nativeOnOn 等价于 普通元素on 组件的on会单独处理)

v-model中的实现原理及如何自定义v-model ❗

v-model 可以看成是 value+input 方法的语法糖(组件)。原生的 v-model ,会根据标签的不同生成不同的事件与属性。解析一个指令来。
自定义:自己写 model 属性,里面放上 propevent
👍还行哟~知道响应式数据和数据绑定问完了,接着问问渲染呗:

为什么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.vuejs.org/zh/

  • Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式
  • 状态自管理应用包含以下几个部分:

    • state,驱动应用的数据源;
    • view,以声明方式将 state 映射到视图;
    • actions,响应在 view 上的用户输入导致的状态变化。下图单向数据流示意图:

    image.png

  • vuex,多组件共享状态,因-单向数据流简洁性很容易被破坏:

    • 多个视图依赖于同一状态。
    • 来自不同视图的行为需要变更同一状态。

image.png

如何从真实DOM到虚拟DOM

涉及到Vue中的模板编译原理,主要过程:

  1. 将模板转换成 ast 树, ast 用对象来描述真实的JS语法(将真实DOM转换成虚拟DOM)
  2. 优化树
  3. 将 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算法的优化策略:四种命中查找,四个指针

  1. 旧前与新前(先比开头,后插入和删除节点的这种情况)
  2. 旧后与新后(比结尾,前插入或删除的情况)
  3. 旧前与新后(头与尾比,此种发生了,涉及移动节点,那么新前指向的节点,移动到旧后之后)
  4. 旧后与新前(尾与头比,此种发生了,涉及移动节点,那么新前指向的节点,移动到旧前之前)

    computed、 watch 和 method

    computed:默认computed也是一个watcher具备缓存,只有当依赖的数据变化时才会计算, 当数据没有变化时, 它会读取缓存数据。如果一个数据依赖于其他数据,使用 computed。计算属性基于响应式依赖进行缓存。
    watch:每次都需要执行函数。 watch 更适用于数据变化时的异步操作。如果需要在某个数据变化时做一些事情,使用watch。
    method:只要把方法用到模板上了,每次一变化就会重新渲染视图,性能开销大

总结:

1)计算属性变量在computed中定义,属性监听在data中定义。
2)计算属性是声明式的描述一个值依赖了其他值,依赖的值改变后重新计算结果更新DOM。属性监听的是定义的变量,当定义的值发生变化时,执行相对应的函数。

filter的理解和用法

1)全局过滤器必须写在vue实例创建之前

  1. Vue.filter('testfilter', function (value,text) { // 返回处理后的值
  2. return value+text
  3. })

2)局部写法:在组件实例对象里挂载。

  1. filters: {
  2. changemsg:(val,text)=>{
  3. return val + text
  4. }
  5. }

3)使用方式:只能使用在{{}}和:v-bind中,定义时第一个参数固定为预处理的数,后面的数为调用时传入的参数,调用时参数第一个对应定义时第二个参数,依次往后类推

  1. <h3 :title="test|changemsg(1234)">{{test|changemsg(4567)}}</h3>
  2. //多个过滤器也可以串行使用
  3. <h2>{{name|filter1|filter2|filter3}}</h2>

4)vue-cli项目中注册多个全局过滤器写法:

  1. //1.创建一个单独的文件定义并暴露函数对象
  2. const filter1 = function (val) {
  3. return val + '--1'
  4. }
  5. const filter2 = function (val) {
  6. return val + '--2'
  7. }
  8. const filter3 = function (val) {
  9. return val + '--3'
  10. }
  11. export default {
  12. filter1,
  13. filter2,
  14. filter3
  15. }
  16. //2.导入main.js(在vue实例之前)
  17. import filters from './filter/filter.js'
  18. //3.循环注册过滤器
  19. Object.keys(filters).forEach(key=>{
  20. Vue.filter(key,filters[key])
  21. })

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 函数返回一个对象作为组件的状态。

为什么要使用异步组件?

  1. 节省打包出的结果,异步组件分开打包,采用jsonp的方式进行加载,有效解决文件过大的问题。
  2. 核心就是包组件定义变成一个函数,依赖 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 。

  1. <!-- 逗号分隔字符串,只有组件a与b被缓存。-->
  2. <keep-alive include="a,b">
  3. <component></component>
  4. </keep-alive>
  5. <!-- 正则表达式 (需要使用 v-bind,符合匹配规则的都会被缓存) -->
  6. <keep-alive :include="/a|b/">
  7. <component></component>
  8. </keep-alive>
  9. <!-- Array (需要使用 v-bind,被包含的都会被缓存) -->
  10. <keep-alive :include="['a', 'b']">
  11. <component></component>
  12. </keep-alive>

vue-router实现懒加载的方式

vue异步组件

vue异步组件技术 ==== 异步加载
vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 。但是,这种情况下一个组件生成一个js文件

  1. /* vue异步组件技术 */
  2. {
  3. path: '/home',
  4. name: 'home',
  5. component: resolve => require(['@/components/home'],resolve)
  6. },{
  7. path: '/index',
  8. name: 'Index',
  9. component: resolve => require(['@/components/index'],resolve)
  10. },{
  11. path: '/about',
  12. name: 'about',
  13. component: resolve => require(['@/components/about'],resolve)
  14. }

es提案的import()

  1. // 下面2行代码,没有指定webpackChunkName,每个组件打包成一个js文件。
  2. /* const Home = () => import('@/components/home')
  3. const Index = () => import('@/components/index')
  4. const About = () => import('@/components/about') */
  5. // 下面2行代码,指定了相同的webpackChunkName,会合并打包成一个js文件。把组件按组分块
  6. const Home = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/home')
  7. const Index = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/index')
  8. const About = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/component/about')
  9. {
  10. path: '/about',
  11. component: About
  12. }, {
  13. path: '/index',
  14. component: Index
  15. }, {
  16. path: '/home',
  17. component: Home
  18. }

webpack的require,ensure()

vue-router配置路由,使用webpack的require.ensure技术,也可以实现按需加载。这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。

  1. /* 组件懒加载方案三: webpack提供的require.ensure() */
  2. {
  3. path: '/home',
  4. name: 'home',
  5. component: r => require.ensure([], () => r(require('@/components/home')), 'demo')
  6. }, {
  7. path: '/index',
  8. name: 'Index',
  9. component: r => require.ensure([], () => r(require('@/components/index')), 'demo')
  10. }, {
  11. path: '/about',
  12. name: 'about',
  13. component: r => require.ensure([], () => r(require('@/components/about')), 'demo-01')
  14. }

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对象等。

  1. $route.path:字符串,对应当前路由的路径,总是解析为绝对路径,如 “/foo/bar”。
  2. $route.params:一个 key/value 对象,包含了 动态片段 和 全匹配片段,如果没有路由参数,就是一个空对象。
  3. $route.query:一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1,则有 $route.query.user == 1,如果没有查询参数,则是个空对象。
  4. $route.hash:当前路由的 hash 值 (不带#) ,如果没有 hash 值,则为空字符串。
  5. $route.fullPath:完成解析后的 URL,包含查询参数和 hash 的完整路径。
  6. $route.matched:数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
  7. $route.name:当前路径名字
  8. $route.meta:路由元信息

vue-roter的钩子函数

vue路由钩子大致可以分为三类:

全局钩子

主要包括 beforeEachaftrEach ,

  • beforeEach函数有三个参数:
    • to:router即将进入的路由对象
    • from:当前导航即将离开的路由
    • next:Function,进行管道中的一个钩子,如果执行完了,则导航的状态就是 confirmed (确认的);否则为false,终止导航。
  • afterEach函数不用传next()函数这类钩子主要作用于全局,一般用来判断权限,以及以及页面丢失时候需要执行的操作,例如:

单个路由里面的钩子

主要用于写某个指定路由跳转时需要执行的逻辑

组件路由

主要包括 beforeRouteEnterbeforeRouteUpdate , beforeRouteLeave,这几个钩子都是写在组件里面也可以传三个参数(to,from,next),作用与前面类似.

Vuex

vuex的使用

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化,具体包括:

  1. state:Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。
  2. getter:state的计算属性,类似vue的计算属性,主要用来过滤一些数据。
  3. action:actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。可以异步函数调用
  4. mutation:mutations定义的方法动态修改Vuex 的 store 中的状态或数据
  5. modules:项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。