一、$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