目录
一、继承
1、Vue.extend()
vue 中 通过 Vue.extend() 函数来创建一个“子类”。
Vue.extend() 的参数是一个包含组件选项的对象。其中,data 选项必须是一个函数而不能是一个对象。
继承而来的子组件会拥有其父组件的一切属性和方法。
例如:
<template>
<div id="mount-point"></div>
</template>
<script>
// 创建构造器
var Profile = Vue.extend({
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#mount-point')
</script>
结果:
<p>Walter White aka Heisenberg</p>
2、extends
- 类型:Object | Function
- 详细:
允许声明扩展另一个组件 (可以是一个简单的选项对象或构造函数),而无需使用 Vue.extend。这主要是为了便于扩展单文件组件。这和 mixins 类似。
- 语法:
var CompA = { ... }
// 在没有调用 `Vue.extend` 时候继承 CompA
var CompB = {
extends: CompA,
...
}
【案例一】:抽离 JS 部分为公共组件
抽取公共的部分定义为可被继承的 JS 组件:
// my-extend.js 文件
import { Toast } from 'vant'
export default {
data () {
return {
list: [111, 222, 333, '...']
}
},
methods: {
clickHandle (item) {
return Toast(item)
}
}
}
继承这个 JS 组件:
<template lang="pug">
.my-extend
.list-item(v-for='(item, index) in list' :key='index' @click='clickHandle(item)') {{item}}
</template>
<script>
import myExtend from '@/mixins/my-extend.js'
export default {
extends: myExtend
}
</script>
【案例二】抽离 template 部分为公共组件
抽取公共的模版定义为可被继承的 vue 组件:
<template lang="pug">
.base-component
header Hi
footer ©️onetwotwo --tonight
</template>
<style lang="less" scoped>
.base-component {
height: 100vh;
padding: 60px 0;
box-sizing: border-box;
header, footer {
width: 100%;
height: 60px;
line-height: 60px;
background: #eee;
position: absolute;
}
header {
top: 0;
padding: 0 20px;
box-sizing: border-box;
}
footer {
bottom: 0;
text-align: center;
}
}
</style>
继承这个 vue 组件:
<script>
import BaseComponent from '@/views/amy/components/extends/baseComponent/index.vue'
export default {
extends: BaseComponent
}
</script>
【总结】vue 中,任何公共的部分都可以组件化,共使用者继承复用。
二、混合
当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”:
- 数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。
- 同名钩子函数将合并为一个数组。
- 混入对象的钩子将在组件自身钩子之前调用。
- 值为对象的选项,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。
mixin 解决的作用:
- vue2.x中,mixin 是将部分组件逻辑抽离成公共的部分,用于实现功能、逻辑和模块的“复用”。从其功能来讲与 extends 类似,所以很是鸡肋。
mixin 存在的问题:
- mixin很容易发生冲突:因为 mixin 的 property 都被合并到了一个组件中,同名的会被覆盖。
- 数据来源不明确:如果你引入了多个 mixin 对象,想要知道其中一个具体方法、属性等的来源无疑是很难查找的。代码可读性差。
- 可重用性有限:我们只能被动的使用 mixin 中传递的任何东西,而不能通过参数传递的方式来改变其中的某些逻辑,这大大降低了它抽象逻辑方面的灵活性。
这些问题导致:vue3 抛弃了 mixin 语法。
1、Vue.mixin()
通过 Vue.mixin() 可以全局注册使用一个混入。
一旦使用全局混入,它将影响每一个之后创建的 Vue 实例。使用时格外小心!
插件作者可以使用混入,向组件注入自定义的行为。不推荐在应用代码中使用。
例如:
// 为自定义的选项 'myOption' 注入一个处理器。
Vue.mixin({
created: function () {
var myOption = this.$options.myOption
if (myOption) {
console.log(myOption)
}
}
})
new Vue({
myOption: 'hello!'
})
// => "hello!"
【注意】
请谨慎使用全局混入,因为它会影响每个单独创建的 Vue 实例 (包括第三方组件)。大多数情况下,只应当应用于自定义选项,就像上面示例一样。推荐将其作为插件发布,以避免重复应用混入。
2、mixins
通过 mixins 可以在单文件组件中局部注册使用一个混入。
例如:创建一个局部的混入
// mixin.js
export default {
data: function () {
return {
message: 'hello',
foo: 'abc'
}
},
created: function () {
console.log('混入对象的钩子会优先被调用')
}
methods: {
// ...
}
}
在单文件组件中使用这个混入:
<script>
import mixin from './mixin.js'
export default {
mixins: [mixin]
}
</script>