vue官方文档中是这么解释的:
混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
人话:
Vue.mixin给我们提供了一种混入Vue实例的方法,创建了混入对象之后,我们自定义的方法或者变量可以很轻松的挂载在Vue实例上。
Vue.mixin为我们提供了两种混入方式:局部混入和全局混入;
这里只讲局部混入
首先我们在src目录下新建一个名为mixin的文件夹并在mixin文件中创建一个drag.js文件:
这个文件用来做组件拖拽
// dom.js
// 获取元素的位置
export function getOffset (curEle) {
let totalLeft = null
let totalTop = null
let par = curEle.offsetParent
// 首先把自己本身的进行累加
totalLeft += curEle.offsetLeft
totalTop += curEle.offsetTop
// 只要没有找到body,我们就把父级参照物的边框和偏移量累加
while (par) {
if (navigator.userAgent.indexOf('MSIE 8.0') === -1) {
// 不是标准的ie8浏览器,才进行边框累加
// 累加父级参照物边框
totalLeft += par.clientLeft
totalTop += par.clientTop
}
// 累加父级参照物本身的偏移
totalLeft += par.offsetLeft
totalTop += par.offsetTop
par = par.offsetParent
}
return { left: totalLeft, top: totalTop }
}
// drag.js
import { getOffset } from '@/utils/dom'
// let distenceX, distenceY, clickCicleTime
// 抛出混入对象,方便外部访问
export const mixin = {
data() {
return {
number: 1,
distenceX: '',
distenceY: '',
clickCicleTime: ''
}
},
methods: {
dragMouseDown(e, clickTarget) {
if (clickTarget) {
this.clickCicleTime = +new Date()
}
var positionDiv = getOffset(this.$el)
this.distenceX = e.pageX - positionDiv.left
this.distenceY = e.pageY - positionDiv.top
document.addEventListener('mousemove', this.dragMouseMove)
document.addEventListener('mouseup', this.dragMouseup)
},
dragMouseup(e, clickTarget) {
if (clickTarget) {
let _clickCicleTime = +new Date()
let differTime = _clickCicleTime - this.clickCicleTime
if (differTime < 200) {
this.isZoomOut = false
}
}
document.removeEventListener('mousemove', this.dragMouseMove)
},
dragMouseMove(e) {
let $outWrap = this.$el
var r =
document.documentElement.clientWidth -
e.clientX -
($outWrap.offsetWidth - this.distenceX) -
document.documentElement.scrollLeft
var y = e.pageY - this.distenceY
if (r < 0) {
r = 0
} else if (
r >
document.documentElement.clientWidth - $outWrap.offsetWidth
) {
r = document.documentElement.clientWidth - $outWrap.offsetWidth
}
if (y < 0) {
y = 0
} else if (
y >
document.documentElement.clientHeight - $outWrap.offsetHeight
) {
y = document.documentElement.clientHeight - $outWrap.offsetHeight
}
$outWrap.style.right = r + 'px'
$outWrap.style.top = y + 'px'
}
}
}
前置文件准备好后,下面是mixin在vue的使用
// xxx.vue
import { mixin } from '@/mixin/drag'
export default {
name: 'tip-pl',
components: { swiper, swiperSlide },
mixins: [mixin],
data() {
return {
BEM_NAMESPACE: 'tip-pl',
specialData: [],
TOY_MODES_ICO_LIST,
isShowSwiper: true,
isClosePanel: false,
panelSetting: this.$$lvsGlobelData.panelSetting,
normalSettingData: {
itemListNum: 5
},
swiperOption: {
loop: true,
speed: 1000,
autoplay: autoplay
},
basicData: []
}
},
.......
这样混入mixin就完成了。至于变量是否公用,mixin与vuex的区别,这里有几个关键点
1.mixin混入对象的变量是不会共享的
2.例如methods,components等如果变量名和mixin混入对象的变量名发生冲突,将会以组件优先并进行递归合并,相当于组件数据直接覆盖了mixin中的同名数据;
3.
mixin混入对象和Vuex的区别:
Vuex是状态共享管理,所以Vuex中的所有变量和方法都是可以读取和更改并相互影响的;
mixin可以定义公用的变量或方法,但是mixin中的数据是不共享的,也就是每个组件中的mixin实例都是不一样的,都是单独存在的个体,不存在相互影响的;
mixin混入对象值为函数的同名函数选项将会进行递归合并为数组,两个函数都会执行,只不过先执行mixin中的同名函数;
mixin混入对象值为对象的同名对象将会进行替换,都优先执行组件内的同名对象,也就是组件内的同名对象将mixin混入对象的同名对象进行覆盖;
参考资料: