vuejs中mixins,extends,extend的区别

2,819 阅读3分钟

1、mixins
mixins是对组件的扩充,包括methods、components、directive等。
mixins的几个规则:
1、触发生命周期钩子函数时,先触发mixins组件中的钩子,再调用组件自身的函数。
2、当mixins数组中有watch,混入的组件中也存在watch,并且watch中的key相同时,混入组件中的watch会先触发,然后再是组件中的watch触发
3、虽然也能在创建mixin时添加data、template属性,但当组件自身也拥有此属性时以自己为准,从这一点也能看出制作者的用心(扩充)。
4、data、methods内函数、components和directives等键值对格式的对象均以组件自身或实例为准,组件自身没有定义才会去mixins混入的组件中去找。
5、watch,mixins数组中的组件和组件自身的watch会合并在一个数据中,mixins中的组件中的watch会先运行,然后再是组件本身的watch


mixins选项合并:
当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。数据对象在内部会进行递归合并,在有同名的keys时以组件数据优先。
2、extends
extends与mixins类似;合并规则和mixins一致。extends允许声明扩展另一个组件(可以是一个简单的选项对象或构造函数),而无需使用 Vue.extend。这主要是为了便于扩展单文件组件。
3、extend
extend可以扩展 Vue 构造器,从而用预定义选项创建可复用的组件构造器。
<body>
<div id="app">
	<!--<runoob></runoob>-->
	extend扩展的组件
	<myrunoob></myrunoob>  
</div>

<script>
// 注册
let options = {
    //template: '<p>{{name}} {{lastName}} aka {{alias}}</p>',
    data: function () {
        return {
            name: 'extend',
            lastName: 'White',
            alias: 'Heisenberg'
        }
    },
    created(){
        console.log('extend created');
    },
	mounted(){
        console.log('extend mounted');
    }
};
let runoob=Vue.component('runoob', {
  template: '<h1>{{name}}</h1>',
  data(){
	return{
		name:'compnents self'
	}  
  },
  created(){
   console.log("runoob created")
  },
  mounted(){
   console.log("runoob mounted")
  }
})
let myrunoob=runoob.extend(options);
Vue.component('myrunoob',myrunoob)
// 创建根实例
new Vue({
  el: '#app',
  data () {
    return {
      //name: 'name'
    }
  },
  created(){
  // console.log("self created")
  },
  mounted(){
  // console.log("self mounted")
  }
})
</script>
</body>
打印出:
runoob created
extend created
runoob mounted
extend mounted
<h1>{{name}}</h1>中name的值是extends中data中定义的

mixins和extends都可以理解为继承
mixins接受的是一个数组可以理解为面相对象语言的多继承,extends接受的是一个对象或函数,可以理解为单继承;
Vue.extend 创建组件的构造函数,Vue.extend是为了创建可复用的组件
mixins和extends是为了扩展组件。
从源码来看通过extend,extends和mixins三种方式接收的options,最终都是通过mergeOptions进行合并的.差异只是官方文档中提到的优先级不同extend > extends > mixins. 所以,如果是简单的扩展组件功能,三个方式都可以达到目的.
/*继承钩子函数*/
const extend = {
 created () {console.log('extends created')}
}
const mixin1 = {
 created () {console.log('mixin1 created')}
}
const mixin2 = {
 created () { console.log('mixin2 created')}
}
export default {
 extends: extend,
 mixins: [mixin1, mixin2],
 name: 'app',
 created () {
  console.log('created')
 }
}
输出结果:
extends created
mixin1 created
mixin2 created
created
结论:
继承钩子函数的时候,是不进行覆盖的,extends的钩子函数先触发,然后再是mixins的钩子函数触发,最后就是组件自身的钩子函数触发。extends优先级比mixins优先级高,先运行优先级高的钩子函数。