模板的条件渲染
1、v-show
v-show指令可以根据条件显示、隐藏元素,使用格式:v-show = '表达式',表达式的值为真就显示,为假隐藏。
<template>
<h1 v-show="isShow">Hello!</h1>
</template>
<script setup>
import { ref } from "vue";
const isShow = ref(false);
// 一秒后后显示
setTimeout(() => {
isShow.value = true;
}, 1000);
</script>
v-show的隐藏并不会将元素删除,只是给元素加了一个css属性display: none将其隐藏的。
2、v-if
v-if同样也是根据条件的真假来判断元素是否显示,但是和v-show不同的是,v-if为假时会清除这个元素,为真时是添加这个元素。
<template>
<h1 v-if="isShow">Hello!</h1>
</template>
<script setup>
import { ref } from "vue";
const isShow = ref(false);
// 一秒后后显示
setTimeout(() => {
isShow.value = true;
}, 1000);
</script>
3、v-else
和编程语言一样有if那就有else,使用如下:
<template>
<h1 v-if="isShow">Hello!</h1>
<h1 v-else>哈喽</h1>
</template>
<script setup>
import { ref } from "vue";
const isShow = ref(true);
</script>
4、v-else-if
同理v-else-if那肯定也有的,同样v-else-if可以连续使用多次,如下:
<template>
<span v-if="type === 'a'"> A </span>
<span v-else-if="type === 'b'"> B </span>
<span v-else-if="type === 'c'"> C </span>
<span v-else>Other</span>
</template>
<script setup>
import { ref } from "vue";
const type = ref('a');
</script>
v-if和v-show虽然实现的效果都差不多,但是本质区别还是挺大的,一个是创建/删除元素,另一个是显示/隐藏元素。如果是在频繁的切换的情况下,v-show明显要比v-if的性能要好,如果是加载的切换项特别多的情况或在运行时很少去切换的情况下,v-if更合适。
列表渲染
v-for指令可以来渲染一个列表,格式为:v-for = "(循环项, 循环索引) in 数据源",如:
<template>
<ul>
<li v-for="(item, index) in datas">
{{ index }} -- {{ item.id }} -- {{ item.name }}
</li>
</ul>
</template>
<script setup>
import { reactive } from "vue";
const datas = reactive([
{id: 1, name: '苹果'},
{id: 2, name: '华为'},
{id: 3, name: 'vivo'},
{id: 3, name: 'oppo'},
{id: 3, name: '小米'},
{id: 3, name: '一加'},
]);
</script>
使用key
如上item是datas数据组循环的一个自定义别名,index是循环索引的一个别名(从0开始)。
在使用v-for指令的时候最好给循环标签添加加一个key,以便Vue可以跟踪每个节点的标识,从而重用和重新排序现有的元素。如以上的就可以改为:
<li v-for="(item, index) in datas" :key="item.id">
{{ index }} -- {{ item.id }} -- {{ item.name }}
</li>
key的值得为一个不会重复的值,一般情况下是不建议使用index索引作为key的,因为索引是会根据数据调整而变化的,像上面的数据里的id这种每项唯一而且又不会变的是最合适的。
对象列表渲染
如果数据列表是一个对象时,使用的方法也是一样的,唯一需要注意的就是索引将不会从0开始了,此时的索引就是对象的键值索引。
<template>
<ul>
<li v-for="(item, index) in datas" :key="index">
{{ index }} -- {{ item }}
</li>
</ul>
</template>
<script setup>
import { reactive } from "vue";
const datas = reactive({
id: 1,
name: "允儿",
age: 33,
jpb: "歌手、演员、主持人",
});
</script>
输出结果为:
- id -- 1
- name -- 允儿
- age -- 33
- jpb -- 歌手、演员、主持人
循环嵌套渲染
列表嵌套是可以循环嵌套的,如下:
<template>
<ul>
<li v-for="(item, index) in datas">
<span v-for="(subItem, subIndex) in item" :key="subIndex">{{ subItem }}</span>
</li>
</ul>
</template>
<script setup>
import { reactive } from "vue";
const datas = reactive([
{id: 1, name: '苹果'},
{id: 2, name: '华为'},
{id: 3, name: 'vivo'},
{id: 3, name: 'oppo'},
{id: 3, name: '小米'},
{id: 3, name: '一加'},
]);
</script>
这段代码就是将前面的循环改造了一下,数组里的对象也采用循环输出每项的方式。被嵌套的循环是可以使用上级的变量别名的,但要注意别重复命名。
v-if和v-show同样也可以使用循环别的变量别名。在vue2中最好是别将v-if和v-for放在同一级别的标签上,会造成优先级的问题,vue3中优化了这个问题,但还是建议别放同一标签上,如:
<div v-for="(item ,index) in datas" v-if="datas.length > 0" :key="index">
// 其它代码
</div>
建议写成这样:
<template>
<template v-if="datas.length > 0">
<div v-for="(item ,index) in datas" :key="index">
{{ item }}
</div>
</template>
</template>
这样写就逻辑上主次分明一些,同时当如果只需要一个循环逻辑而不需要生成标签时,可使用template标签来作为循环标签。
表单输入绑定
传统写法里表单的值都在value属性上,所以要想使表单绑定一个响应式数据,直接绑定动态属性语法即可,如:
<template>
<input type="text" :value="name">
</template>
<script setup>
import { ref } from "vue";
const name = ref("");
</script>
这样一来响应式数据一旦发生了变化,表单同样也会更新变化。但是表单的需求和其它地方不一样,我们往往需要的是表单的修改值同样也能影响到响应式数据。
我们可以这么做,为这个表单绑定一个输入事件来改动响应式数据的值,如:
<template>
<input type="text" :value="name" @input="handleInput">
<p>{{ name }}</p>
</template>
<script setup>
import { ref } from "vue";
const name = ref("");
// input事件方法
const handleInput = (e) => {
name.value = e.target.value;
}
</script>
功能虽然实现了,但是觉得就有点麻烦了,要是表单一多,那不得写一大堆或者去封装一个通用的公共函数才行。
vue为我们提供了一个v-model指令,不用我们手动去处理这个过程,vue会自动的形成对表单数据的双向绑定,如:
<template>
<input type="text" v-model="name">
<p>{{ name }}</p>
</template>
<script setup>
import { ref } from "vue";
const name = ref("");
</script>