Vue
1.什么是双向绑定?
Model-View-ViewModel (MVVM模式)
model
:即所谓的数据
View
:即所谓的视图
双向绑定,即model数据层更新,View视图层也会随之更新;如果视图层更新,对应的数据Model层也会更新;
- MVVM实现方式 (参考:https://blog.csdn.net/dwfrost/article/details/85777900)
1.发布者-订阅者模式: 一般通过sub, pub的方式实现数据和视图的绑定监听,更新数据方式通常做法是 vm.set(‘property’, value)。
2.脏值检查: angular.js 是通过脏值检测的方式比对数据是否有变更,来决定是否更新视图,在指定的事件触发时进入脏值检测。
3.数据劫持: vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
2.什么是单向数据流?
指的是组件与组件之间的数据导向,父组件到子组件的数据,是单向影响的,子组件不能直接修改父组件的prop值,这种数据流向是单向的;
3.Vue 一说是双向绑定,一说是单向数据流,什么意思?是否能共存?
注意:双向绑定和单向数据流是不同的概念
双向绑定:
- 单双向绑定
指的是View层和Model层之间的映射关系
。 - 双向绑定:是model改变view自动更新,view改变model自动更新,如
v-model
,用户对View层的更改会直接同步到Model层,实际上v-model只是v-bind:value 和 v-on:input的语法糖 - Vue中的单向绑定:如插值形式
{{data}}
,v-bind
也是单向绑定; - 双向绑定优缺点:vue的v-model在操作表单时,显得很简单,不用去写繁琐的onChange事件去处理每个表单数据的变化,但是双向绑定也会导致数据变化不透明,不清晰可控。
单向数据流:
- 单向数据流:指的是组件与组件之间的数据导向,父组件到子组件的数据,是单向影响的,子组件不能直接修改父组件的prop值,这种数据流向是单向的;
- 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中
,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
- 另外,父组件更新时,子组件的props都会刷新,因此子组件内部不应该去修改props值,否则Vue会提示报错;
4.Vue事件
- 普通事件
@click,@input,@change,@***
等事件,通过this.$emit('xxx',...)
触发; - 修饰符事件
@input.trim,@click.stop,#submit.prevent
等,一般用于原生HTML元素,自定义组件需要自行开发支持;
5.Vue 中虚拟DOM的比较方式
Vue
中虚拟DOM
的比较方式采用同层比对,先后的DOM
通过每一层的比较,对比出改变,删除的节点
6.Vue如何促进组件更新?
Vue
是通过数据驱动DOM
更新,即当Model数据发生改变,才会导致视图层的改变;任何情况下,应该尽量避免直接操作DOM
元素
7.Vue中数据的来源?
1. 来自父元素的Prop;
2. 来自组件自身的状态 Data;
3. 来自状态管理器,如vuex,Vue.observale
8.Vue响应式更新
- Vue在实例化的时候,会在Data中做setter 和getter的操作,直白的说就是,Vue对数据做了一个代理层,无论是getter取数据还是setter设置数据,都需要通过这个代理层进行操作;
- 组件
=============>>>>
Data[B,C]================>>>>
watcher - 在组件中需要用到Data中的数据,如果组件中用到数据A,B,C,当Data中有数据B,C时,Data会将组件中使用到的B,C放到watcher中,如果watcher监听到B,C的变化,则会促使组件渲染更新,否则不改变;
- 当组件中的数据不在Data中,则watcher无法监听到数据,所以会产生数据改变了,但是视图并没有改变;
9.computed 计算属性
- 计算属性,顾名思义是一种可以写入一些计算逻辑的属性,注意落脚点是“属性”;
- 计算属性可以进行数据缓存,具有记忆性,当数据没改变时,不会促使渲染;
【此处与method区别开,如果用方法,即使数据不变也会调用方法】
- 计算属性依赖固定的数据类型
【必须是响应式数据】
10.watch监听
- watch可以执行任何逻辑,如函数节流,Ajax异步获取数据,操作DOM;
- watch监听的是data中的属性值;
11.watch和Computed:
computed
能做的,watch
都能做,反之则不行;- 能够用
computed
尽量用computed
,因为computed属性是根据缓存去决定是否执行变化操作
,可以减少没必要的渲染;
12.provide/inject 主要用于处理组件间的通信问题,类似react中useContext
13.在复杂的业务场景下,可能存在需要操作DOM实例对象的情况,此时需要用到Ref引用信息 【provide/inject】
-
当有多层结构时可以递归查找指定层级的实例对象,
【不推荐使用,代码繁琐,性能较低】
-
callBack ref
主动通知 setXXXRef
主动获取 getXXXRef注意:使用Provide提供get,set等自定义方法;在子组件中inject注入方式,获取指定方法,暴露本组件的DOM实例
-
父节点
provide(){
return {
setChildRef:(name,ref)=>{
this[name] = ref;
},
getChildrenRef:name =>{
return this[name];
},
getRef:()=>{
return this;
}
}
}
// Provide 提供set方法,将组件ref注入到this对象中,然后暴露方法getRef去让引用出获取
-
子节点 主动通知本节点的ref到Provide组件中,更新ref动作
<ChildrenH v-ant-ref="c=>setChildren('childrenH,c')"> // 此处的v-ant-ref是自定义指定 export defualt{ // inject 注入 inject:{ setChildrenRef:{ defualt:()=>{} }, getParentRef:{ form:'getRef', // 方法名重定义 defualt:()={} }, getParentChildrenRef:{ form:'getChildRef', // 方法名重定义 defualt:()={} } }, }
15. template 是一种模板语法,是HTML的扩展,数据的绑定使用{{}}双大括号进行数据绑定;JSX 是js语法的扩展,不是一种模板语法,因此相对于template更加灵活
-
template: 1,学习成本低;2,大量内置指令简化开发;3,组件作用域 CSS 缺点:灵活性低;
-
JSX: 灵活,灵活,灵活
-
无论是Vue中双大括号还是JSX中单大括号,两种写法都是一种语法糖(即抽象出来的形式不同,但是底层的原理实现一致),最后个元素都是编译成
createElement('span','Message:${this.msg}')
//Vue
<span>Message:{{msg}}</span>
// react
<span>Message:{this.masg}</span>
// 底层
createElement('span','Message:${this.msg}')