[英]Call method and update component between Vuejs2 multiple instances
I have index.html我有索引。html
<!DOCTYPE html>
<html lang="en">
<body>
<div id="appOne">
</div>
<div id="appTwo">
</div>
</body>
</html>
And 2 Vue instances in different files:以及不同文件中的 2 个 Vue 实例:
//appOne.js
import Vue from 'vue';
import AppOne from "./AppOne.vue";
new Vue({
render: h => h(AppOne),
}).$mount('#appOne')
//appTwo.js
import Vue from 'vue';
import AppTwo from "./AppTwo.vue";
new Vue({
render: h => h(AppTwo),
}).$mount('#appTwo')
And components:和组件:
//AppOne.vue
<template>
<component-one/>
</template>
<script>
import ComponentOne from "./components/ComponentOne.vue";
export default {
name: "AppOne",
components: {ComponentOne}
}
</script>
//AppTwo.vue
<template>
<component-two/>
</template>
<script>
import ComponentTwo from "./components/ComponentTwo.vue";
export default {
name: "AppTwo",
components: {ComponentTwo}
}
</script>
//components/ComponentOne.vue
<template>
<div>
<div>
<button @click="foo(counter)">ComponentOne</button>
<div>{{ label }}</div>
</div>
</div>
</template>
<script>
export default {
name: "ComponentOne",
data() {
return {
counter: 1,
label: "default"
}
},
methods: {
foo: function (id) {
this.label = id
}
}
}
//components/ComponentTwo.vue
<template>
<div>
<div>
<button @click="updateComponentOne">ComponentTwo</button>
</div>
</div>
</template>
<script>
export default {
name: "ComponentTwo",
methods: {
updateComponentOne: function () {
//update componentOne.label and do some additional logic
}
}
}
</script>
Question: Click on ComponentTwo button and in method updateComponentOne
update data in ComponentOne and do some additional logic问题:单击 ComponentTwo 按钮并在方法updateComponentOne
中更新 ComponentOne 中的数据并执行一些附加逻辑
I tried:我试过了:
this
reference scope)结果:在组件一上收到事件但数据未更新(我猜是因为this
参考范围) computed: {
someStateThatShouldBeChanged(): {
return state.initialState
}
}
also does not work.也不起作用。
class Event {
constructor() {
this.events = {};
}
on(eventName, fn) {
this.events[eventName] = this.events[eventName] || [];
this.events[eventName].push(fn);
}
emit(eventName, data) {
if (this.events[eventName]) {
this.events[eventName].forEach(function (fn) {
fn(data);
});
}
}
}
export default new Event();
Works as in the 1st case.像第一种情况一样工作。
export const vm1 = new Vue({
render: h => h(AppTwo),
})
and after that tried to change data directly:
vm1.someData = 'newValue'
Also does not work也不起作用
I'm confused, please help me to understand why all these options do not work and how to fix it.我很困惑,请帮助我理解为什么所有这些选项都不起作用以及如何解决它。
Two unrelated instance is pretty isolate and can't access to each others.两个不相关的实例非常孤立,无法相互访问。
Most people in this scenario will create an instance and set AppOne
and AppTwo
as its components.在这种情况下,大多数人会创建一个实例并将AppOne
和AppTwo
设置为其组件。 After than you can using $emit
to pass event to main instance from AppTwo
's updateComponentOne
function and let main instance to call AppOne
by $refs
and change value.之后,您可以使用$emit
将事件从AppTwo
的updateComponentOne
function 传递给主实例,并让主实例通过$refs
调用AppOne
并更改值。
But I can only assume you have your reason to keep those App isolate, but it's okay - I still have some trick can achieved it.但我只能假设您有理由将这些 App 隔离,但没关系 - 我仍然有一些技巧可以实现它。
appOne.js
and appTwo.js
into something like this:首先:将appOne.js
和appTwo.js
合并成这样的:import Vue from 'vue';
import AppOne from "./AppOne.vue";
import AppTwo from "./AppTwo.vue";
const InstanceOne = new Vue({
render: h => h(AppOne),
}).$mount('#appOne')
const InstanceTwo = new Vue({
render: h => h(AppTwo),
}).$mount('#appTwo')
InstanceTwo.$el.addEventListener('someCustomEventName', event => {
// // you can get custom event payload by `event.detail`
// console.log(event.detail);
InstanceOne.someUpdateValueFunction();
});
AppTwo.vue
And components/ComponentOne.vue
:第二:调整AppTwo.vue
和components/ComponentOne.vue
://components/ComponentTwo.vue
<template>
<div>
<div>
<button @click="$emit('updateComponentOne', {thisIsPayloadKey: 'thisIsValue'})">ComponentTwo</button>
</div>
</div>
</template>
<script>
export default {
name: "ComponentTwo"
}
</script>
//AppTwo.vue
<template>
<component-two updateComponentOne="updateComponentOne"/>
</template>
<script>
import ComponentTwo from "./components/ComponentTwo.vue";
export default {
name: "AppTwo",
components: {ComponentTwo},
method: {
updateComponentOne(detail) {
const event = new CustomEvent("someCustomEventName", { detail });
this.$el.dispatchEvent(event);
}
}
}
</script>
Your ComponentTwo
will trigger a $emit
to AppTwo.vue
and pass value you need in a object.您的ComponentTwo
将触发$emit
到AppTwo.vue
并在 object 中传递您需要的值。 Your AppTwo
will dispatch a custom event to himself.您的AppTwo
将向自己发送一个自定义事件。
Due to we already add a event listener, so we can aware when this custom event be trigger and execute whatever we want in that event listener.由于我们已经添加了一个事件侦听器,因此我们可以知道何时触发此自定义事件并在该事件侦听器中执行我们想要的任何内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.