1.vue双向绑定原理
通过数据劫持结合发布者-订阅者模式实现。用Object.defineProperty实现数据劫持,对属性设置一个set或get函数,数据改变时函数被触发,会发布信息给订阅者触发监听渲染视图。主要实现的是{{}},v-model,事件指令这些功能。函数的参数是:监听对象+属性值名字(字符串)+操作即{set:function()/get:function()},然后设定好函数之后,对属性进行更改,比如直接给该属性赋一个值,然后Object.defineProperty就会被调用。将需要更新的方法放入就可以实现data更新view(数据变动时发送消息给订阅者触发相应的监听回调)。首先数据进行劫持监听,设定监听器Observer,属性发生变化就告诉订阅者Watcher是否需要更新,因为有很多订阅者,所以用消息订阅器Dep收集订阅者,然后对监听器和订阅者进行统一管理,再用一个指令解析器Compile,对每个结点元素进行扫描和解析,把相关指令对应初始化成一个订阅者Watcher,替换模板数据或绑定相应函数。
1.vue组件间的通信方式
1.父组件向子组件传值
通过props,父向下给子传,组件数据是:data,props,computed
2.子组件向父组件传值
子组件通过事件方式(events)给父组件发送消息,就是把自己的数据发送到父组件,自定义事件,使用$emit,父组件用v-on接收
3.on实现任何组件通信
通过空的vue实例作为事件中心,用来触发事件和监听事件,实现任何组件的通信,项目大的时候可以用vuex。先定义空的vue实例Event,发送的用Event.on('name',data=>{}),on内部有箭头函数,因为箭头函数内部不产生新的this,否则this指代Event。$on监听自定义事件,所以一般在mounted或created中监听
4.vuex
vuex全局有个state存数据,更改数据通过提交mutation进行,mutation的订阅模式供外部插件获取state更新,所有异步操作需要走action,最后根据state变化渲染到视图。
组件
HTML页面接收交互行为,执行dispatch触发对应action回应
dispatch
dispatch是唯一执行action的方法
actions
操作行为处理模块,$store.dispatch触发,commit调用mutation间接更新state,支持同名当打,向后台api请求,提供promise封装,支持action的链式触发
commit
唯一执行mutation的方法
mutations
由actions的commit触发,修改state唯一推荐方法,只能同步,方法名全局唯一,会有hook暴露进行state监控
getters
state对象读取方法,组件通过此方法读取全局state对象
vuex与localstorage
vuex是vue的状态管理器,存储数据是响应式的,但不会保存,刷新后就会到处是,vuex里数据改变时就拷贝到localstorage,刷新后将localstorage里存的数据取出来替换store的state。vuex保存的状态是数组:state.subscribeList,所以用JSON转换成字符串。
5.listeners
只传递数据,不做中间处理用listeners。attrs传入内部。listeners"传入内部组件。其实这是2个对象,l是父组件绑定的非原生事件
6.provide/inject
允许一个祖先组件向所有后代注入一个后代,在上下游关系成立的时间里始终生效,解决跨级组建的通信。祖先通过provide提供变量,子孙通过inject注入变量
7.children/ref
ref在普通DOM元素使用,引用指向的是DOM,用在组组件,引用指向组件实例。children访问父,子实例。这两种都是直接得到组件实例,使用后可以直接调用组件方法或访问数据。无法跨级或兄弟间通信
2.vue的钩子函数
vue实例创建时经过初始化,初始化运行的函数叫生命周期钩子函数。
created
实例创建完成后立即调用,此时实力已经完成数据观测,属性方法的运算,watch/event事件回调的配置,但挂在阶段未开始,$el property不可用,data和methods初始化好了,要调用methods或操作data可以从该阶段开始
mounted
实例已挂载,不会承诺所有子组件也挂载,该钩子服务器渲染期间不被调用。el被新创建的vm.$el替换。执行该钩子,vue实例化已经初始化完成,组件脱离创建到运行部分,想通过插件操作页面DOM节点可以从这阶段进行
常用钩子
父create->子created->子mounted->父mounted
3.vue的key属性
为了高效更新虚拟DOM,不使用key,vue会最大限度减少动态元素并尽可能尝试修改/复用同类元素算法,使用key时,会给予key的变化重新排列元素顺序,移除key不在的元素
4.移动端适配方法
flex弹性布局,viewport适配,rem弹性布局(等比缩放),rem+viewport缩放
5.rem和em区别
子元素字体大小的em时相对于父元素字体大小,rem时全部的长度相对于根元素元素,通常给html元素设置字体大小,然后其他元素长度单位是rem
6.MVVM
Model,View,ViewModel,Controller演变成ViewModel,通过数据显示视图层而不是节点操作,解决了MVC中大量DOM操作使页面渲染性能降低,加载速度变慢,影响用户体验。
7.权限控制
1)动态生成路由表
获取权限后根据用户拥有访问权限的路由信息构建路由表并动态添加进路由表(vue-router的addRoute方法),保证无权限路由没有被挂载,无法被访问。
2)全局路由拦截
在每次路由跳转时对要跳转的路由进行判断(hasOwnProperty),有权限就跳转,否则提示或跳转到对应页面(如404)。
3)组件权限控制
实现一个通用的hasPermision指令,来设置用户是否有权限查看或操作页面中的组件。
8.diff算法
diff算法是通过同层的树节点进行比较的高效算法,比较过程循环从两边向中间比较,vue中作用于虚拟DOM渲染成真实dom的新旧vnode节点比较。
原理
数据变化时,订阅者watcher会调用patch给真实的dom打补丁,用isSameVnode判断,相同就调用patchVnode