1. 程式人生 > 其它 >Vue 監視資料的原理

Vue 監視資料的原理

一、Vue 會監視 data 中的所有層次的資料,

並且如果他檢測到是物件那麼就會給物件裡面所有的屬性配置 gettersetter


二、如何監測物件中的資料

  1. 通過 setter 實現監視,且要在 new Vue 時就傳入要監測的資料
  2. 物件中後追加的屬性,Vue 預設不做響應式處理(因為沒有配置 getter 和 setter)
  3. 如需給後新增的屬性做響應式,請使用如下 API:
 Vue.set(target,propertyName/index,value)

 vm.$set(target,propertyName/index,value)

特別注意Vue.set()vm.$set()

都不能給 vm(data) 或 vm的根資料物件(_data)新增屬性


給後新增的屬性做響應式 例項

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>給後新增的屬性做響應式</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>

<div id="root">
    <h3>操作</h3>
    <button @click="addSex">新增 性別:男</button>
    <hr>
    <h3>學生資訊</h3>
    <h3>姓名:{{student.name}}</h3>
    <h3>年齡:{{student.age}}</h3>
    <h3 v-if="student.sex">性別:{{student.sex}}</h3>
</div>


</body>

<script type="text/javascript">
    const vm = new Vue({
        el: '#root',
        data: {
            student: {
                name: '王大錘',
                age: 18,
            }
        },
        methods: {
            addSex() {
                // Vue.set(this.student, 'sex', '男')
                this.$set(this.student, 'sex', '男')
            }
        }
    })
</script>

</html>


三、如何監測陣列中的資料

通過包裹陣列更新元素的方法實現,本質就是做了兩件事

  1. 呼叫原生對應的方法對陣列進行更新
  2. 重新解析模板,進而更新頁面

在 Vue 中修改陣列中的某個元素一定要用如下方法

使用這些 API:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()
  • Vue.set()
  • vm.$set()

總結 例項

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>總結_Vue資料監測</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>

<div id="root">
    <h3>操作</h3>
    <button @click="student.age++">年齡 + 1</button>
    <button @click="addSex">新增 性別:男</button>
    <button v-if="student.sex" @click="student.sex = '保密'">修改 性別:保密</button>
    <button @click="addFriend">在列表首位新增一個朋友</button>
    <button @click="updateFriendOneFriendName">修改第一個朋友的姓名:李小梅</button>
    <button @click="addHobby">新增愛好:學習</button>
    <button @click="updateOneHobby">修改第一個愛好:喝水</button>
    <button @click="removeSmoke">過濾愛好:抽菸</button>
    <hr>
    <h3>學生資訊</h3>
    <h3>姓名:{{student.name}}</h3>
    <h3>年齡:{{student.age}}</h3>
    <h3 v-if="student.sex">性別:{{student.sex}}</h3>
    <h3>愛好:</h3>
    <ul>
        <li v-for="(h,index) in student.hobby">{{h}}</li>
    </ul>
    <h3>朋友:</h3>
    <ul>
        <li v-for="(f,index) in student.friends">{{f.name}} - {{f.age}}</li>
    </ul>
</div>


</body>

<script type="text/javascript">
    const vm = new Vue({
        el: '#root',
        data: {
            student: {
                name: '王大錘',
                age: 18,
                hobby: ['吃飯', '睡覺', '抽菸'],
                friends: [
                    {id: '002', name: '王小李', sex: '男', age: 19},
                    {id: '003', name: '李大剛', sex: '男', age: 21}
                ]
            }
        },
        methods: {
            addSex() {
                // Vue.set(this.student, 'sex', '男')
                this.$set(this.student, 'sex', '男')
            },
            addFriend() {
                this.student.friends.unshift({name: '王曉梅', age: 18})
            },
            updateFriendOneFriendName() {
                this.student.friends[0].name = '李小梅'
            },
            addHobby() {
                this.student.hobby.push('學習')
            },
            updateOneHobby() {
                // this.student.hobby.splice(0,1,'喝水')
                // Vue.set(this.student.hobby, 0, '喝水')
                this.$set(this.student.hobby, 0, '喝水')
            },
            removeSmoke() {
                this.student.hobby = this.student.hobby.filter((h) => {
                    return h !== '抽菸'
                })
            }
        }
    })
</script>

</html>