项目开发时,如果组件间存在许多相似的功能,都有部分相同的功能函数,如果在每个组件中都去重复定义这些属性和方法,就会使项目出现冗余代码,并且也会增加后期维护难度,针对这种情况,可以使用 Mixins特性。
混入提供了一种非常灵活的方式,来分发 vue 组件中的可复用功能。
一个混入对象可以包含任意组件选项。
简单理解就是:mixins 可以提取复用的功能,当组件使用 mixins 混入对象时,所有混入对象的选项将被“混合”进入该组件,成为组件本身的功能。
它是一个 js 对象,可以包含组件中 script项中的任意功能选项 ,例如 data、components、 methods 、created、computed 等等公用的功能。
1.定义一个混入对象:
mixins/index.js :
export default {
data () {
return {
username: "123"
}
},
created () {
//钩子函数
},
methods: {
clickHandle () {
this.username = '456'
console.log(this.username)
}
}
}
2.在组件中使用混入:
page1.vue:
<template>
<div class="hello">
<h4>组件1 username:{{username}}</h4>
</div>
</template>
<script>
//导入js文件
import commonMins from '../mixins/index.js'
export default {
name: "HelloWorld",
// 使用mixins混入对象
mixins: [commonMins],
created () {
console.log('当前组件 created')
},
data () {
return {
}
},
created () {
this.clickHandle()
},
methods: {
}
}
</script>
page2.vue:
<template>
<div class="hello">
<h4>组件2 username:{{username}}</h4>
</div>
</template>
<script>
//导入js文件
import commonMins from '../mixins/index.js'
export default {
name: "HelloWorld",
// 使用mixins混入对象
mixins: [commonMins],
created () {
console.log('当前组件 created')
},
data () {
return {
}
},
created () {
this.clickHandle()
},
methods: {
}
}
</script>
运行结果:
当组件和混入对象含有同名选项时,这些选项将以恰当的方式混合。
mixin 的数据对象和组件的数据发生冲突时以组件数据优先。
mixins.index.js:
export const CommonMins = {
data () {
return {
msg: 'this is mixins msg',
form: {
name: '混入的form数据'
}
}
},
filters: {
//过滤器
},
created () {
//钩子函数
console.log('混入的组件 created')
this.clickFn();
this.exm();
},
computed: {
//计算属性
},
methods: {
exm () {
console.log('这是混入的exm方法')
},
clickFn () {
console.log(this.msg)
}
// 其它属性方法......
}
}
page.vue:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h1>{{ form.name }}</h1>
</div>
</template>
<script>
//导入js文件
import { CommonMins } from '../mixins/index.js'
export default {
name: "HelloWorld",
// 使用mixins混入对象
mixins: [CommonMins],
data () {
return {
msg: "组件的msg"
}
},
methods: {
}
}
</script>
同名钩子函数将会混合为一个数组,都将会被调用到,但是混入对象的钩子函数将在组件自身钩子函数之前调用。
mixins/index.js
export const CommonMins = {
data () {
return {
msg: 'this is mixins msg',
form: {
name: '混入的form数据'
}
}
},
filters: {
//过滤器
},
created () {
//钩子函数
console.log('混入的组件 created')
this.clickFn();
this.exm();
},
computed: {
//计算属性
},
methods: {
exm () {
console.log('这是混入的exm方法')
},
clickFn () {
console.log('混入 clickFn函数打印msg:', this.msg)
}
// 其它属性方法......
}
}
page.vue
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h1>{{ form.name }}</h1>
</div>
</template>
<script>
//导入js文件
import { CommonMins } from '../mixins/index.js'
export default {
name: "HelloWorld",
// 使用mixins混入对象
mixins: [CommonMins],
data () {
return {
msg: "组件的msg"
}
},
created () {
console.log('这是当前组件 created')
this.clickHandle()
},
methods: {
clickHandle () {
console.log('组件 clickHandle打印msg:', this.msg)
}
}
}
</script>
值为对象的选项, 例如 methods, components 和 directives,将被混合为同一个对象。两个对象键名冲突时,取组件对象的键值对。
mixins.index.js
export const CommonMins = {
data () {
return {
loading: false,
msg: 'this is mixins msg',
form: {
name: '混入的form数据'
}
}
},
filters: {
//过滤器
valDeal (value) {
return value + '------';
}
},
created () {
//钩子函数
console.log('混入的组件 created')
this.clickFn();
this.exm();
},
computed: {
//计算属性
ids () {
return !this.loading
}
},
methods: {
exm () {
console.log('这是混入的exm方法')
},
clickFn () {
console.log('混入 clickFn函数打印msg:', this.msg)
console.log('这是混入的exm方法,打印计算属性结果', this.ids)
}
// 其它属性方法......
}
}
page.vue
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<h1>{{ msg|valDeal }}</h1>
<h1>{{ form.name }}</h1>
</div>
</template>
<script>
//导入js文件
import { CommonMins } from '../mixins/index.js'
export default {
name: "HelloWorld",
// 使用mixins混入对象
mixins: [CommonMins],
data () {
return {
msg: "组件的msg"
}
},
created () {
console.log('这是当前组件 created')
this.clickHandle()
},
methods: {
clickHandle () {
console.log('组件 clickHandle打印msg:', this.msg)
},
exm () {
console.log('这是组件的exm方法')
}
}
}
</script>
● 数据对象:混入对象中属性和组件的属性冲突,以组件的值优先。 组件中没有的属性,混入对象中的生效
● 同名钩子函数:将会合并成一个数组 ,都会被调用,混入对象钩子中的函数先调用
● 对象的选项:如methods,components,directives 等,将会合并为一个新对象,如果键名冲突,组件的值优先
使用全局混入需谨慎,因为全局混入后,项目中所有的 vue 对象都“继承”了它,它会影响每个单独创建的 vue 实例(包括第三方组件)。
大多数情况下,只应当应用于自定义选项。
实例
全局混入:在main.js中全局混入
main.js:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './plugins/element.js'
import CommonMins from '@/mixins/index.js'
Vue.config.productionTip = false
// 混入
Vue.mixin(CommonMins)
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
页面使用:
page.vue:
<template>
<div class="home">
<p>
// 可直接使用混入对象内的数据
{{ username }}
</p>
</div>
</template>
<script>
export default {
name: 'Home',
created() {
// 可直接调用混入对象内的方法
this.clickHandle()
},
}
</script>