v-for
通过v-for
进行循环,不光可以拿到元素本身,也可以拿到索引值。
如果数据是对象类型,则可以使用(value,key,index)
进行取值。
需要注意的是,当不指定key/value
而只指定一个迭代变量,那么该迭代变量取值会取value
<body>
<div id="app">
<ul>
<li v-for="(ele,index) in array">{{ele}}-{{index}}</li>
</ul>
</div>
<script src='https://cdn.jsdelivr.net/npm/vue/dist/vue.js'></script>
<script>
"use strict";
const app = new Vue({
el: "#app",
data: {
array: ["第一个元素", "第二个元素", "第三个元素"],
}
})
</script>
</body>
v-if
当if
后的条件为true
时则渲染出该标签以及该标签内的子标签。为false
时则不渲染。
类似于v-show
,但是可以与v-else
进行联用。
<body>
<div id="app">
<p v-if="conditionOne">渲染我</p>
<p v-if="conditionTwo">不渲染我</p>
</div>
<script src='https://cdn.jsdelivr.net/npm/vue/dist/vue.js'></script>
<script>
"use strict";
const app = new Vue({
el: "#app",
data: {
conditionOne: true,
conditionTwo: false,
},
})
</script>
</body>
v-else
该指令应当和v-if
连用,效果与v-if
相反。
这两组指令一个代表如果渲染,一个代表否则渲染。
<body>
<div id="app">
<p v-if="conditionOne">条件为真渲染我</p>
<p v-else>否则渲染我</p>
</div>
<script src='https://cdn.jsdelivr.net/npm/vue/dist/vue.js'></script>
<script>
"use strict";
const app = new Vue({
el: "#app",
data: {
conditionOne:false,
},
})
</script>
</body>
v-else-if
额外的判断条件,当有v-if/v-else/v-else-if
在时,只会执行其中的一条。
<body>
<div id="app">
<p v-if="grades > 90">成绩优秀</p>
<p v-else-if="grades > 60">成绩及格</p>
<p v-else-if="grades > 40">成绩一般</p>
<p v-else>成绩较差</p>
</div>
<script src='https://cdn.jsdelivr.net/npm/vue/dist/vue.js'></script>
<script>
"use strict";
const app = new Vue({
el: "#app",
data: {
grades:80,
},
})
</script>
</body>
逻辑判断
在v-if/v-else/v-else-if
中,可以使用逻辑判断与或非。
符号 | 描述 |
---|---|
&& | 与(优先级3),一真一假取一假 |
|| | 或(优先级2),一真一假取一真 |
! | 非(优先级1),两个为真才取真 |
<body>
<div id="app">
<p v-if="conditionOne && conditionTwo">两个为真,渲染</p>
</div>
<script src='https://cdn.jsdelivr.net/npm/vue/dist/vue.js'></script>
<script>
"use strict";
const app = new Vue({
el: "#app",
data: {
conditionOne:true,
conditionTwo:true,
},
})
</script>
</body>
key属性
由于虚拟DOM
的渲染复用,所以我们的真实DOM
并不会做我们想要的刷新。
如下所示,我们定义了两个input
框,但是会出现窜值的情况(即不同的输入框切换会保留一样的值):
<body>
<div id="app">
<input v-if="type == 'phone'" type="text" placeholder="手机注册" >
<input v-if="type == 'email'" type="text" placeholder="邮箱注册" >
<br>
<label for="phoneReigster">手机
<input id="phoneReigster" type="radio" v-model="type" value="phone">
</label>
<label for="emailReigster">邮箱
<input id="emailReigster" type="radio" v-model="type" value="email">
</label>
</div>
<script src='./vue.js'></script>
<script>
"use strict";
const app = new Vue({
el: "#app",
data: {
type: "phone",
},
});
</script>
</body>
这样的情况对用户体验来说并不友好,所以我们可以指定不同的key
进行唯一绑定,这样就不会窜值了。
<input v-if="type == 'phone'" type="text" placeholder="手机注册" key="phoneRigster">
<input v-if="type == 'email'" type="text" placeholder="邮箱注册" key="emailRigster">
Vue与真实DOM之间存在一层虚拟DOM,虚拟DOM进行渲染时会尽量复用已存在的组件,而不是创建新的组件。
上述示例中看起来写了两个input,其实是被复用了,所以导致窜值问题的出现,使用属性key可解决这个问题
:key唯一标识
在使用v-for
进行循环的时候,你应该指定:key
唯一标识,并且与渲染值要有一一对应关系,这样可以提升你后期操纵的效率。
虚拟DOM
的数组插入会依赖于diff
算法,如下图所示:
如果没有指定:key
唯一标识,diff
算法会这样执行:
虚拟DOM在渲染到真实DOM时,会将第三个位置改成E,会将第四个位置改成C,会将第五个位置改成D
显然这样效率是很低下的
如果指定了:key
唯一标识,且该唯一标识与渲染值有一一对应的关系,那么diff
算法就会直接进行插入。
如下代码所示,你应该在循环时指定:key
唯一标识,并且要与渲染值一一对应。
<body>
<div id="app">
<ul>
<!-- 一定要一一对应,所以这里是与value做绑定,而不是index,index是可以变化的 -->
<li v-for="(value,index) in array" :key="value">{{index+1}}-{{value}}</li>
</ul>
<button @click.once=func()>插入</button>
</div>
<script src='./vue.js'></script>
<script>
"use strict";
const app = new Vue({
el: "#app",
data: {
array:[
"A","B","C","D",
]
},
methods:{
func(){
this.array.splice(2,0,"E");
},
},
});
</script>
</body>