Vue 的动态绑定是其核心功能之一,通过它可以实现数据与视图之间的双向绑定,当数据发生变化时,视图会自动更新,反之亦然。以下是几种常见的动态绑定方式:
数据绑定
-
插值表达式:使用双大括号
{ { }}
将数据插入到模板中。例如{ { message }}
,当message
数据发生变化时,页面上对应的位置会自动更新显示新的值。这种方式主要用于文本内容的绑定。 -
v-text 指令:与插值表达式类似,也是用于绑定文本内容。例如
<span v-text="message"></span>
,它会将message
的值设置为<span>
元素的文本内容。与插值表达式不同的是,v-text
会替换掉元素内的所有内容,而插值表达式只会替换掉大括号内的部分。
属性绑定
-
v-bind 指令:用于绑定元素的属性。例如
<img v-bind:src="imageSrc">
,将imageSrc
数据绑定到<img>
元素的src
属性上,当imageSrc
的值改变时,图片的地址也会相应更新。简写形式为<img :src="imageSrc">
。 -
绑定多个属性:可以使用对象语法或数组语法。对象语法如
<div v-bind="{ id: someId, title: someTitle }"></div>
,将多个属性绑定到<div>
元素上。数组语法如<div v-bind:[attributeName]="value"></div>
,其中attributeName
是一个变量,可以根据变量的值动态绑定不同的属性。
事件绑定
-
v-on 指令:用于绑定事件处理器。例如
<button v-on:click="handleClick">点击我</button>
,当按钮被点击时,会调用handleClick
方法。简写形式为<button @click="handleClick">点击我</button>
。 -
事件修饰符:Vue 提供了一些事件修饰符,如
.stop
阻止事件冒泡、.prevent
阻止默认行为、.once
事件只触发一次等。例如<form @submit.prevent="onSubmit"></form>
,在表单提交时阻止默认的提交行为。
表单输入绑定
-
v-model 指令:实现了表单输入和应用状态之间的双向绑定。例如
<input v-model="message">
,当用户在输入框中输入内容时,message
的值会实时更新;反之,当message
的值发生变化时,输入框的内容也会自动更新。v-model
可以用于input
、textarea
、select
等表单元素。 -
修饰符:
v-model
也有修饰符,如.lazy
使数据在change
事件触发时才更新,而不是input
事件;.number
自动将用户的输入值转换为数值类型;.trim
自动过滤用户输入的首尾空白字符。
计算属性和侦听器
-
计算属性:基于它们的依赖进行缓存,只有当依赖项发生变化时,才会重新计算。例如:
JavaScript复制
computed: { fullName() { return `${this.firstName} ${this.lastName}`; } }
在模板中使用
{ { fullName }}
时,只有当firstName
或lastName
发生变化时,fullName
才会重新计算。 -
侦听器:用于观察数据的变化并执行一些操作。例如:
JavaScript复制
watch: { firstName(newVal, oldVal) { console.log(`名字从 ${oldVal} 变为 ${newVal}`); } }
当
firstName
的值发生变化时,会触发侦听器中的函数。
通过这些动态绑定方式,Vue 能够高效地实现数据与视图之间的同步更新,提高开发效率和用户体验。
<script setup>
import { ref } from 'vue';
const str=ref('')
const list=ref([
{isComplete:true,
text:'吃饭',
},
{
isComplete:false,
text:'睡觉'
},
{
isComplete:false,
text:'打豆豆'
},
])
function add(){
list.value.push({
isComplete:false,
text:str.value
})
str.value="";
}
function del(index){
list.value.splice(index,1)
}
</script>
<template>
<div class="box1">
<div class="title">Todo App</div>
<div class="todo-form">
<input v-model="str" class="todo-input" type="text" placeholder="add a todo">
<div @click="add" class="todo-button">Add Todo</div>
</div>
<div v-for="(item,index) in list" :class="[item.isComplete ? 'item box2':'item' ]">
<div class="name">
<input v-model="item.isComplete" type="checkbox"/>
<div>{
{ item.text }}</div>
</div>
<div @click="del(index)" class="del">del</div>
</div>
</div>
</template>
<style scoped>
body{
background: linear-gradient(to right, blue,purple);
}
.box1{
width: 80%;
height: 500px;
background-color: aliceblue;
margin: auto;
padding-top: 40px;
border-radius: 5px;
margin-top: 20px;
box-sizing: border-box;
}
.title{
font-size: 50px;
color: black;
font-weight: 700;
text-align: center;
}
.todo-form{
display: flex;
padding-left: 20px;
padding-top: 30px;
}
.todo-input{
width: 60%;
height: 50px;
border-color: blanchedalmond;
outline: none;
border-radius: 20px 0px 0px 20px;
padding-left: 15px;
}
.todo-button{
line-height: 52px;
width: 100px;
height: 52px;
border-radius: 0px 20px 20px 0px;
text-align: center;
background: linear-gradient(to right, blue,purple);
color: aliceblue;
cursor: pointer;
user-select: none;
}
.item{
justify-content: space-between;
display: flex;
box-sizing: border-box;
align-items: center;
width: 80%;
height: 50px;
margin: 8px auto;
padding: 16px;
border-radius: 20px;
box-shadow: 0px 8px 20px rgba(149, 157, 165, 0.2);
}
.del{
color: red;
}
.box2{
display: flex;
text-decoration: line-through;
opacity: 0.4;
}
</style>