Vue.js 数据绑定与指令详解

作者:山岚时间:2026-10-22 13:53:53浏览:209

本文详解 Vue.js 核心数据绑定机制,涵盖文本插值、HTML 属性绑定、表达式与过滤器用法。深入解析 v-model 在各类表单控件中的双向绑定实现,以及 class 和 style 的动态绑定策略,帮助开发者构建高效、可维护的前端应用。

Vue.js 数据绑定概述

本文详细介绍 Vue.js 中的数据绑定机制,旨在提供实用的参考示例。

数据绑定

Vue 采用响应式数据绑定系统。建立绑定后,DOM 会自动与数据保持同步,无需手动操作 DOM,从而简化代码、提升开发效率。

数据绑定语法与表达式

数据绑定语法

1. 文本插值

使用 Mustache 标签 {{ }} 进行文本插值。


<span>Hello {{ name }}</span>


data:{
    name: 'vue'
}
== > Hello vue

单次插值

使用单次插值后,即使修改 vm 实例的属性值,DOM 也不会再更新。


<span v-once="name">{{ name }}</span>

2. HTML 属性

同样可以使用 Mustache 标签 {{ }} 绑定 HTML 属性。


<div v-bind:id="'id-'+id"></div>

简写方式如下:


<div :id="'id-'+id"></div>

3. 绑定表达式

Mustache 标签内可放置 JavaScript 表达式,支持可选的过滤器(不支持正则表达式)。复杂转换建议使用过滤器或计算属性。


{{ index + 1}}
{{ index == 0 ? 'a' : 'b' }}
{{name.split('').join('|') }}
{{ var a = 1 }} //无效

4. 过滤器

Vue.js 允许在表达式后通过管道符 "|" 添加可选过滤器。


{{ name | uppercase }} // Vue.js将name的值传入给uppercase这个内置的过滤器中(本质是一个函数),返回字符串的大写值。
{{ name | filterA | filterB }}  //多个过滤器链式使用
{{ name | filterA arg1 arg2 }} //传入多个参数

此时,filterA 接收 name 作为第一个参数,arg1 和 arg2 分别作为第二、第三个参数传入过滤器函数。

最终输出为函数的返回值。arg1 和 arg2 可以是表达式,也可用单引号包裹直接传入字符串。

例如:


{{ name.split('') | limitBy 3 1 }} // ->u,e

过滤器 limitBy 接受两个参数:第一个参数指定显示个数,第二个可选参数指定从数组下标开始显示。

以下是 Vue.js 内置的 10 个过滤器(注:Vue.js 2.0 中已移除):

capitalize:将字符串首字符转为大写。\n\nuppercase:将字符串全部转为大写。\n\nlowercase:将字符串全部转为小写。\n\ncurrency:参数为 {String}[货币符号],{Number}[小数位],将数字转换为带货币符号的字符串,并自动添加千位分隔号。


{{ amount | currency '¥' 2 }} //若amount值为1000,则输出为¥1,000.00

pluralize:参数为 {String}single,[double,triple],用于字符串复数化处理。


<p v-for="c in count">{{ c | pluralize 'item' }} {{ c | pliralize 'st' 'nd' 'rd' 'th' }} </p>


//输出结果:
1item 1st
2items 2nd
3items 3rd
4items 4th

json:参数为 {Number}[indent] 空格缩进数,将 JSON 对象格式化为符合 JSON 规范的字符串。

debounce:传入值必须是函数,参数可选,为 {Number}[wait] 延时时长。作用是在调用函数 n 毫秒后执行该动作。


<input v-on:keyup="onKeyup | debounce 500"> //input元素上监听了keyup事件,并且延迟500ms触发

limitBy:传入值必须是数组,参数为 {Number}limit,{Number}[offset],limit 为显示个数,offset 为开始显示的数组下标。


<div v-for="item in items | limitBy 10"></div> //items为数组,且只显示数组中的前十个元素

filterBy:传入值必须是数组,参数为 {String | Function}targetStringOrFunction,即需要匹配的字符串或函数;"in" 为可选分隔符。{String}[...searchKeys] 指定检索的属性区域。


<p v-for="name in names | filterBy '1.0'">{{ name }}</p> //检索names数组中值包含1.0的元素

<p v-for="item in items | filterBy '1.0' in 'name'">{{ item | json }}</p> //检索items中元素属性name值为1.0的元素输出。检索区域也可以为数组,即in [name,version],在多个属性中进行检索。


//输出结果
vue1.0
{"name":"vue1.0","version":"1.0"}

可以使用自定义过滤函数,函数需在 options 的 methods 中定义。


<p v-for="item in items | filterBy customFilter"
  methods:{
    cuestomFilter:function(item){
      if(item.name) return true;  //检索所有元素中包含name属性的元素
    }
  }

orderBy:传入值必须是数组,参数为 {String|Array|Function}sortKeys,指定排序策略。

单个键名:


<p v-for="item in items | orderBy 'name' -1">{{ item.name}}</p> //items数组中以键名name进行降序排列

多个键名:


<p v-for="item in items | orderBy [name,version]">{{item.name}}</p> //使用items里的两个键名进行排序

自定义排序函数:


<p v-for="item in items | orderBy customOrder">{{item.name}}</p>
methods:{
  customOrder: function(a,b){
    return parseFloat(a.version) > parseFloat(b.version) //对比item中version的值的大小进行排序
  }
}

指令与计算属性

5. 指令

指令的值限定为绑定表达式。当表达式的值发生变化时,会触发特殊行为作用于绑定的 DOM 元素。

参数:src 为参数示例。


<img v-bind:src="avatar" /> <==>  <img src="{{avatar}}" />

