来个 vue 大牛解释下这个神奇的 bug?

来个 vue 大牛解释下这个神奇的 bug?

  • 完整代码
    bug 出现在 watch 中,已写注释
<!--

* @Version: 2.0

* @Date: 2021-12-20 09:30:41

* @LastEditTime: 2022-01-13 11:15:54

-->

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8" />

<meta http-equiv="X-UA-Compatible" content="IE=edge" />

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<title>Document</title>

</head>

<body>

<div id="app">

<component-a></component-a>

<component-b></component-b>

</div>

</body>

<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.js"></script>

<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js"></script>

<script src="https://unpkg.com/vuex@3.6.2/dist/vuex.js"></script>

<script>

const store = new Vuex.Store({

state: {

localData: { name: '' },

},

getters: {

localData: (state) => state.localData,

},

mutations: {

changeLocalData(state, data) {

state.localData = data;

},

},

});

const mapGetters = Vuex.mapGetters;

var myMixin = {

data() {

return {

msg: 'mixin',

};

},

computed: {

...mapGetters(['localData']),

},

watch: {

// 此处有个bug 我点击 `a` 组件的时候 为什么打印的是 b 的值? 期望的是 a

localData: {

handler: _.debounce(function() {

console.log('this.msg', this.msg);

}, 500),

deep: true,

},

},

};

var a = {

mixins: [myMixin],

template: '<div @click="_changeMsg()">a</div>',

mounted() {

this.msg = 'aaa';

},

methods: {

_changeMsg() {

this.$store.commit('changeLocalData', { name: 'a' });

},

},

};

var b = {

mixins: [myMixin],

template: '<div @click="_changeMsg()">b</div>',

mounted() {

this.msg = 'bbb';

},

methods: {

_changeMsg() {

this.$store.commit('changeLocalData', { name: 'b' });

},

},

};

new Vue({

el: '#app',

data() {

return {

flag: false,

};

},

store,

components: {

'component-a': a,

'component-b': b,

},

});

</script>

</html>

项目中 用到了 vuexmixinsdebounce

如果让我打印 this, 已经知道两个 this 都是 b 组件了...

  • 改造一下

删除 myMixinwatch 添加到 ab中,就符合我的期望了,每个 watch 都打印出来了 a,b

var myMixin = {

data() {

return {

msg: 'mixin',

};

},

/* ------删除部分------- */

// watch: {

// localData: {

// handler: _.debounce(function() {

// console.log('this.msg', this.msg);

// }, 500),

// deep: true,

// },

// },

computed: {

...mapGetters(['localData']),

},

};

var a = {

mixins: [myMixin],

template: '<div @click="_changeMsg()">a</div>',

mounted() {

this.msg = 'aaa';

},

/* ------新增 start------- */

watch: {

localData: {

handler: _.debounce(function() {

console.log('this.msg', this.msg);

}, 500),

deep: true,

},

},

/* ------新增 end------- */

methods: {

_changeMsg() {

this.$store.commit('changeLocalData', { name: 'a' });

},

},

};

var b = {

mixins: [myMixin],

template: '<div @click="_changeMsg()">b</div>',

mounted() {

this.msg = 'bbb';

},

/* ------新增 start------- */

watch: {

localData: {

handler: _.debounce(function() {

console.log('this.msg', this.msg);

}, 500),

deep: true,

},

},

/* ------新增 end------- */

methods: {

_changeMsg() {

this.$store.commit('changeLocalData', { name: 'b' });

},

},

};

就是为了想知道原理,请大佬丝滑的解释一波✨(可能是我理解的 mixin 用法有问题?)


回答:

引用一下 @李十三 的回复

那你应该吧mixin封装成一个函数返回,就跟vue的data必须是函数一样mixin: [myMixin()],为了避免公用对象同一个引用地址

再次感谢大佬的细心解答!


回答:

来, 把去抖动函数去掉,这段改成这

 handler() {

console.log('this.msg', this.msg);

// this.msg aaa

// this.msg bbb

},

其实两个都打印了,只是防抖动函数起作用了

以上是 来个 vue 大牛解释下这个神奇的 bug? 的全部内容, 来源链接: utcz.com/p/936887.html

回到顶部