Vue 指令v-for和v-model

上一篇文章中总结了v-bind和v-on指令的用法。这篇文章总结一下v-for和v-model指令的用法。

(1)v-for

v-for指令可以对数组或者对象或者整数进行循环。需要使用 item in items(或者item of items) 的特殊语法,items是定义的原数组或者原对象,item是数组元素或者对象属性的别名。

1.对整数进行循环:
<div>
  <span v-for="n in 10">{{ n }} </span>
</div>
2.v-for对数组进行循环:
<div id="app">
   <ul>
       <li v-for="item in lists">
           {{item}}
       </li>
   </ul>
</div>
<script>
    var app=new Vue({
        el:"#app",
        data:{
          lists:[
              "苹果",
              "香蕉",
              "橘子"
          ]
        }
    })
</script>

渲染结果为:

<div id="app">
   <ul>
       <li>苹果</li>
       <li>香蕉</li>
       <li>橘子</li>
   </ul>
</div>
v-for支持一个可选的第二个参数作为当前项的索引:
<div id="app">
    <ul>
        <li v-for="(item,index) in lists">
            {{index}}--{{item}}
        </li>
    </ul>
</div>

渲染的结果为:

<div id="app">
   <ul>
       <li>0--苹果</li>
       <li>1--香蕉</li>
       <li>2--橘子</li>
   </ul>
</div>
3.v-for对对象进行循环

在遍历对象时,是按照Object.keys()的结果遍历的,在不同javascript的引擎下不能保证结果相同。

<div id="app">
    <ul>
        <li v-for="value in object">
            {{value}}
        </li>
    </ul>
</div>
<script>
    var app=new Vue({
        el:"#app",
        data:{
            object:{
                "11":"q",
                "22":"w",
                "33":"e"
            }
        }
    })
</script>

渲染的结果为:

<div id="app">
   <ul>
       <li>q</li>
       <li>w</li>
       <li>e</li>
   </ul>
</div>

可以提供第二个参数作为键名,第三个参数作为索引

<div id="app">
    <ul>
        <li v-for="(value,key,index) in object">
           {{index}}--{{key}}:{{value}}
        </li>
    </ul>
</div>

渲染的结果为:

<div id="app">
   <ul>
       <li>0--11:q</li>
       <li>1--22:w</li>
       <li>2--33:e</li>
   </ul>
</div>
4.v-for与方法和计算属性的联合使用:

有时,我们想要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据。在这种情况下,可以创建返回过滤或排序数组的计算属性或者方法:

<div id="app">
    <ul>
        <li v-for="n in evenNumbers">{{ n }}</li>
    </ul>
</div>
<script>
    var app=new Vue({
        el:"#app",
        data: {
            numbers: [ 1, 2, 3, 4, 5 ]
        },
        computed: {
            evenNumbers: function () {
                return this.numbers.filter(function (number) {
                    return number % 2 === 0
                })
            }
        }
    })
</script>
<div id="app">
    <ul>
        <li v-for="n in even(numbers)">{{ n }}</li>
    </ul>
</div>
<script>
    var app=new Vue({
        el:"#app",
        data: {
            numbers: [ 1, 2, 3, 4, 5 ]
        },
        methods: {
            even: function (numbers) {
                return numbers.filter(function (number) {
                    return number % 2 === 0
                })
            }
        }
    })
</script>

渲染结果均为:

<div id="app">
   <ul>
       <li>2</li>
       <li>4</li>
   </ul>
</div>
5.v-for用在内置标签<template>上,渲染多个元素
<div id="app">
    <ul>
        <template v-for="item in lists">
            <li>name:{{item.name}}</li>
            <li>number:{{item.number}}</li>
        </template>
    </ul>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            lists: [
                {
                    name: "苹果",
                    number: 1
                },
                {
                    name: "香蕉",
                    number: 2
                },
                {
                    name: "橘子",
                    number: 3
                }
            ]
        }
    })
</script>

渲染结果为:

    <ul>
        <li>name:苹果</li>
        <li>number:1</li>
        <li>name:香蕉</li>
        <li>number:2</li>
        <li>name:橘子</li>
        <li>number:2</li>
    </ul>
6.v-for与v-if

当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你想为仅有的一些项渲染节点时,这种优先级的机制会十分有用,如下:

<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo }}
</li>

上面的代码只传递了未完成的 todos。
而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 <template>)上。如:

<ul v-if="todos.length">
  <li v-for="todo in todos">
    {{ todo }}
  </li>
</ul>
<p v-else>No todos left!</p>
(2)v-model:

v-model可以实现表单类元素上的双向绑定数据。它会根据控件类型自动选取正确的方法来更新元素。

1.文本
<div id="app">
    <p>{{message}}</p>
    <input v-model="message">
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: "hhhhh"
        },
    })
</script>

在改变input的内容的同时,<p>中的内容也会实时更新。

