【发布时间】:2018-09-06 08:02:32
【问题描述】:
我有一系列深入几个层次的组件。每个组件都有自己的一段数据,它通过 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 的方法是什么?还有比我目前使用的更好的设计模式吗?
【问题讨论】:
-
你看过 Vuex 吗? vuex.vuejs.org
-
我在这个项目中使用了 Vuex,但我不知道如何让它在这个用例中工作。
-
是否要将
this包含在emit的有效负载中? -
@RoyJ 这样做有什么好处?
-
这将使发出事件的组件可以通过根实例更新其数据。
标签: javascript vue.js vuejs2