Vue js数据绑定不起作用
Posted
技术标签:
【中文标题】Vue js数据绑定不起作用【英文标题】:Vue js data binding doesn't work 【发布时间】:2018-07-13 10:36:42 【问题描述】:我正在尝试创建一个 vue 组件,但每当我想用 v-show
隐藏一些元素时,它都不起作用。
当您单击列表中的任何元素时,我想隐藏它并且在单击事件中 element.visible
设置为 false,因此在组件模板中我将该值绑定到 v-show
但它不会隐藏。
我猜是因为element.visible
它是一种嵌套属性,但我不太确定。
var collection = [
id: 1, name: 'element 1' ,
id: 2, name: 'element 2' ,
id: 3, name: 'element 3' ,
id: 4, name: 'element 4' ,
id: 5, name: 'element 5' ,
id: 6, name: 'element 6' ,
id: 7, name: 'element 7' ,
id: 8, name: 'element 8' ,
];
var multiselect =
props: ['collection'],
data: function()
return
subscribed: [],
toSubscribe: [],
toUnsubscribe: [],
dataset: []
,
mounted: function()
this.dataset = _.map(this.collection, function(element)
element.visible = true;
return element;
);
,
methods:
subscribe: function(element)
element.visible = false;
new Vue(
el: '#app',
components:
'multiselect': multiselect
,
data:
elements: collection
)
.multiselect .list
border: 1px solid #000;
height: 215px;
max-height: 215px;
overflow: scroll;
.multiselect .list .list-element
text-align: center;
padding: 0.2em;
cursor: pointer;
.multiselect .list .list-element:hover
background-color: #d6dbdf;
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"></script>
<script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script>
<div id="app">
<multiselect inline-template :collection="elements">
<div class="col-sm-12 multiselect">
<div class="col-sm-5 list">
<div class="col-sm-12">
<div v-for="element in dataset" class="list-element" @click="subscribe(element)" v-show="element.visible">
element.name
</div>
</div>
</div>
<div class="col-sm-2">
<button class="btn btn-primary btn-fill">
<i class="fa fa-arrow-right" aria-hidden="true"></i>
</button>
<button class="btn btn-primary btn-fill">
<i class="fa fa-arrow-left" aria-hidden="true"></i>
</button>
</div>
<div class="col-sm-5 list">
</div>
</div>
</multiselect>
</div>
【问题讨论】:
【参考方案1】:作为一个有趣的变体,您不需要克隆 collection
元素或在它们上设置属性。
拥有一个并行的标志数组就足够了,但是您必须注意更新它们的语法,并且标志必须包含在对象中才能被观察到。
即 visible: true
的数组,而不是true
的数组。
参考:Mutation-Methods
var collection = [
id: 1, name: 'element 1' ,
id: 2, name: 'element 2' ,
id: 3, name: 'element 3' ,
id: 4, name: 'element 4' ,
];
var multiselect =
props: ['collection'],
data: function()
return
visibleFlags: []
,
created: function()
this.collection.forEach(x =>
this.visibleFlags.push(visible: true); // Vue mutation method
)
,
methods:
subscribe: function(index)
this.$set(this.visibleFlags, index, false)
new Vue(
el: '#app',
components:
'multiselect': multiselect
,
data:
elements: collection
)
.multiselect .list
border: 1px solid #000;
height: 125px;
max-height: 215px;
overflow: scroll;
.multiselect .list .list-element
text-align: center;
padding: 0.2em;
cursor: pointer;
.multiselect .list .list-element:hover
background-color: #d6dbdf;
<script src="https://unpkg.com/vue@2.5.13/dist/vue.js"></script>
<div id="app">
<multiselect inline-template :collection="elements">
<div class="col-sm-12 multiselect">
<div class="col-sm-5 list">
<div class="col-sm-12">
<div v-for="(element, index) in collection"
class="list-element" v-show="visibleFlags[index].visible"
@click="subscribe(index)">
element.name
</div>
</div>
</div>
</div>
</multiselect>
</div>
【讨论】:
【参考方案2】:问题是您正在修改一个已经响应的对象。 Vue cannot detect property additions.
您通过map
复制并将其分配给一个新数组这一事实掩盖了这一点,但它是对响应对象的引用数组,您已向每个对象添加了visible
属性。如果您检查父项中的数据项,您会发现它也添加了 visible
。
最小的解决方法是使用Object.assign
创建一个新对象并将属性复制到其中。这样,所有属性都被插入到非响应对象中,然后在分配期间使其响应。
mounted: function()
this.dataset = _.map(this.collection, function(element)
return Object.assign(, element, visible: true);
);
,
您可以在 created 中执行此操作,因为您不需要 DOM 元素。
【讨论】:
以上是关于Vue js数据绑定不起作用的主要内容,如果未能解决你的问题,请参考以下文章