本文基于https://segmentfault.com/a/1190000010095089 参考诗人的咸鱼文章,添加自己的理解,供自己笔记使用。
当我们需要在其他页面扩展或者叫混合时,Vue中提供了多种的实现方式:extend,mixins,extends.
let options = {
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
},
created(){
console.log('onCreated-1-created');
}
};
1. extend 可以扩展 Vue 构造器,从而用预定义选项创建可复用的组件构造器。
let BaseComponent = Vue.extend(options);
//基于基础组件BaseComponent,再扩展新逻辑.
new BaseComponent({
created(){
//do something
console.log('onCreated-2');
}
//其他自定义逻辑
});
// -> onCreated-1
// -> onCreated-2
2. Vue.component 是用来注册或获取全局组件的方法,其作用是将通过 Vue.extend 生成的扩展实例构造器注册(命名)为一个组件
Vue.component('global-component', Vue.extend(options));
//传入一个选项对象(自动调用 Vue.extend),等价于上行代码.
Vue.component('global-component', options);
3. mixins 选项接受一个混合对象的数组。这些混合实例对象可以像正常的实例对象一样包含选项,他们将在 Vue.extend() 里最终选择使用相同的选项合并逻辑合并
new Vue({
mixins: [options],
created(){
//do something
console.log('onCreated-2');
}
//其他自定义逻辑
});
// -> onCreated-1
// -> onCreated-2
mixins 可以混入多个,执行循序同排列顺序参考xxx
4.extends 这和 mixins 类似,区别在于,组件自身的选项会比要扩展的源组件具有更高的优先级,extend > extends ,extend的执行早于extends。
new Vue({
extends: options,
created(){
//do something
console.log('onCreated-2');
}
//其他自定义逻辑
});
// -> onCreated-1
// -> onCreated-2
从源码来看通过extend,extends和mixins三种方式接收的options,最终都是通过mergeOptions进行合并的.差异只是官方文档中提到的优先级(执行顺序)不同extend > extends > mixins. 所以,如果是简单的扩展组件功能,三个方式都可以达到目的。
-
Vue.extend
Vue.extend只是创建一个构造器,他是为了创建可复用的组件. -
mixins,extends
而mixins和extends是为了拓展组件.
Mixins:可以定义共用的变量,在每个组件中使用,引入组件中之后,各个变量是相互独立的,值的修改在组件中不会相互影响。
与公共组件的区别
组件:在父组件中引入组件,相当于在父组件中给出一片独立的空间供子组件使用,然后根据props来传值,但本质上两者是相对独立的。
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>extends&&mixin</title>
</head>
<body>
<div id="app">
{{num}}
<p><button @click="add">ADD</button></p>
<div>{{message}}-----{{foo}}</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
let extendObj={
methods: {
add(){
console.log("我是扩展出来的ADD方法");//和混入一样:当原生有同一个方法时,扩展出来的方法不会执行,只会执行原生的方法
}
},
created(){
console.log('extendObj');//1
},
updated:function(){//updated是Vue生命周期
console.log("我是扩展的extendObj---->updated");
},
}
let mixinsOne = {
data () {
return {
message: 'hello',
foo: 'mixinsOne'
}
},
methods: {
add(){
console.log("我是mixinsOne---->add方法");
},
},
created(){
console.log('mixinsOne');
},
}
let mixinsTwo = {
data () {
return {
foo: 'mixinsTwo'
}
},
methods: {
add(){
console.log("mixinsTwo---->add方法");
},
},
created(){
console.log('mixinsTwo');
},
}
let app = new Vue({
el: '#app',
extends:extendObj,
mixins:[mixinsOne,mixinsTwo],
data:{
num:1
},
methods:{
add(){
console.log("我是原生的ADD方法");
this.num++;
}
},
created(){
console.log('app---created');
},
updated() {
console.log("我是原生的updated");//
},
})
</script>
</body>
</html>