Vue快速上手:四、模板的逻辑渲染、列表渲染、表单数据的绑定

202 阅读4分钟

模板的条件渲染

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-ifv-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

如上itemdatas数据组循环的一个自定义别名,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-ifv-show同样也可以使用循环别的变量别名。在vue2中最好是别将v-ifv-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>