我有一系列深入多个级别的组件。每个组件都有自己的数据片段,通过 AJAX 加载这些数据并用于呈现子组件的每个实例。 days
父模板例如:
<template>
<accordion :one-at-atime="true" type="info">
<panel :is-open="index === 0" type="primary" :header="'Day ' + day.day" v-for="(day, index) in days" :key="day.id">
<br/>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">Cycles</h3>
</div>
<div class="panel-body">
<cycles
:day="day"
>
</cycles>
</div>
</div>
</panel>
</accordion>
</template>
cycles
子模板例如:
<template>
<accordion :one-at-atime="true" type="info">
<panel :is-open="index === 0" type="primary" :header="'Week ' + cycle.week + ': ' + cycle.name" v-for="(cycle, index) in cycles" :key="cycle.id">
<form v-on:submit.prevent="update">
....misc input fields here...
<button type="button" class="btn btn-warning" v-if="cycle.id" v-on:click="destroy">Delete</button>
</form>
</panel>
</accordion>
</template>
<script>
export default {
props: [
'day'
],
data() {
return {
cycles: []
}
},
beforeMount: function () {
var self = this;
if (this.cycles.length === 0) {
axios.get('/plans/days/' + this.day.id + '/cycles')
.then(function (response) {
self.cycles = response.data;
})
.catch(function (error) {
console.log(error);
});
}
},
methods: {
destroy: function (event) {
var self = this;
axios.delete('/plans/cycles/' + event.target.elements.id.value)
.then(function (response) {
self.cycles.filter(function (model) {
return model.id !== response.data.model.id;
});
})
.catch(function (error) {
console.log(error);
});
}
}
}
</script>
每个cycles
组件然后在v-for
循环中渲染另一个组件,该循环渲染另一种类型的组件,依此类推。创建的是一个树状的组件结构。
当我需要向服务器发送通用请求,然后更新调用它的组件中的数据时,我不想在每个组件中重复该请求方法。我宁愿在根 Vue 实例上只拥有该方法的一个实例。
例如,这将是首选:
const app = new Vue({
el: '#app',
store,
created: function () {
this.$on('destroy', function (event, type, model, model_id, parent_id) {
this.destroy(event, type, model, model_id, parent_id);
})
},
methods: {
destroy: function (event, type, model, model_id, parent_id) {
var self = this;
axios.delete('/plans/' + type + '/' + model_id)
.then(function (response) {
model = model.filter(function (model) {
return model.id !== response.data.model.id;
});
this.$emit('modified-' + type + '-' + parent_id, model);
})
.catch(function (error) {
console.log(error);
});
}
}
});
然后在cycles.vue
删除按钮中单击时调用:
<button type="button" class="btn btn-warning" v-if="cycle.id" v-on:click="$root.$emit('destroy', event, 'cycles', cycles, cycle.id, day.id)">Delete</button>
并将其添加到 cycles.vue
事件中:
created: function () {
this.$on('modified-cycles-' + this.day.id, function (cycles) {
this.cycles = cycles;
})
},
但是,这不起作用,因为子元素永远不会从根元素获取发出的 'modified-' + type + '-' + Parent_id
事件。
我还尝试了 this.$children.$emit('modified-' + type + '-' + Parent_id, model);
但这也不起作用。
Vue 2.5.16 的方法是什么?有没有比我目前使用的更好的设计模式?
最佳答案
每个 Vue 实例(根实例和子实例)都是一个独立的事件中心。
您在实例上 $emit 事件,并且可以在同一实例上使用 $on 订阅事件通知。
您可以使用 this.$root.$on()
和 this.$root.$emit()
将根实例用作事件总线并实现你的目的。
但是,我不太清楚您想要实现什么关注点分离,因此我不准备提供更好的建议。
关于javascript - Vue root 和任何子组件之间的通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49520891/