1.数据代理

1.1什么是数据代理

通过一个对象代理对另一个对象中属性的操作(读/写)
1.Vue中的数据代理:通过vm对象来代理data对象中属性的操作(读/写)
2.Vue中数据代理的好处:更加方便的操作data中的数据
3.基本原理:通过0bject . defineProperty( )把data对象中所有属性添加到vm上。为每一一个 添加到vm上的属性,都指定个getter/setter。在getter/setter内部去操作(读/写) data中对应的属性。简单来说就是把data的属性全部都复制给了_data了一份,可以让vm进行使用

1.2了解使用数据代理

Object.defineProperty方法(给对象添加属性方法的一个方法)这个方法会传入三个参数分别是 对象名,属性名,配置项
在这里我们可以看到,这个颜色稍微的优点变化(这里就是使用Object.defineProperty方法进行添加的,这里的age是不可以进行枚举的,即不参与遍历)

    <script>    let person = {        name:'大熊'        sex:'男',    }        Object.defineProperty(person,'address',{        value:18    })    console.log(person);    </script>

这里可以使用Object.keys()进行验证一下(并没有age这个属性)(可以看到依然没有age)

当然也可以使用for… in进行遍历一下这个对象

如和才能让他可以被枚举呢?(这里就使用 enumerable 只要将它的值改为true即可)enumerable: true (是否可以被枚举)writable:true(是否可以修改属性)configurable: true(是否可以删除改属性)这四个基本配置项的内容(包括value)他们的默认值为false

    <script>    let person = {        name:'大熊',        sex:'女',    }        Object.defineProperty(person,'address',{        value:18    })    for(k in person){        console.log(k);    }    console.log(Object.keys(person));    console.log(person);    </script>

那问题来了,如何进行对数据的读取和修改呢?这里用到了两个方法,get和set
当有人读取person的age属性时,get函 数(getter)就会被调用,且返回值就是age值
当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具值

    <script>        let number = 19;        let person = {            name: '大熊',            sex: '女',        }        Object.defineProperty(person, 'address', {            get() {                console.log('age属性已被读取');                return number;            },            set(value) {                console.log('age属性已被修改');                number = value            }        })    </script>

2. 事件处理

1.使用v-on:xxx或@xxx绑定事件,其中xxx是事件名
2.事件的回调需要配置在methods对象中,最终会在vm上
3.methods中配置的函数,不可以使用箭头函数,否则this就不是vm了而是window
4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm或组件实例对象5.@click=”demo”和@click=”demo”效果一致,但后者可以传参
注:不要把事件回调方法data里,虽然可以实现相同的功能,但是这样会给增加一个数据代理,给一个方法添加数据代理是没有意义的

