早安喵咪~
关于v-if与v-for为什么不能连用?
原因是很简单的:v-for优先级比v-if高。当需要判断某个条件成立后想把成立的一组数据遍历,初学者会选择v-for+v-if。当然,是会出问题的。v-for永远都会比v-if先执行。我举个栗子
<ul>
<li
v-for="user in users"
v-if="user.isSelected"
:key="user.id"
>
{{user.name}}
</li>
</ul>
const app = new Vue({
el:'#app1',
data:{
users:[{
id:uid,
name:uname,
isSelected:true
}]
},
});
上述情况,尽管只想使用user数组中一个数据,但v-for仍会遍历数组。
当然,可以用下面这种方式来使用。因为v-if是惰性的(没印象?查看上一篇文章),所以不会消耗性能去渲染多余的元素.
<ul>
<li
v-for="user in users"
:key="user.id"
>
<span v-if="user.isSelected">{{user.name}}</span>
</li>
</ul>
下面用数组提供的过滤方法举个解决栗子。
<ul>
<li
v-for="user in selected_users"
:key="user.id"
>
{{user.name}}
</li>
</ul>
const app = new Vue({
el:'#app1',
data:{
user:[{
id:uid,
name:uname,
isSelected:true,
}]
},
computed:{
selected_users: function(){
//数组的过滤方法
return this.users.filter(function (user){
return user.isSelected;
});
},
},
});
关于Vue提供的过滤器
Vue提供的过滤器有两种,一种是组件内部的本地过滤器,一种是创建实例之前全局过滤器。
全局过滤器↓
// 注册
Vue.filter('my-filter', function (value) {
// 返回处理后的值
})
// getter,返回已注册的过滤器
var myFilter = Vue.filter('my-filter')
局部过滤器↓
const app2 = new Vue({
el:'#app2',
data:{
},
filters:{
my-filter: function(value){
// 返回处理后的值
},
}
});
过滤器可以用在两个地方:双花括号插值和 v-bind 表达式 (后者从 2.1.0+ 开始支持)。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符号指示
{{message | my-filter}}
<!--多个过滤器可以串联-->
{{message | filter1 | filter2}}
关于vue监听的问题
初学者在一些教程里大多都会听说的就是vue响应式数据…我是搞不明白为什么vue在官网上介绍响应式系统的时候要用响应式这种词…因为很容易和响应式布局搞混。
看个例子
<div id="app1">
<p v-for="(user, index) in users" :key="user.id">{{user.name}}</p>
<button @click="btnClick()">点击改变数组</button>
</div>
const a = {
name:'张三',
id:1
};
const b = {
name:'李四',
id:2
};
const c = {
name:'王五',
id:3
};
const d = {
name:'赵六',
id:4
};
const app1 = new Vue({
el:'#app1',
data:{
users:[a,b],
},
methods: {
btnClick:function(){
this.users[0] = c;
this.users.push(d);
}
},
});
上述代码中,按钮点击会把数组第0个位置的对象a换成对象c,并把对象d插入到数组末尾。当把push(d)语句注释掉,就会发现点击后页面并没有重新渲染。而当push(d)时,数组新添了一个成员,页面重新渲染了。
注意!
为了解决某些时候需要监听数组成员的改变,vue提供了set功能。
Vue.set(this.users, 0 ,c);
经过三个小时的查阅总结了一些监听问题
const a = {
name:'张三',
}
const b = {
name:'李四',
}
const app = new Vue({
el:'#app',
data:{
arr1:[a],
msgs:['a','b','c'],
person:{
name:'王五'
}
},
methods:{
arr1_btnClick(index){
this.arr1[index] = b;//此处不会动态渲染页面
//解决办法,使用Vue.set 如下传参(arr,index,value)
Vue.set(this.arr1, 0, b);
this.arr1[index].name = '张三三';//此处会动态渲染页面
a.name = '法外狂徒张三三';//此处会动态渲染页面
this.msgs[index] = 'aaa';//此处不会动态渲染页面
//解决办法,使用Vue.set
Vue.set(this.msgs, 0, 'aaa');
this.person.id = 1;//对象添加新属性,页面通过遍历来显示person所有数据时,此处不会动态渲染页面
//a.id = 1;同上也是对象添加新属性,也不会渲染
//解决办法,使用Vue.set 如下传参(object,key,value)
Vue.set(this.person, 'id',1);
this.arr1.length = 5;//修改arr1的长度,vue不会检测到变动
//解决办法.splice
this.arr1.splice(6);
}
}
});
感谢这位作者的文章。原文更详细一些。
https://www.cnblogs.com/thinkingthigh/p/7789108.html
强调一点
不是不能使用数组索引!在某些情况下需要更改一个对象内部的某个属性,而这个属性不需要显示到页面时,自然可以使用。
补充v-bind
我是没想到今天又看到了v-bind的一种用法…
v-bind还可以动态的绑定标签上的属性。比如
<button :disabled="true">不能交互</button>
当然,可以使用方法、表达式。
<img :src="'/path/to/images/' + fileName"> <!--表达式-->
<div :style="{ fontSize: size + 'px' }"></div>