• 【Vue基础四】Vue检测数据改变的原理


    一 引出问题

    Vue更新数据时遇到的问题

    1-1 点击更新马冬梅的信息时,页面没有发生变化

    1. 代码如下

    this.persons[0] = { id: '001', name: '马老师', age: 50, sex: '男' }

    
    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
        <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
    head>
    
    <body>
        <div id="root">
            <h2>人员列表h2>
            <input type="text" placeholder="请输入名字" v-model="keyWord">
            <button @click="updatem">更新马冬梅的信息button>
            <ul>
                <li v-for="(p,index) of persons" :key="index">
                    {{p.name}}-{{p.age}}-{{p.sex}}
                li>
            ul>
        div>
    
        <script>
            // 用computed实现
            new Vue({
                el: "#root",
                data: {
                    keyWord: '',
                    sortType: 0, // 原顺序  1降序  2升序
                    persons: [{
                        id: '001',
                        name: '马冬梅',
                        age: 19,
                        sex: '女'
                    }, {
                        id: '002',
                        name: '周冬雨',
                        age: 20,
                        sex: '女'
                    }, {
                        id: '003',
                        name: '周杰伦',
                        age: 0,
                        sex: '男'
                    }, {
                        id: '004',
                        name: '温兆伦',
                        age: 22,
                        sex: '男'
                    }],
                },
    
                methods: {
                    updatem() {
                        // this.persons[0].name = '马老师'   //奏效
                        // 开发者工具没变,控制台变了
                        this.persons[0] = {
                            id: '001',
                            name: '马老师',
                            age: 50,
                            sex: '男'
                        }
                    }
                }
            })
        script>
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    1. 页面展示如下

    开发者工具没变,控制台变了
    在这里插入图片描述

    1-2 在开发者工具中更改数据时:

    image-20220724171724182

    二、

    2-1

    image-20220731173902749

    1. Vue.set(target,key,val)

      • 往target身上追加属性和属性值
      DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
        <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js">script>
    head>
    
    <body>
        <div id="root">
            <h1>学校信息h1>
            <h2>学校名称:{{name}}h2>
            <h2>学校地址:{{address}}h2>
            <h1>学生信息h1>
            <button @click="addSex">添加一个性别属性,默认值是男button>
            <h2>姓名: {{student.name}}h2>
            <h2 v-if="student.sex">性别: {{student.sex}}h2>
            <h2>年龄: {{student.age.rAge}}h2>
            <h2>朋友们h2>
            <ul>
                <li v-for="(f,index) in student.friends" :key="index">
                    {{f.name}}--{{f.age}}
                li>
            ul>
        div>
    
    body>
    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                name: '尚硅谷',
                address: '北京',
                student: {
                    name: 'tom',
    
                    age: {
                        rAge: 40,
                        sAge: 20
                    },
                    friends: [{
                        name: 'jquery',
                        age: 35
                    }]
                }
            },
            methods: {
                addSex() {
                    // methods的方法正常些,this一定指向vm
                    Vue.set(this.student, 'sex', '男')
                    this.$set(this.student, 'sex', '男')
                }
            }
        })
    script>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    1. 想往如上实例身上添加sex

      • vm.$set(vm.student,'sex','女')
    2. // methods的方法正常些,this一定指向vm
                      Vue.set(this.student, 'sex', '男')
                      this.$set(this.student, 'sex', '男')
      
      • 1
      • 2
      • 3
    3. set不能给vm._data或者vm添加属性

    2-2 Vue检测数据的原理

    1. 更改 原 数组:

      • push
        • 包装数组身上的
        • 重新解析
      • pop
      • shift
      • unshift
      • splice
      • sort
      • reverse
    2. 包装,不是Array原型对象上的方法

      • arr.push = Array.prototype.push true

      • vm._data.student.push === Array.prototype.push false

    3. 常用修改数组的方法

      • Vue将被侦听的数组的变更方法进行包裹,它们也将会触发试图更新

      • Vue.set(vm._data.student.hobby, 1, '打台球')

    2-3 总结vue监视数据

    1. Vue监视数据的原理

      • vue会监视data中所有层次的数据。
    2. 如何监测对象中的数据?

      • 通过setter实现监视,且要在new Vue时就传入要监测的数据

      • 对象中后追加的属性,Vue默认不做响应式处理

      • 如需给后添加的属性做响应式,请使用如下API:

        ```js
        Vue.set(target,propertyName/index,value) vm.$set(target,propertyName/index,value)
        ```
        
        • 1
        • 2
        • 3
    3. 如何监测数组中的数据?

      • 通过包裹数组更新元素的方法实现,本质就是做了两件事:
        • 调用原生对应的方法对数组进行更新。
        • 重新解析模板,进而更新页面。
    4. 在Vue修改数组中的某个元素一定要用如下方法:

      • 使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
      • Vue.set() 或 vm.$set()

    特别注意:Vue.set() 和 vm.$set() 不能给vm 或 vm的根数据对象 添加属性!!!

    三、模拟数据监听

    let data = {
    	nam:'aaa',
    	address: '北京'
    }
    
    // 创建一个监听的实例对象,用于监听data中属性的变化
    const obs = new Observer(data)
    console.log(obs)
    
    function Observer(obj) {
    	// 汇总对象中所有的属性形成一个数组
    	const keys = Object.keys(obj)
    	// 遍历
    	keys.forEach((k) => {
    		Object.definePoperty(this, k, {
    			get() {
    				return obj[k]
    			},
    			set(val) {
    				console.log(`${k}被变了,我要去解析模板,生成虚拟DOM。。。我要开始忙了`)
    				obj[k] = val
    			}
    		})
    	})
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
  • 相关阅读:
    线程同步之信号量
    【微服务技术02】认识微服务--架构演变/技术对比/SpringCloud
    Java项目:SSM图书在线销售商城网站
    2024年,计算机相关专业还值得选择吗?
    【微服务~Nacos】Nacos之配置中心
    (附源码)php校园寝室分配查询系统 毕业设计 032027
    2022世界人工智能大会 “智慧金融与数字员工”分论坛在沪成功举办
    深入理解RNN
    v-on的修饰符
    笔记01:第一行Python
  • 原文地址:https://blog.csdn.net/hannah2233/article/details/126885350