前言
一直不是很明白 Vue
中的 extend,mixins,extends,components, install
, 是怎么用的,今天整理一下。
看了 Vue 相关的文档,这些 extend 、component、mixin
都分为 全局 API 和 实例属性,下面就根据 全局 API 和 实例属性这两类做了相关整理
全局 API
Vue.extend(options)
使用基础 Vue
构造器,创建一个“子类”。参数是一个包含组件选项的对象。
注意:data 选项是特例,需要注意 - 在 Vue.extend() 中它必须是函数
例子
// 创建构造器
var Profile = Vue.extend({
template: '<p>{{extendData}}</br>实例传入的数据为:{{propsExtend}}</p>',//template对应的标签最外层必须只有一个标签
data: function () {
return {
extendData: '这是extend扩展的数据',
}
},
props:['propsExtend']
})
// 创建 Profile 实例,并挂载到一个元素上。可以通过propsData传参.
new Profile({propsData:{propsExtend:'我是实例传入的数据'}}).$mount('#app-extend')
Vue.component(id, [definition] )
- {string} id: 组件名的 key
- {Function | Object} [definition]
- 注册或获取全局组件。
- 注册还会自动使用给定的 id 设置组件的名称
作用
通过 Vue.extend
生成的扩展实例构造器注册(命名)为一个全局组件, 参数可以是 Vue.extend()
扩展的实例, 也可以是一个对象 ( 会自动调用 extend
方法 )
本质
与 Vue.extend
一样,创建了一个 Vue “子类” ,只是多了一个全局唯一标识 key
用法
-
注册组件,传入一个扩展过的构造器
Vue.component('my-component', Vue.extend({ /* … */ }))
-
注册组件,传入一个选项对象 ( 自动调用
Vue.extend
)Vue.component('my-component', { /* … */ })
-
获取注册的组件 (始终返回构造器)
var MyComponent = Vue.component('my-component')
例子
// 1.创建组件构造器
var obj = {
props: [],
template: '<div><p>{{extendData}}</p></div>',//最外层只能有一个大盒子,这个和<tempalte>对应规则一致
data: function () {
return {
extendData: '这是Vue.component传入Vue.extend注册的组件',
}
},
};
var Profile = Vue.extend(obj);
// 2.注册组件方法一:传入Vue.extend扩展过得构造器
Vue.component('component-one', Profile)
// 2.注册组件方法二:直接传入
Vue.component('component-two', obj)
// 3.挂载
new Vue({
el: '#app'
});
//获取注册的组件 (始终返回构造器)
var oneComponent=Vue.component('component-one');
console.log(oneComponent===Profile)//true,返回的Profile构造器
Vue.mixin(mixin)
全局注册一个 mixin
,影响注册之后所有创建的每个 Vue
实例。插件作者可以使用 mixin
,向组件注入自定义的行为。不推荐在应用代码中使用。
属性
extends
允许声明扩展另一个组件 (可以是一个简单的选项对象或构造函数),而无需使用 Vue.extend
。这主要是为了便于扩展单文件组件。
例子
var CompA = { ... }
// 在没有调用 `Vue.extend` 时候继承 CompA
var CompB = {
extends: CompA,
...
}
extends
和 mixins
属性混合一起使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<script src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.min.js"></script>
</head>
<body>
<div id="app">
<!-- <p>mixin的data值为:{{mixinData}}</p>
<button @click="getSum()">点我触发getSum方法</button> -->
</div>
</body>
<script>
var extend = {
template: `
<div>
<p> extend 的data值为:{{mixinData}}</p>
<button @click="getSum()">点我触发getSum方法</button>
</div>
`,
data: {
mixinData: "我是extend的mixinData data",
extendData: "我是extend的data"
},
created: function () {
console.log("这是extend的created");
},
beforeDestroy() {
console.log("这是extend的 beforeDestroy");
},
methods: {
getSum: function () {
console.log("这是extend的getSum里面的方法");
},
},
};
var mixin = {
template: `
<div>
<p> mixin 的data值为:{{mixinData}}</p>
<button @click="getSum()">点我触发getSum方法</button>
</div>
`,
data: { mixinData: "我是mixin的data" },
created: function () {
console.log("这是mixin的created");
},
beforeDestroy() {
console.log("这是mixin的 beforeDestroy");
},
methods: {
getSum: function () {
console.log("这是mixin的getSum里面的方法");
},
},
};
var vm = new Vue({
template: `
<div>
<p> vue 的data值为:{{mixinData}}</p>
<button @click="getSum()">点我触发getSum方法</button>
</div>
`,
el: "#app",
data: { mixinData: "我是vue实例的data" },
created: function () {
console.log("这是vue实例的created");
},
beforeDestroy() {
console.log("这是vue实例的 beforeDestroy");
},
methods: {
getSum: function () {
console.log("这是vue实例里面getSum的方法");
},
},
mixins: [mixin],
extends: extend,
});
</script>
</html>
结论
- 执行顺序为:
extends > mixins > created
- 定义的属性覆盖规则和
mixins
一致 - Vue 定义的属性和方法 覆盖
mixins
覆盖extends
- 生命周期函数是先执行
extends
再执行mixins
再执行 Vue 实例 的
components
注册一个局部组件,即包含 Vue
实例可用组件的哈希表。
例子
// 1.创建组件构造器
var obj = {
props: [],
template: '<div><p>{{extendData}}</p></div>',//最外层只能有一个大盒子,这个和<tempalte>对应规则一致
data: function () {
return {
extendData: '这是component局部注册的组件',
}
},
};
var Profile = Vue.extend(obj);
// 3.挂载
new Vue({
el: '#app',
components:{
'component-one': Profile,
'component-two': obj
}
});
mixins
mixins
选项接收一个 mixin
对象的数组。这些 mixin
对象可以像正常的实例对象一样包含实例选项,这些选项将会被合并到最终的选项中,使用的是和 Vue.extend()
一样的选项合并逻辑。也就是说,如果你的混入包含一个 created
钩子,而创建组件本身也有一个,那么两个函数都会被调用。
Mixin
钩子按照传入顺序依次调用,并在调用组件自身的钩子之前被调用。
var mixin={
data:{mixinData:'我是mixin的data'},
created:function(){
console.log('这是mixin的created');
},
methods:{
getSum:function(){
console.log('这是mixin的getSum里面的方法');
}
}
}
var mixinTwo={
data:{mixinData:'我是mixinTwo的data'},
created:function(){
console.log('这是mixinTwo的created');
},
methods:{
getSum:function(){
console.log('这是mixinTwo的getSum里面的方法');
}
}
}
var vm=new Vue({
el:'#app',
data:{mixinData:'我是vue实例的data'},
created:function(){
console.log('这是vue实例的created');
},
methods:{
getSum:function(){
console.log('这是vue实例里面getSum的方法');
}
},
mixins:[mixin,mixinTwo]
})
// 打印结果为:
// 这是mixin的created
// 这是mixinTwo的created
// 这是vue实例的created
// 这是vue实例里面getSum的方法
结论
mixins
执行的顺序为mixins > mixinTwo > created
(vue 实例的生命周期钩子);- 选项中数据属性如
data, methods
, 后面执行的回覆盖前面的 - 生命周期钩子都会执行
Vue.extend
和 Vue.component component
的区别
Vue.component component
两者都是需要先进行组件注册后,然后在template
中使用注册的标签名来实现组件的使用。Vue.extend
则是编程式的写法- 关于组件的显示与否,需要在父组件中传入一个状态来控制 或者 在组件外部用
v-if/v-show
来实现控制,而Vue.extend
的显示与否是手动的去做组件的挂载和销毁。 Vue.component component
在组件中需要使用slot
等自定义 UI 时更加灵活,而Vue.extend
由于没有template
的使用,没有slot
都是通过props
来控制 UI,更加局限一些。
插件开发(Vue.use && install)
Vue.js
的插件应该暴露一个install
方法。- 这个方法的第一个参数是
Vue
构造器,第二个参数是一个可选的选项对象
例子
var MyPlugin = {};
MyPlugin.install = function (Vue, options) {
// 2. 添加全局资源,第二个参数传一个值默认是update对应的值
Vue.directive('click', {
bind(el, binding, vnode, oldVnode) {
// 做绑定的准备工作,添加时间监听
console.log('指令my-directive的bind执行啦');
},
inserted: function(el){
// 获取绑定的元素
console.log('指令my-directive的inserted执行啦');
},
update: function(){
// 根据获得的新值执行对应的更新
// 对于初始值也会调用一次
console.log('指令my-directive的update执行啦');
},
componentUpdated: function(){
console.log('指令my-directive的componentUpdated执行啦');
},
unbind: function(){
// 做清理操作
// 比如移除bind时绑定的事件监听器
console.log('指令my-directive的unbind执行啦');
}
})
// 3. 注入组件
Vue.mixin({
created: function () {
console.log('注入组件的created被调用啦');
console.log('options的值为',options)
}
})
// 4. 添加实例方法
Vue.prototype.$myMethod = function (methodOptions) {
console.log('实例方法myMethod被调用啦');
}
}
// 调用MyPlugin
Vue.use(MyPlugin,{someOption: true })
// 3.挂载
new Vue({
el: '#app'
});
结论
Vue.extend
和Vue.component
是为了创建构造器和组件;mixins
和extends
是为了拓展组件;install
是开发插件Vue.extend > Vue.component > extends > mixins
评论区