来个 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>
项目中 用到了 vuex
mixins
debounce
如果让我打印 this
, 已经知道两个 this
都是 b 组件了...
- 改造一下
删除 myMixin
的 watch
添加到 a
b
中,就符合我的期望了,每个 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