1. 简单的说一说, vue中组件和插件有什么区别?
首先, 两者之间的关系我们可以从以下方面来区分:
① 编写形式 ② 注册形式 ③ 使用场景
编写形式:
- 编写组件有很多方式, 我通常将以.vue结尾的文件就叫做一个组件.
- 插件的编写我们应该暴露出一个install方法, 其方法上面有两个参数; 第一参数为Vue构造器, 第二个参数为可选的选项对象.
注册形式:
- 组件的注册可以是局部也可以是全局的注册
- 局部的注册组件, 我们可以使用components属性来进行局部注册.
- 全局的注册组件, 我们可以使用Vue.component方法来进行注册; 它其中有两个参数, 第一个为组件名称, 第二个为组件的配置项.
- 插件的注册是全局的, 我们可以使用Vue.use来进行注册; 其中有两个参数, 对象或函数.
- 如果参数为对象, 我们就应该暴露出一个install的方法.
- 如果参数为函数, Vue就会把这个当做install方法来使用.
- 注意: 注册插件的时候,需要在调用 new Vue() 启动应用之前完成,
Vue.use
会自动阻止多次注册相同插件,只会注册一次.
使用场景:
- 组件
(Component)
是用来构成你的App
的业务模块,它的目标是App.vue.
- 插件
(Plugin)
是用来增强你的技术栈的功能模块,它的目标是Vue
本身. - 简单来说,插件就是指对
Vue
的功能的增强或补充.
2. 说说你对Vue中的mixin的理解?
它的作用就是让公共的逻辑代码进行复用, 简单的来说, 就是讲公共的逻辑代码抽离出来形成一个单独的模块; 当有组件需要使用的时候, 直接混入组件内进行使用即可. (很类似于封装的组件, 就是让公共的结构进行复用).
它可以局部的使用, 也可以全局的注册:
- 局部的使用就是将mixin.js进行导入, 让后在data中有个mixins属性它是一个数组, 直接将导入的对象放入数组中即可.
- 全局的使用就是Vue.mixin(mixins)进行注册即可
特性:
- 要混入的对象中如果是 生命周期函数 "依次执行" 先执行混入的生命钩子函数.
- 要混入的对象中 data 如果变量的值冲突,以组件内的值为准 (覆盖).
- 要混入的对象中 methods 如果函数名冲突,以组件内的值为准 (覆盖).
3. 在Vue2中动态的给data添加新的属性会发生什么?如何解决?
问题:
数据层虽然是更新了; 但是视图层实时更新的.
原因:
- 因为在Vue2中数据双向绑定的原理是使用的Object.defineProperty.
- 当我们访问和修改原先data中已经定义好的数据时, 会触发set和get方法.
- 但是新添加的属性, 是无法触发事件属性的拦截的(数据劫持)
- 原因就在于data中原先需要被定义的数据都通过了Object.defineProperty, 将所有的数据设置成了响应式的. 但是动态添加的新属性是没有通过Object.defineProperty的.
简单的来说就是因为Vue2中数据双向绑定使用的是Object.defineProperty, data中原本的数据都通过了Object.defineProperty设置成了响应式的; 但是动态添加的新属性是无法触发数据劫持的, 所以数据层会更新, 但是视图层时无法实时更新的.
解决:
- Vue.set(target, propertName/index, value) 或者 this.$set(局部)
参数:
- target是目标源, 它可以是一个对象也可以是一个数组({Object | Array} target)
- propertyName/index是属性名或者是数组下标值({String | Number} propertyName/index)
- value是属性值({any} value)
用法:
给响应式的目标添加一个新的属性(property), 新添加的属性必须也是一个响应式的, 且可以触发的视图更新.
它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = 'hi'
).
注意对象不能是 Vue 实例,或者 Vue 实例的根数据对象.
2. Object.assign()
用法:
创建一个新的对象, 合并原有属性和新添加的属性; 再使用Object.assign添加到原来响应式对象上面去. 因为Object.assgin()是可以用来当做浅拷贝使用的.
3. $forceUpdate
如果你发现你自己需要在 Vue
中做一次强制更新,99.9% 的情况,是你在某个地方做错了事,
$forceUpdate
迫使Vue
实例重新渲染(PS:仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件 ).
总结:
- 如果为对象添加少量的新属性,可以直接采用
Vue.set()
- 如果需要为新对象添加大量的新属性,则通过
Object.assign()
创建新对象 - 如果你实在不知道怎么操作时,可采取
$forceUpdate()
进行强制刷新 (不建议) - PS:
vue3
是用过proxy
实现数据响应式的,直接动态添加新属性仍可以实现数据响应式