我已经搜索了Vue文档,除非我是盲人,否则我什么也看不到任何说明不能在子组件上使用观察者的组件,也不能在我的情况下使用全局混合属性。但是,由于某种原因,我无法让我上班...
我有一个全局mixin,用于锁定/解锁窗口滚动。很简单,我正在尝试从子组件中监听对全局mixin上的bodyLocked
布尔属性的更改。
由于某些原因,观察者确实会在页面加载时触发,但此后,它似乎并没有监听更改。
这是我的mixin(它与Vue.mixin()
一起全局使用):
export default {
data() {
return {
bodyLocked: false
}
},
methods: {
/**
* Lock the DOM body to disable scrolling.
*
* @return void
*/
_lockBody() {
this.bodyLocked = true;
document.documentElement.classList.add('no-scroll');
},
/**
* Unlock the DOM body to enable scrolling.
*
* @return void
*/
_unlockBody() {
this.bodyLocked = false;
document.documentElement.classList.remove('no-scroll');
}
}
};
这是一个示例子组件:
export default {
watch: {
bodyLocked: function(locked) {
console.log('locked: ' + locked);
}
}
}
答案 0 :(得分:2)
来自Vue's documentation for mixin:
Mixin是一种灵活的方式来分发可重复使用的功能,用于 Vue组件。 mixin对象可以包含任何组件选项。什么时候 组件使用混入,混入中的所有选项将被“混合” 进入组件自己的选项。
声明全局混合时,应用程序中的每个Vue组件都将拥有自己的数据locked
,并使用2种方法_lockBody
和_unlockBody
来修改自己的locked
值。我相信您希望在全局mixin中声明的值在组件之间共享,但事实并非如此。您正在寻找的可能是全局状态管理:https://vuejs.org/v2/guide/state-management.html
答案 1 :(得分:1)
Watchers用于监视同一组件中的计算属性和状态属性。组件基本上是带有闭包的对象,因此您要执行的操作无法正常工作。
答案 2 :(得分:1)
使用全局混合时,组件将不会共享bodyLocked
数据的同一实例。因此,在一个组件中进行更改不会在其他组件中进行更改。每个组件都有自己的bodyLocked
值。
执行此操作的另一种方法是使用Vue原型上的对象,而不是使用全局mixin。这样的对象将在所有组件实例之间共享。它还可以使组件内的命名空间更清晰,并且对性能的影响应小于全局mixin。
const locker = Vue.observable({
locked: false,
lock () {
locker.locked = true;
document.documentElement.classList.add('no-scroll');
},
unlock () {
locker.locked = false;
document.documentElement.classList.remove('no-scroll');
}
});
Vue.prototype.$bodyLocker = locker;
new Vue({
el: '#app',
watch: {
'$bodyLocker.locked' (locked) {
console.log('watcher fired: ' + locked);
}
}
});
.no-scroll {
background-color: #f00;
}
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="app">
<button @click="$bodyLocker.lock">Lock</button>
<button @click="$bodyLocker.unlock">Unlock</button>
</div>