修饰符:以半角句号 . 开头的特殊后缀,用于表示指令应以特定方式绑定。


<button v-on:click.stop="doClick"></button> //stop:停止冒泡。相当于调用了e.stopPropagagation().

计算属性

避免在模板中嵌入过重的业务逻辑,确保模板结构清晰且易于维护。

1. 基础例子


var vm = new Vue({
    el: '#app',
    data: {
      firstName:'Gavin',
      lastName:'CLY'
    },
    computed: {
      fullName:function(){
        //this指向vm实例
        return this.firstName + ' ' + this.lastName;
      }
    }
})


<p>{{ firstName }}</p>  //Gavin
<p>{{ lastName }}</p>  //CLY
<p>{{ fullName }}</p>  //Gavin CLY

注:此时对 vm.firstName 和 vm.lastName 进行修改,始终会影响 vm.fullName。

2. Setter

更新属性时带来便利。


var vm = new Vue({
    el:'#el',
    data:{
      cents:100
    },
    computed:{
      price:{
        set:function(newValue) {
          this.cents = newValue * 100;
        },
        get:function(){
          return (this.cents / 100).toFixed(2);
        }
      }
    }
})

表单控件与 v-model 双向绑定

表单控件

v-model:对表单元素进行双向数据绑定。修改表单元素值时,实例 vm 中对应的属性值同步更新,反之亦然。


var vm = new Vue({
    el:'#app',
    data: {
      message: '',
      gender: '',
      cheched: '',
      multiChecked: '',
      a: 'checked',
      b: 'checked'
    }
})

1. Text

输入框示例,用户输入的内容与 vm.message 直接绑定:


<input type="text" v-model="message" />
<span>Your input is : {{ message }} </span>

2. Radio

单选框示例:


<label><input type="radio" value="male" v-model="gender">男</lable>
<label><input type="radio" value="famale" v-model="gender">女</lable>
<p>{{ gender }}</p> //显示的是value值

3. Checkbox

单个勾选框,v-model 即为布尔值,此时 Input 的 value 不影响 v-model 的值。


<input type="checkbox" v-model="checked" />
<span>checked: {{ checked }} </span> //显示的是true/false

多个勾选框,v-model 使用相同的属性名称,且属性为数组。


<label><input type="checkbox" value="1" v-model="multiChecked">1</label>
<label><input type="checkbox" value="1" v-model="multiChecked">2</label>
<label><input type="checkbox" value="1" v-model="multiChecked">3</label>
<p>MultiChecked:{{ multiChecked.join{'|'} }}</p> //multiChecked:1|2

4. Select

单选


<select v-model="selected">
  <option selected>A</option>
  <option>B</option>
  <option>C</option>
</select>
<span>Selected: {{ selected }}</span>

多选


<select v-model="multiSelected" multiple>
  <option selected>A</option>
  <option>B</option>
  <option>C</option>
</select>
<span>MultiSelected: {{ multiSelected.join('|') }}</span>

5. 绑定 value

通过 v-bind 实现,将表单控件的值绑定到 Vue 实例的动态属性上。

Checkbox


<input type="checkbox" v-model="checked" v-bind:true-value="a" v-bind:false-value="b" />

选中:


vm.checked == vm.a  //=> true

未选中:


vm.checked == vm.b //=>true

Radio


<input type="radio" v-model="checked" v-bind:value="a" >

选中:


vm.checked == vm.a //=> true

3. Select Options


<select v-model="selected">
    <!-- 对象字面量 -->
    <option v-bind:value="{ number:123}">123</option>
</select>

选中:


typeof vm.selected //=> object
vm.selected.number //=> 123

6. 参数特性

.lazy:默认情况下,v-model 在 input 事件中同步输入框与数据,添加 lazy 属性后会在 change 事件中同步。


<!-- 在 "change" 而不是 "input" 事件中更新 -->
<input v-model.lazy="msg" >

.number:自动将用户输入转为 Number 类型,如果原值转换结果为 NaN,则返回原值。


<input v-model.number="age" type="number">

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


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

Class 与 Style 动态绑定

Class 与 Style 绑定

1. Class 绑定

对象语法:v-bind:class 接受参数是一个对象,且可以与普通的 class 属性共存。


<div class="tab" v-bind:class="{'active':active,'unactive':!active}"></div>

vm 实例中需要包含:


data:{
  active:true
}

渲染结果为:


<div class="tab active"></div>

数组语法:v-bind:class 也接受数组作为参数。


<div v-bind:class="[classA,classB]"></div>

vm 实例中需要包括:


data:{
  classA:"class-a",
  classB:"class-b"
}

渲染结果为:


<div class="class-a class-b"></div>

使用三元表达式切换数组中的 class。


<div v-bind:class="[classA,isB?classB:""]"></div>

若


vm.isB = false

则渲染结果为


<div class="class-a"></div>

2. 内联样式绑定 (style 属性绑定)

对象语法:直接绑定符合样式格式的对象。


<div v-bind:style="alertStyle"></div>

vm 实例中包含:


data:{
  alertStyle:{
    color: 'red',
    fontSize: '2px'
  }
}


<div v-bind:style="{fontSize:alertStyle.fontSize,color:'red'}"></div>

数组语法:v-bind:style 允许将多个样式对象绑定到同一元素上。


<div v-bind:style="[ styleObjectA,styleObjectB]" .></div>

3. 自动添加前缀

在使用 transform 这类属性时,v-bind:style 会根据需要自动添加厂商前缀。:style 在运行时进行前缀探测,如果浏览器版本本身就不支持不加前缀的 css 属性,那就不会添加。

希望本文所述对大家 vue.js 程序设计有所帮助。

作者最新文章