最近使用Vue开发网页,在实现一个条件筛选框时出现了问题,原本计划是实现这样一个类似的筛选效果,
实现想法为 v-for循环生成分类,然后点击其中的分类实现选中效果,设计是利用动态样式,定义一个是选中时的class,另一个是未选中的class,然后在data对象中维护一个变量来记录选中的类别,根据选择类别是否是本类别来使得样式变换。点击m某分类时来给将该分类的索引赋值给type变量,实现切换分类的效果。
实现效果如下
源码如下
<style>
.choose,.unChoose{
display: inline-block;
width: 70px;
height: 30px;
line-height: 30px;
text-align: center;
}
.choose{
border: #6290FF 1px solid;
color:#6290FF ;
box-shadow: 1px 2px 7px #6290FF;
}
.unChoose{
color: #bbb;
}
</style>
<div id="app">
<span v-for="(item,i) in types" :class="type==i?'choose':'unChoose'" @click="chooseItem(i)" >{{item.name}}</span>
</div>
<script>
var myVue = new Vue({
el:'#app',
data:{
type:'',
types:[
{id:1,name:'分类1'},
{id:2,name:'分类2'},
{id:3,name:'分类3'},
{id:4,name:'分类4'},
],
},
methods:{
chooseItem:function(i){
this.type = i;
},
}
})
</script>
但是现在需求改了,需要实现多选,之前只需要记录一个变量,现在需要多个,因此我在data对象中维护了一个数组 type[ ],我的想法是按照索引,如果对应索引位置的元素为true,表示选中,否则为未选中,点击分类将type数组对应的元素赋值为true,但是在赋值之后动态class样式没有实现刷新。
代码如下
<div id="app" >
<span v-for="(item,i) in types" :class="typeArr[i]?'choose':'unChoose'" @click="chooseMore(i)" >{{item.name}}</span>
</div>
<script>
var myVue = new Vue({
el:'#app',
data:{
typeArr:[],
types:[
{id:1,name:'分类1'},
{id:2,name:'分类2'},
{id:3,name:'分类3'},
{id:4,name:'分类4'},
],
},
methods:{
chooseMore:function(i){
this.typeArr[i] = true;
},
}
})
</script>
查阅了Vue官网的关于深入响应式原理的文档,大体了解了Vue如何来追踪data对象模型中对象的变化,Vue在初始化data对象模型将所有的属性property都转成了setter、getter,这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。
具体查看官网文档 https://cn.vuejs.org/v2/guide/reactivity.html#%E5%A6%82%E4%BD%95%E8%BF%BD%E8%B8%AA%E5%8F%98%E5%8C%96
Vue由于js限制不能直接监听对象和数组的变化,这种通过索引来直接赋值的方式是不会触发Vue的刷新的, 因此要通过一些其他的方法,想要Vue监听他的变化 ,可以使用set方法
例如上方我要操作数组元素就要通过 Vue.set(this.types,i,true)
这样就可以触发Vue的动态响应了,改变对象的属性也一样 Vue.set(this.obj,property,value)