如何从mixin访问Vue实例



我想实现这种将this.$store.value分配给本地数据的逻辑。例如,我在pages/index.vue中就是这样做的。

method: {
this.value = this.$store.value
}

我想把它写进mixin中,因为我实际上有另一个逻辑,我使用了一些页面。

但是,我不知道如何从mixin访问this(VueInstnce(?

Vue不支持它,因为mixin在组件代码之前先运行,然后mixin由Vue绑定(合并(到组件实例,因此可以很容易地从组件/实例范围访问mixin,但反之亦然。

为了满足您的需求,我认为mixin方法(如created(应该运行(例如(,并将对组件实例的给定引用作为参数,但事实并非如此。

但是,如果您重新组织代码以运行instance中所需的内容。created访问mixin的方法和数据是可能的,并且可以自己传递参数:

var mixin = {
data: {mixin: 'mixin'},
created: function () {
console.log('mixin hook called')
},
methods: { test: function(arg){console.log(arg); } }
};
vm=new Vue({
data: {component: 'component'},
mixins: [mixin],
created: function () {
console.log('called hook of ' + this.component + ' and accessing ' + this.mixin)
},
});
vm.test(vm.mixin);
vm.test(vm.component);  // no problem to run mixin's method with component's data
> mixin hook called
> called hook of component and accessing mixin
> mixin
> component

好的,所以我不知道这是否被认为是一种糟糕的做法,但我已经成功地在没有event bus的情况下实现了单向数据传输。

我使用vuejs 3composition api要求:所有组件都应能够访问显示在整个应用程序顶部的全局单例组件。

plugin.js-这里我们使用mixin中的created事件来获取组件实例的引用。在下面的示例中,我总是只有一个tracker组件实例(全局弹出窗口(如果您有不同的更复杂的场景,我建议您改用事件总线解决方案

import Tracker from "@/plugins/ProgressTracker/components/Tracker.vue";
export default {
install(app, params = {}) {
app.component("tracker", Tracker);
let instance = undefined;
app.mixin({
created() {
if (this.$options.name === "ProgressTrackerPopup") {
instance = this;
}
},
});
const progressTracker = () => {
//
};
progressTracker.show = function () {
instance.show();
};
app.config.globalProperties.$progressTracker = progressTracker;
},
};

useProgressTracker.js-公开show方法的全局可重用可组合函数

import { ref, computed, getCurrentInstance } from "vue";
export default function useProgressTracker() {
const internalInstance = getCurrentInstance();
const progressTracker = internalInstance.appContext.config.globalProperties.$progressTracker;
const show = () => {
progressTracker.show();
};
return {
show,
};
}

Tracker.vue-我们需要从任何其他组件全局访问的组件(它的方法(name是重要的应设置它,以便mixin能够检测到您的组件创建

<template>
<div class="onTop" v-if="isShow">test</div>
</template>
<script>
import { ref } from "vue";
export default {
name: "ProgressTrackerPopup",
setup() {
var isShow = ref(false);
const show = () => {
isShow.value = true;
};
return {
isShow,
show,
};
},
};
</script>
<style scoped>
.onTop{
position: absolute;
z-index: 1999;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #0000004f;
}
</style>

就是这样。别忘了注册插件:

import ProgressTracker from "@/plugins/plugin.js";
// ..
app.use(ProgressTracker, {});

现在,当你想显示弹出窗口时,你可以调用:

// <tracker />
import useProgressTracker from "@/plugins/ProgressTracker/use/useProgressTracker.js";
const tracker = useProgressTracker();
tracker.show();

最后一行代码基本上将调用全局组件实例本身的show方法!然而,如果您使用event bus,您就会订阅目标组件本身的pop事件。

我发现,当您不想处理事件总线,并且情况相对琐碎(您始终只有一个全局实例(时,此解决方案非常有用。不过,您当然可以使用实例数组,并按顺序循环调用它们上的方法。..:(

最新更新