<div id="user">        <h1>{{name}}吃饭了吗?</h1>        <button v-on:click="showPage($event,18)">点击提示</button>            </div>    <script>        let vm = new Vue({            el: '#user',            data: {                name: '山鱼',            },            methods: {                // 在这里配置各种事件回调                showPage(event, number) {                    alert('山鱼吃饭了!')                    console.log(number);                }            }        })    </script>

2.1事件修饰符

1.prevent:阻止默认事件(常用)
2.stop: 阻止事件冒泡(常用)
3.once:事件只触发一次(常用)
4.capture: 使用事件的捕获模式
5.self: 只有event.target是当前操作的元素是才触发事件;
6.passive: 事件的默认行为立即执行,无需等待事件回调执行完毕;

<div id="user">        <h1>欢迎来到{{name}}的小屋</h1>                <a href="http://baidu.com" @click.prevent = "showInfo">点我不跳转</a>                <div class="one" @click = 'showInfo'>            <button @click.stop = 'showInfo'>点我</button>        </div>                <button @click.once = 'showInfo'>只能点一次</button>    </div>    <script>    const vm = new Vue({        el:'#user',        data:{            name:'大熊',        },        methods:{            showInfo(e){                alert('同学,慢走!')            }        }    })    </script>

2.2键盘事件

常用的按键别名
回车=> enter,删除=>delete(捕获“删除”和“退格”键),退出=> esc,空格=> space,上=>up,下=> down,左=> left,右=> right

特殊的按键别名
1.换行=> tab (特殊,必须配合keydown使用)
2.系统修饰键 ctrl,alt,shift,meta(meta就是win键也就是windows徽标)
注:
(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown使用:正常触发事件。

<div class="user">        <h1>欢迎加入{{uname}}</h1>                <input type="text" placeholder="按下回车提示输入" @keyup.enter = 'showInfo'>                <input type="text" placeholder="按下del提示输入" @keyup.delete = 'showInfo'>                <input type="text" placeholder="按下ESC提示输入" @keyup.esc = 'showInfo'>                <input type="text" placeholder="一同按下ctrl+‘其他按键’并释放提示输入" @keyup.ctrl = 'showInfo'>                <input type="text" placeholder="按下回车提示输入" @keyup.huiche = 'showInfo'>    </div>    <script>        // 也可以自定义按键别名        Vue.config.keyCodes.huiche = 13;        const vm = new Vue({        el:'.user',        data:{            uname:'山鱼社区'        },        methods:{            showInfo(e){                console.log(e.target.value);            }        }    })    </script>

3.计算属性

1.定义: 要用的属性不存在,要通过已有属性计算得来。
2.原理:底层借助了objcet . defineproperty方法提供的getter和Isetter.
3. get函数什么时候执行” />

4.侦听属性

监视属性watch:
1.当被监视的属性变化时,回调函数自动调用,进行相关操作
2.监视的属性必须存在,I才能进行监视! !
3.监视的两种写法:
(1) . new Vue时传入watch配置
(2) .通过vm. $watch监视

<body>    <div class="user">        <h1>今天我很{{info}}</h1>        <button @click='changeMood'>点击切换心情</button>    </div>    <script>        new Vue({            el: '.user',            data: {                mood: true            },            computed: {                info() {                    return this.mood ? '开心' : '不开心'                },            },            methods: {                changeMood() {                    this.mood = !this.mood                }            },            watch: {                // 被监视的是谁                mood: {                    immediate: true,// 初始化时 让handler调用一次                    // handler有俩参数分别是修改前的值和修改后的值                    handler(newValue, oldValue) {                        console.log('mood被修改了', newValue, oldValue);                    }                },                // 这个监视属性也可以监视计算属性                info: {                    immediate: true,// 初识化时 让handler调用一次                    // handler有俩参数分别是修改前的值和修改后的值                    handler(newValue, oldValue) {                        console.log('info被修改了', newValue, oldValue);                    }                },            }        })        // 也可以用vm.$watch进行监视 =》vm.$watch(监视对象,如何监视)        vm.$watch('mood', {            immediate: true,// 初识化时 让handler调用一次            // handler有俩参数分别是修改前的值和修改后的值            handler(newValue, oldValue) {                console.log('info被修改了', newValue, oldValue);            }        })    </script></body>

4.1深度监视

深度监视
①Vue中的watch默认不监测对象内部值的改变
②配置deep:true可以监测对象内部值改变
备注:
①Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以
②使用watch时根据数据的具体结构,决定是否采用深度监视

4.2监视属性简写

简写(但是不能配置immediate:true,deep:true)

 watch: {                // 完整写法                // mood: {                // deep:true                //     handler(newValue, oldValue) {                //         console.log("mood被修改", newValue, oldValue);                //     }                // }                // 简写                mood(newValue, oldValue) {                    console.log('mood被修改', newValue, oldValue);                }            }        })         // 正常写法        vm.$watch('mood',{                immediate:true,                deep:true,                handler(newValue, oldValue) {                    console.log('mood被修改', newValue, oldValue);                }            })            // 简写            vm.$watch('mood',function(newValue, oldValue){                console.log('mood被修改', newValue, oldValue);            })

4.3computed & watch之间的区别

1.computed能完成的功能,watch 都可以完成。
2.watch能完成的功能,computed不一定能完成,例如: watch可以进行异步操作。
3.两个重要的小原则:
①所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。
②所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等),最好写成箭头函数,这样this的指向才是vm或组件实例对象。

5.写在最后

大家好我是大熊
一个学前端的旅行者也是一个前进的创作者,奋进再这篇土地,希望能和您相遇
✍善于利用零星时间的人,才会做出更大的成绩来。——华罗庚