我有一个 <filter>
.vue 文件中的组件,它具有一些属性来控制查询的过滤器。
这<filter>
可以根据用户需要即时添加/删除。它的行为与 Google Analytics 分割过滤器或 WordPress 的高级自定义字段非常相似。
我看到的唯一解决方案是动态实例化此组件并在我的主 app
中迭代这些组件的数组。 ,但我不知道该怎么做。
Vue.component("my-filter", {
template: "#filterTemplate",
data: function() {
return {
field: null,
value: null
}
},
mounted: function() {
this.$emit("filter-created", this);
},
methods: {
removeFilter: function() {
console.log("Remove this filter");
}
}
});
var app = new Vue({
el: "#app",
data: {
filtersCount: 5,
filters: [] // PROBLEM! I can't decrement on my filtersCount and remove the correct filter. Iteration should be over my "filtersCount" property.
},
methods: {
filterCreated: function(filterObj) {
this.filters.push(filterObj);
},
addFilter: function() {
this.filtersCount += 1;
}
}
});
* {
font-family: "Helvetica", "mono";
font-size: 16px;
}
.filterContainer + .filterContainer {
margin-top: 10px;
}
.filterContainer {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.min.js"></script>
<div id="app">
<!-- I shouldn't iterate over an integer value, but over an array of objects to remove the right ones -->
<my-filter v-on:filter-created="filterCreated" v-for="(index, filter) in filtersCount" :key="index"></my-filter>
<br>
<button @click="addFilter">Add filter</button>
</div>
<script type="text/x-template" id="filterTemplate">
<div class="filterContainer">
<input type="text" :value="field" placeholder="Field" />
<input type="text" :value="value" placeholder="Value" />
<button @click="removeFilter">Remove filter</button>
</div>
</script>
最佳答案
可以更改一些内容以使其正常工作(我只是假设您正在寻找什么!)
首先,您不需要用于计算过滤器的数据属性 (filtersCount
),您可以遍历 filters
属性(property)。
其次,将this
添加到filters
属性可能会导致意外行为,因为this
引用了整个Vue 组件。我建议添加表示 filter
数据的普通对象并将数据作为 props
传递.注意:索引也作为一个 prop 传递,可以被引用并允许通过 emitting 移除过滤器
最后,您的 v-for
似乎被颠倒了。它应该是 (filter, index)
而不是 (index, filter)
。
Vue.component("my-filter", {
template: "#filterTemplate",
props: [
'field',
'value', // filter data
'id',
'index' // index that allows this filter to be removed
],
data: function() {
return {
field: this.field,
value: this.value
}
},
methods: {
removeFilter: function() {
this.$emit('remove-filter', this.index);
},
handleInput: function(prop, e) {
this.$emit('update-filter', { index: this.index, prop, value: e.target.value });
}
}
});
window.vm = new Vue({
el: "#app",
data: {
filters: [
{ id: 1, field: null, value: null },
{ id: 2, field: null, value: null },
{ id: 3, field: null, value: null },
{ id: 4, field: null, value: null },
{ id: 5, field: null, value: null }
]
},
methods: {
addFilter: function() {
var id = Math.max.apply(Math,this.filters.map(function(o){return o.id;})) + 1;
this.filters.push({ id, field: null, value: null });
},
removeFilter: function(index) {
this.filters.splice(index, 1);
},
updateFilter: function(payload) {
this.filters[payload.index][payload.prop] = payload.value;
}
}
});
* {
font-family: "Helvetica", "mono";
font-size: 16px;
}
.filterContainer + .filterContainer {
margin-top: 10px;
}
.filterContainer {
display: block;
border: 1px solid black;
padding: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.min.js"></script>
<div id="app">
<button @click="addFilter">Add Filter</button>
<br><br>
<my-filter v-for="(filter, index) in filters" :key="index" :field="filter.field" :value="filter.value" :id="filter.id" :index="index" @remove-filter="removeFilter" @update-filter="updateFilter"></my-filter>
</div>
<script type="text/x-template" id="filterTemplate">
<div class="filterContainer">
<div>Index: {{ index }}, ID: {{ id }}</div>
<input type="text" :value="field" placeholder="Field" @input="handleInput('field', $event)" />
<input type="text" :value="value" placeholder="Value" @input="handleInput('value', $event)" />
<button @click="removeFilter">Remove filter</button>
</div>
</script>
关于javascript - VueJS - 动态重复组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44264907/