混入(mixin)

混入提供了一种非常灵活的方式,当Vue组件中有一个复用性比较高的js逻辑,可以使用mixin。

一个混入对象可以包含容易组件选项,当组件使用混入对象时,所有混入对象的选项将被“混入”进入该组件本身的选项。

// 定义一个混入的对象
let Mixin = {
    created: function() {
        this.hello();
    },
    methods: {
        hello: funtion() {
        	console.log('this is a mixin!');
    	}
    }
}

// 定义一个使用混入对象的组件
let component = Vue.extend({
    mixins: [Mixin]
})
let component = new Component()   // 'this is a mixin!'

选项合并

组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”

  • 发生冲突时以 组件数据优先
let mixin = {
    data() {
        return {
            message: 'hello',
            foo: 'abc123'
        }
    }
}

new Vue({
    mixins: [mixin],
    data() {
        return {
            message: 'myGod',
            bar: 'deef'
        }
    },
    created: function() {
        console.log(this.$data);   // {message: 'myGod', foo: 'abc123', bar: 'deef'}
    }
})
  • **同名钩子函数将合并为一个数组,因此都将被调用。**混入对象的钩子将在组件自身钩子之前调用
let mixin = {
    created() {
        console.log('混入对象的钩子被调用了');
    }
}

new Vue({
    mixins: [mixin],
    created() {
        console.log('组件钩子被调用了');
    }
})

// 混入对象的钩子被调用了
// 组件钩子被调用了
  • 值为对象的选项,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对
let mixin = {
    methods: {
        foo() {
            console.log('我是foo');
        },
        conflig() {
            console.log('我来自mixin');
        }
    }
}

let vm = new Vue({
    minxins: [mixin],
    methods: {
        bar() {
            console.log('from bar');
        },
        conflig() {
            console.log('from mixin');
        }
    }
})

vm.foo();  // 我是foo
vm.bar();  // from bar
vm.conflig();  // from mixin

全局混入

混入可以进行全局注册,一旦使用全局混入,它将影响每一个之后创建的Vue实例(包括第三方组件也会受到影响)。小心使用,使用恰当时,可以用来自定义选项注入处理逻辑

// 自定义的选项 'option' 注入一个处理器
Vue.mixin({
    created() {
        let option = this.$options.option
        if (option) {
            console.log(option);
        }
    }
})

new Vue({
    option: 'BlueBones'
})
// BlueBones

自定义选项合并策略

自定义选项的默认策略:简单地覆盖已有值

如果想让自定义选项以自定义逻辑合并,可以向 Vue.config.optionMergeStrategies添加一个函数:

Vue.config.optionMergeStrategies.myOption = funtion(toVal, fromVal) {
    // 一顿操作后,返回合并后的值
}

对于多数值为对象的选项,可以使用与methods相同的合并策略:

let strategies = Vue.config.optionMergeStrategies;
strategies.myOption = strategies.methods;

实战

模仿着写了一个 右键 显示我们需要 内容(取消标记 按钮),而不是平常浏览器右键显示的菜单*

先写,我们需要在相应页面引入混入的语句(看着跟引入弹窗方式差不多,也需要将一些值传递给混入对象):

// 需要html代码处引入 相应的rightSign.vue页面
<template>
// 监听 右键 事件
<right-menu
	:show='menuShow'  // 控制显隐,可以替换成自己需要的条件
	:row='menuRow'   // 如果你是表格需要将这一行的信息传递给混入
	:menuPosition='menuPosition'   // 若需要定位可以使用这个
	@rightSign='执行你需要的操作函数'
	@changShow='changeShow'
></right-menu>
</template>

<script>
import rightSign from './相应的路径'
export default {
    minxins: [rightSign],
}
</script>

.js结尾的文件,混入的js逻辑文件(混入主要作用就是,因为涉及某些逻辑都是js代码,因此使用混入的方式将js代码引入Vue页面文件):

import rightMenu from './rightSIgn.vue';
export default {
    components: {
        rightMenu
    },
    data() {
        return {
            menuShow: false,  // 显隐值
            menuPosition: {   // 定位值
                left: 0,
                top: 0
            },
            menuRow: {}  // 行内容,数据格式自定义
        }
    },
    methods: {
        rightClick(row, column, event) {
            event.preventDefault();
            this.menuRow = row;
            this,menuPosition = {
                left: event.clientX,
                top: event.clentY,
            }
            this.menuShow = true;
        },
        changeShow() {
            this.menuShow = false;
        }
    }
}

// 需要在对应的vue文件的table增加
// @row-contextmenu = 'rightClick'

rightSIgn.vue文件内容,使用的时候可以跟其他页面一样,可以引入其他组件:

<template>
<div id="right-sign">
    <div v-show="rightSign" @click="maskEvent" @contextmenu.prevent="maskEvent">
    	<div ref="dataSIgn">
        	<p @click="执行的函数名">取消标记</p>    
        </div>
    </div>
</div>
</template>

<script>
    // 接收.js传来的值
	props: {
        show: {
            type: Boolean,
            default: false,
        },
        row: {
            type: Object,
            default: () => {}
        },
        menuPosition: {
            type: Object,
            default: () => {}
        }
    },
    methods: {
        maskEvent(e) {
            this.$emit('changeShow');
        }
    },
    watch() {
        // 将在鼠标的位置显示相应的“取消”按钮
        menuPosition(val) {
        	this.$nextTick(() => {
                this.$refs.dataSign && this.$refs.dataSign.style = `left: ${val.left}px; top: ${val.top}px`
            })
        }
    }
</script>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@乐知者@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值