使用v-model时,用中文输入法输入中文时,一般在拼音阶段,Vue不会更新数据,当确定汉字时才会更新,如果希望总是实时更新,可以用v-on:input来代替v-model。
实际上v-model是一个特殊的语法糖,它会在不同的表单元素上智能处理。

<div id="app">
    <p>{{message}}</p>
    <input @input="handle">
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: ""
        },
        methods:{
            handle:function(e){
                this.message=e.target.value;
            }
        }
    })
</script>

上面代码中,e.target是引发input事件的DOM元素,e.target.value获得该输入框的值。

2.复选框
<div id="app">
    <!--复选框单独使用-->
    <input type="checkbox" id="checkbox" v-model="check">
    <label for="checkbox">{{check}}</label>
    <br/>
    <br/>
    <!--复选框组合使用-->
    <input type="checkbox" id="jack" value="Jack" v-model="name">
    <label for="jack">Jack</label>
    <input type="checkbox" id="john" value="John" v-model="name">
    <label for="john">John</label>
    <input type="checkbox" id="mike" value="Mike" v-model="name">
    <label for="mike">Mike</label>
    <br>
    <span>Checked names: {{ name }}</span>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            check: true,
            name: []
        },
    })
</script>

在复选框单独使用时,用v-model绑定一个布尔值,label中渲染的内容也会相应更新。
在复选框组合使用时,v-model与value配合使用,多个勾选框的value值绑定到同一个数组,如果value的值在数组当中,就会选中这一项。这个过程也是双向的,在勾选时,value的值也会自动push到这个数组中。

3.单选按钮

v-model配合value一起使用可以实现互斥选择的效果:

<div id="app">
    <input type="radio" id="one" value="One" v-model="picked">
    <label for="one">One</label>
    <br>
    <input type="radio" id="two" value="Two" v-model="picked">
    <label for="two">Two</label>
    <br>
    <span>Picked: {{ picked }}</span>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            picked:""
        },
    })
</script>
4.下拉选择器
下拉选择器中的单选:
<div id="app">
    <!--单选-->
    <select v-model="selected1">
        <option disabled value="">请选择</option>
        <option>A</option>
        <option value="b">B</option>
        <option>C</option>
    </select>
    <span>选择的是: {{ selected1 }}</span>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            selected1: "",
        },
    })
</script>

如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此,更推荐像上面这样提供一个值为空的禁用选项。

<option>是备选项,如果含有value属性,v-model就会优先匹配value的值,如果没有,就会直接匹配<option>的text,比如上面代码中,选中第二项的时候,selected1的值是b,而不是B(如下图所示):
在这里插入图片描述

下拉选择器中的多选:
<div id="app">
    <select v-model="selected2" multiple>
        <option>A</option>
        <option value="b">B</option>
        <option>C</option>
    </select>
    <br>
    <span>选择的是: {{ selected2 }}</span>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            selected2: []
        },
    })
</script>

对于下拉选择器中的多选,在操作过程中:
对于 windows:按住 Ctrl 按钮来选择多个选项。
对于 Mac:按住 command 按钮来选择多个选项。

在业务中,<option>经常用v-for动态输出,value是用v-bind来动态输出的,例如:

<div id="app">
    <select v-model="selected">
        <option disabled value="">请选择</option>
        <option v-for="option in options"
                v-bind:value="option.value">{{option.text}}
        </option>
    </select>
    <span>选择的是: {{ selected }}</span>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            selected: "",
            options: [
                {
                    text: "HTML",
                    value: "html"
                },
                {
                    text: "JavaScript",
                    value: "js"
                },
                {
                    text: "CSS",
                    value: "css"
                }
            ]
        },
    })
</script>
5.修饰符
.lazy

input输入框的change事件,要在 input 失去焦点的时候才会触发,而input 事件在用户输入时触发,它是在元素值发生变化时立即触发。

在默认情况下,v-model在每次input事件触发后将输入框的值与数据进行同步(除了中文输入法的情况),可以添加.lazy修饰符,从而转变为使用change事件进行同步。

<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg" >

这时,msg并不是实时改变的,而是在失去焦点或者按回车时才更新。

.number

如果想自动将用户的输入值转换为数值类型,可以给v-model添加.number修饰符。
这通常很有用,因为即使在 type=“number” 时,HTML 输入元素的值也总会返回字符串。

div id="app">
    <p>{{message}}</p>
    <input v-model.number="message">
    <div v-on:click="aa">点击这里获取当前类型</div>
</div>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            message: ""
        },
        methods:{
            aa:function(){
                console.log(typeof this.message)
            }
        }
    })
</script>

当输入数字后又输入非数字的字符时,最后的结果只会保留最开始输入的数字:
在这里插入图片描述
当最开始就输入非数字字符时,这个修饰符将不起任何作用,返回输入的值。即使后面再输入数字也被视做字符串:
在这里插入图片描述

.trim

如果要自动过滤用户输入的首尾空白字符,可以给v-model添加.trim修饰符。

<input v-model.trim="msg">

参考:
1.Vue.js官方文档
2.《Vue.js实战》

Logo

前往低代码交流专区

更多推荐