一、$set的作用和語法結構
$set是uniapp框架提供的一種方法,可以對data中的數據進行修改和更新。$set的語法結構如下:
Vue.set(object, key, value)或vm.$set(object, key, value)
其中object必填,是要修改的對象;key必填,是對象中要修改或更新的屬性名;value必填,是屬性的新值。
二、$set的常見應用場景
在vue.js的開發中,可以通過直接對data中的數據進行修改來實現對視圖的更新,但當需要修改或更新對象中某個屬性的時候,如果直接對屬性進行修改,vue.js無法監測到數據的變化,也就無法觸發視圖更新。這時就需要使用$set方法來通知vue.js數據改變了,視圖需要更新。下面是$set的常見應用場景。
1、通過數組下標更新數組數據
如果需要修改數組中的某個元素,可以通過數組下標來更新數組數據。例如,有一個tasks數組,需要將第一個任務的狀態由未完成改為已完成,可以使用以下代碼實現:
this.tasks[0].status = 'completed';
上面的代碼可以更新數據,但是vue.js無法檢測到數據的變化,這時就需要使用$set來通知vue.js更新數據。代碼如下:
this.$set(this.tasks[0], 'status', 'completed');
這樣vue.js就能檢測到數據的變化,觸發視圖的更新。
2、通過對象屬性名更新對象數據
如果需要修改對象中的某個屬性,也可以使用$set來觸發視圖更新。例如,有一個person對象,需要將其年齡屬性值改為20,可以使用以下代碼實現:
this.person.age = 20;
同樣,這樣修改數據vue.js也無法檢測到數據變化,需要使用$set方法來通知vue.js更新數據。代碼如下:
this.$set(this.person, 'age', 20);
三、$set的高級操作——監聽對象屬性的新增與刪除
除了可以對已有屬性進行修改和更新,$set方法還支持監聽對象屬性的新增和刪除。這一功能對於實現動態表單、涉及到屬性的動態添加和刪除的組件非常有用。
1、新增屬性
如果需要給對象新增一個屬性,並且希望vue.js能夠監測到新增的屬性,可以使用$set方法。例如,有一個person對象,需要新增一個地址屬性,可以使用以下代碼實現:
this.$set(this.person, 'address', '');
這樣新增屬性就可以被vue.js監測到,從而使得視圖更新。
2、刪除屬性
如果需要刪除對象中的某個屬性,同樣可以使用$set方法。例如,有一個person對象,需要刪除其地址屬性,可以使用以下代碼實現:
this.$set(this.person, 'address', undefined);
這樣操作會使得地址屬性變為undefined,但是vue.js依然會監測到屬性的刪除,使得視圖更新。
四、$set的注意事項
$set雖然非常實用,但是在使用過程中也需要注意一些問題,防止出現不必要的錯誤和問題。
1、避免在模板中使用$set
雖然$set方法可以幫助我們實現動態數據的更新,但是在模板中使用$set是非常不推薦的。在模板中可以直接使用data中的數據和方法,可以不必使用$set。如果需要在組件中進行動態數據更新,可以藉助computed、watch和props等特性來實現。
2、避免在computed屬性中使用$set
在computed計算屬性中,如果使用$set方法進行數據更新,會導致無限循環的問題。因為computed屬性的值是基於data中的其他屬性計算的,如果在computed中使用$set方法,則會讓computed屬性的值發生變化,從而引起重新計算,這樣就形成了循環調用。
3、$set無法監控屬性名的變化
$set方法只能監聽對象屬性值的變化,無法監聽屬性名的變化。比如,如果一個對象中的屬性名稱發生了變化,$set方法是無法監測到這一變化,並且也無法觸發組件的更新。所以在修改屬性名時,需要手動刪除原有屬性並在對象中添加一個新的屬性,從而實現屬性名的修改和更新。
五、$set的實例應用
下面是一個$set的實例應用,代碼中實現了一個待辦事項的功能,支持添加任務、修改任務狀態和刪除任務。
1、模板中的代碼
<template>
<div class="task-list">
<h3>待辦事項</h3>
<ul>
<li v-for="(task, index) in tasks" :key="index">
<input type="checkbox" v-model="task.status">
<span :class="{ completed: task.status }" v-text="task.title"></span>
<i class="iconfont icon-delete" @click="deleteTask(index)"></i>
</li>
</ul>
<form @submit.prevent="addTask">
<input type="text" v-model="newTaskContent">
<button type="submit">添加任務</button>
</form>
</div>
</template>
2、script中的代碼
<script>
export default {
data () {
return {
tasks: [
{ title: '吃飯', status: true },
{ title: '睡覺', status: false },
{ title: '打豆豆', status: false }
],
newTaskContent: ''
}
},
methods: {
addTask () {
if (this.newTaskContent.trim() !== '') {
this.tasks.push({
title: this.newTaskContent,
status: false
})
this.newTaskContent = ''
}
},
deleteTask (index) {
this.tasks.splice(index, 1)
}
}
}
</script>
3、style中的代碼
<style scoped>
.task-list {
margin: 20px auto;
padding: 20px;
box-shadow: 0 0 10px rgba(0,0,0,.1);
}
.task-list h3 {
font-size: 24px;
margin-bottom: 20px;
}
.task-list ul {
list-style: none;
padding: 0;
}
.task-list li {
display: flex;
align-items: center;
margin-bottom: 10px;
font-size: 18px;
}
.task-list input[type="checkbox"] {
margin-right: 10px;
}
.task-list span.completed {
text-decoration: line-through;
color: #999;
}
.task-list i {
margin-left: auto;
cursor: pointer;
font-size: 18px;
}
.task-list form {
margin-top: 20px;
}
.task-list input[type="text"] {
padding: 5px 10px;
font-size: 18px;
margin-right: 10px;
border: none;
border-bottom: 1px solid #999;
outline: none;
}
.task-list button {
padding: 5px 10px;
font-size: 18px;
background-color: #00bcd4;
color: #fff;
border: none;
outline: none;
cursor: pointer;
}
</style>
在這個例子中,我使用了$set方法來更新任務的狀態,確保vue.js能夠檢測到數據變化從而更新視圖。
this.$set(this.tasks[index], 'status', !this.tasks[index].status)
原創文章,作者:VBWEM,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/331890.html
微信掃一掃
支付寶掃一掃