VUE2学习(事件处理,计算属性,监视属性)- day02

1-事件

 1-1  事件处理的基本使用

1 、使用v-on:xxx或@xxx绑定事件,其中xxx是事件名
2、事件的回调需要配置在methods对象中,最终会在vm上;
3、methods中配置的函数不要用箭头函数,否则this指向就不是vm了
4、 methods中配置的函数,都被Vue所管理的函数,this的指向是vm 或组件实例对象
5、 @click="demo"和@click="demo($event)"效果一样,但后者可以传参
 

<!DOCTYPE html>
<html>

<head>
    <mate charset="UTF-8"></mate>
    <title> 初识VUE</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <H1>名称 : {{name}}</H1>
        <!-- <button v-on:click="showInfo('淮安', '总理故乡')">点我提示信息</button> -->
        <button @click="showInfo('淮安', '总理故乡', $event)">点我提示信息</button>
    </div>
    <script type="text/javascript">

        const vm = new Vue({
            el: '#root',
            data() {
                return {
                    name: 'VUE学习123',
                    addr: '淮安总理故乡'
                }
            },
            methods: { 
                showInfo(a , b, c) {
                    console.log(c);
                    alert("欢迎来到" + a + b)
                }
            }
        })
    </script>
</body>

</html>
1-2 事件修饰符

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

<!DOCTYPE html>
<html>

<head>
    <mate charset="UTF-8"></mate>
    <title> 初识VUE</title>
    <script type="text/javascript" src="../js/vue.js"></script>

    <style>
        * {
            margin-top: 20px;
        }

        .demo1 {
            height: 100px;
            background-color: skyblue;
        }

        .demo2{
            height: 100px;
            background-color: yellow;
        }

        .div1 {
            background-color: red;
        }

        .div2 {
            background-color: greenyellow;
        }

        .list {
            width: 200px;
            height: 200px;
            background-color: peru;
            overflow: auto;
        }

        li {
            height: 100px;
        }
    </style>
</head>

<body>
    <div id="root">
        <H1>名称 : {{name}}</H1>
        <!-- 阻止默认事件 常用-->
        <a href="http://wwww.baidu.com" @click.prevent="showInfo">点我提示信息</a>

        <!-- 阻止事件冒泡 常用-->
        <div class="demo1" @click="showInfo">
            <button @click.stop="showInfo">点我提示信息</button>
            </br>

            <a href="www.baidu.com" @click.stop.prevent="showInfo">先阻止冒泡,再阻止默认事件(阻止a标签跳转)</a>
        </div>

        <!-- 事件只执行一次  常用-->
        <div class="demo2" @click="showInfo">
            <button @click.once="showInfo">点我提示信息</button>

        </div>

        <!--先执行捕获事件-->
        <div class="div2" @click.capture="showMsg(2)">
            div2
            <div class="div1" @click="showMsg(1)">
                div1
            </div>
        </div>

        <!-- 只有event.target是当前操作的元素时才触发事件 -->
        <div class="div2" @click.self="showMsg(2)">
            div2
            <div class="div1" @click="showMsg(1)">
                div1
            </div>
        </div>

        <!-- 事件的默认行为立即执行,无需等待事件回调执行完毕  
            比如鼠标wheel 滚事件,只有等方法执行完才会触发滚动,passive则可以先滚动再执行事件-->
        <ul @wheel.passive="demo" class="list">
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>

    </div>
    <script type="text/javascript">

        const vm = new Vue({
            el: '#root',
            data() {
                return {
                    name: 'VUE学习123'
                }
            },
            methods: {
                showInfo(e) {
                    //阻止事件冒泡
                    // e.stopPropagation();
                    alert("欢迎来到得来联盟")
                },
                showMsg(val) {
                    console.log(val);
                },
                demo() {
                    for (let i = 0; i < 100000; i++) {
                        console.log('#')
                    }
                    console.log('累坏了')
                }
            },


        })
    </script>
</body>

</html>
1-3 键盘事件
  • keydown:按下按键不用抬起来就触发事件
  • keyup:按下按键抬起来才触发事件(常用)

上面代码中通过Enter键按下后抬起触发事件,enter为vue中Enter的别名

<!DOCTYPE html>
<html>

<head>
    <mate charset="UTF-8"></mate>
    <title> 初识VUE</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <H1>名称 : {{name}}</H1>
        
        <input type="text" placeholder="按下按键提示" @keyup.enter="showInfo"> 
    </div>
    <script type="text/javascript">

        const vm = new Vue({
            el: '#root',
            data() {
                return {
                    name: 'VUE学习123'
                }
            },
            methods: {
                showInfo(e) {
                    console.log("打印按键的值",e.key, e.keyCode);
                    //不如判断不是回车键就不打印输入框的val
                    // if(e.keyCode != 13){
                    //     return;
                    // }
                    console.log("打印输入框的值",e.target.value);
                   
                }
            },
        })
    </script>
</body>

</html>

 常用的按键别名有总结:

1-

回车=>enter
删除=>delete(捕获“删除”和“退格”键)
退出=>esc
空格=>space
换行=>tab(特殊,必须配合keydown使用)
上=>up
下=>down
左=>left
右=>right

2-

Vue未提供别名的按键,可以使用按键原始的key值去绑定,但要注意驼峰命名法的原始key值要转化为短横线命名,例如大小写转换键CapsLock 要写为 caps-lock。

3-

系统修饰键(用法特殊):ctrl、alt、shift、meta(win键),用法如下:

配合keyup使用:按下修饰键的同时再按下其他键,随着释放其他键,事件才被触发

配合kedown使用:正常触发事件

如果只想要修饰键+一个其他键 才能触发事件可以连续写,例如下面这行代码就是只有按下ctrl+y才能触发事件:

@keyup.ctrl.y=“xxx”
 

2- 计算属性与监视

2-1 计算属性

案例:根据用户输入姓和名来生成全名

1-插值语法实现

表达式太蓉冗长,vue并不推荐

<!DOCTYPE html>
<html>

<head>
    <mate charset="UTF-8"></mate>
    <title> 初识VUE</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        
        姓:<input type="text" v-model="firstName"></br>
        名:<input type="text" v-model="secondName"></br>
        全名:(都截取截取前2位)</br>:
        <span>{{firstName.slice(0,2)}}-{{secondName.slice(0,2) }}</span>
    </div>
    <script type="text/javascript">

        const vm = new Vue({
            el: '#root',
            data() {
                return {
                    firstName: '张',
                    secondName: '三',
                }
            },
        
        })
    </script>
</body>

</html>

2-调用函数实现

,每次都会调用方法

<!DOCTYPE html>
<html>

<head>
    <mate charset="UTF-8"></mate>
    <title> 初识VUE</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
    <div id="root">

        姓:<input type="text" v-model="firstName"></br>
        名:<input type="text" v-model="secondName"></br>
        全名:(都截取截取前2位)</br>:
        <span>{{fullName()}}</span>
    </div>
    <script type="text/javascript">

        const vm = new Vue({
            el: '#root',
            data() {
                return {
                    firstName: '张',
                    secondName: '三',
                }
            },
            methods: {
                fullName() {
                    console.log('观察函数调用次数');
                    return this.firstName.slice(0, 2) + '-' + this.secondName.slice(0, 2);
                },
            }
        })
    </script>
</body>

</html>
3-vue提供计算属性 computed 来依赖已定义属性,生成不存在的属性

定义:要用的属性不存在,要通过已有属性计算出来
原理:底层借助了Object.defineproperty方法提供的getterr和setter
get函数什么时候执行?
初次读取时会执行一次
当依赖的数据发生改变时会被再次调用
优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试更方便


备注:
计算属性最终会出现在vm上,直接调用即可
如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生变化
如果计算属性确定不考虑修改,可以使用计算属性的简写形式
 

<!DOCTYPE html>
<html>

<head>
    <mate charset="UTF-8"></mate>
    <title> 初识VUE</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
    <div id="root">

        姓:<input type="text" v-model="firstName"></br>
        名:<input type="text" v-model="secondName"></br>
        姓名:(都截取截取前2位)</br>:
        <span >{{fullName}}</span>

        姓名:(都截取截取前2位)</br>:
        <span >{{fullName}}</span>

        姓名:(都截取截取前2位)</br>:
        <span >{{fullName}}</span>

        姓名:(都截取截取前2位)</br>:
        <span >{{fullName}}</span>

    </div>
    <script type="text/javascript">

        const vm = new Vue({
            el: '#root',
            data() {
                return {
                    firstName: '张',
                    secondName: '三',
                }
            },
            //计算属性
            computed:{
                fullName:{
                   // get被调用的时机
                   //1-初始化时候,
                   //2-所依赖的属性发生变化时候
                   get(){
                    // 当有人读取fullNmae时候,get就会返回fullNmae的值
                        console.log('get被调用了');
                        return this.firstName.slice(0, 2) + '-' + this.secondName.slice(0, 2);
                    },
                    set(val){
                        //当fullName被修改时
                        console.log('set', val);
                        const arr = val.split('-');
                        this.firstName = arr[0];
                        this.secondName = arr[1]
                    }
                }
            }
        })
    </script>
</body>

</html>

以上只考虑读取,不考虑修改 的简写

<!DOCTYPE html>
<html>

<head>
    <mate charset="UTF-8"></mate>
    <title> 初识VUE</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
    <div id="root">

        姓:<input type="text" v-model="firstName"></br>
        名:<input type="text" v-model="secondName"></br>
        姓名:(都截取截取前2位)</br>:
        <span >{{fullName}}</span>

    </div>
    <script type="text/javascript">

        const vm = new Vue({
            el: '#root',
            data() {
                return {
                    firstName: '张',
                    secondName: '三',
                }
            },
            computed:{
                // fullName:{
                //    get(){
                //         console.log('get被调用了');
                //         return this.firstName.slice(0, 2) + '-' + this.secondName.slice(0, 2);
                //     },
                //     set(val){
                //         console.log('set', val);
                //         const arr = val.split('-');
                //         this.firstName = arr[0];
                //         this.secondName = arr[1]
                //     }
                // }

                //简写 只是考虑读取时候
                fullName(){
                    console.log('get被调用了');
                        return this.firstName.slice(0, 2) + '-' + this.secondName.slice(0, 2);
                }
            }
        })
    </script>
</body>

</html>

2-2 监视属性

案列 : 点击切换天气按钮,改变文案如图

先点击按钮调用方法,再用用计算属性返回文案

监视属性watch:
1.当被监视的属性变化时,回调函数自动调用,进行相关操作

2.监视的属性必须存在,才能进行监视!!

3.监视的两种写法:
(1).new Vue时传入watth配置
(2).通过vm.$watch监视

=<!DOCTYPE html>
<html>

<head>
    <mate charset="UTF-8"></mate>
    <title> 初识VUE</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <h2>今天天气很{{info}} </h2>
        <button @click="changeWeather()">切换天气 </button>

    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data() {
                return {
                    isHot: true
                }
            },
            methods: {
                changeWeather() {
                    this.isHot = !this.isHot;
                }
            },
            computed: {
                info() {
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            watch: {
                isHot: {
                    //初始化时候让handler调用
                    immediate: true,
                    //当值发生改变时候 
                    handler(newval, oldval) {
                        console.log('ishot新值', newval);
                        console.log('ishot旧值', oldval);
                    }
                }
            }
        })

        //监视的另外写法
        // vm.$watch('isHot', {
        //     immediate: true,
        //     handler(newval, oldval) {
        //         console.log('ishot新值', newval);
        //         console.log('ishot旧值', oldval);
        //     }
        // })

    </script>
</body>

</html>

 2-3 深度监视

(1).Vue中的watch默认不监测对象内部值的改变(一层)

(2).配置deep:true可以监测对象内部值改变(多层)。

备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视

<!DOCTYPE html>
<html>

<head>
    <mate charset="UTF-8"></mate>
    <title> 初识VUE</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <h2>今天天气很{{info}} </h2>
        <button @click="changeWeather()">切换天气 </button>
        <hr />
        <h3>a的值是:{{numbers.a}}</h3>
        <button @click="numbers.a++">点击a+加 </button>

        <h3>b的值是:{{numbers.b}}</h3>
        <button @click="numbers.b++">点击b+加 </button>

    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data() {
                return {
                    isHot: true,
                    numbers: {
                        a: 1,
                        b: 2
                    }
                }
            },
            methods: {
                changeWeather() {
                    this.isHot = !this.isHot;
                }
            },
            computed: {
                info() {
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            watch: {
                isHot: {
                    immediate: true,
                    handler(newval, oldval) {
                        console.log('ishot新值', newval);
                        console.log('ishot旧值', oldval);
                    }
                },
                //监视某个属性的变化
                'numbers.a': {
                    handler(newval, oldval) {
                        console.log('a新值', newval);
                        console.log('a旧值', oldval);
                    }
                },
                //深度监视 numbers里面所有属性变化
                numbers:{
                    deep: true,
                    handler(newval, oldval) {
                        console.log('numbers', newval);
                        console.log('numbers', oldval);
    
                    }
                }
            }
        })



    </script>
</body>

</html>

以上监视属性也可以简写为以下

<!DOCTYPE html>
<html>

<head>
    <mate charset="UTF-8"></mate>
    <title> 初识VUE</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
    <div id="root">
        <h2>今天天气很{{info}} </h2>
        <button @click="changeWeather()">切换天气 </button>

    </div>
    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data() {
                return {
                    isHot: true,
                }
            },
            methods: {
                changeWeather() {
                    this.isHot = !this.isHot;
                }
            },
            computed: {
                info() {
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            watch: {
                // 完整写法
                // isHot: {
                //      // immediate: true,
                //     // deep:true,
                //     handler(newval, oldval) {
                //         console.log('ishot新值', newval);
                //         console.log('ishot旧值', oldval);
                //     }
                // }

                //简写
                // isHot(newval, oldval) {
                //     console.log('ishot新值', newval);
                //     console.log('ishot旧值', oldval);
                // }
            }
        })

        //完整写法
        // vm.$watch('isHot', {
        //     handler(newval, oldval) {
        //         console.log('ishot新值', newval);
        //         console.log('ishot旧值', oldval);
        //     }
        // })

        // 简写
        vm.$watch('isHot', function(newval, oldval) {
                console.log('ishot新值', newval);
                console.log('ishot旧值', oldval);
            })


    </script>
</body>

</html>

3-计算属性对比监视属性

总结:

computed和watch之间的区别:
computed能完成的功能,watch都可以完成
watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作(如下面例子 异步等待一秒修该姓名)
两个重要的小原则:

所有被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象
所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象。

目标都一个,就是让this指向是vm。

我们按照上面修改姓名为例子对比

<!DOCTYPE html>
<html>

<head>
    <mate charset="UTF-8"></mate>
    <title> 初识VUE</title>
    <script type="text/javascript" src="../js/vue.js"></script>
</head>

<body>
    <div id="root">

        <!-- 姓:<input type="text" v-model="firstName"></br>
        名:<input type="text" v-model="secondName"></br>
       计算属性实现全名:(都截取截取前2位)</br>:
        <span>{{fullName}}</span> -->


        姓:<input type="text" v-model="firstName"></br>
        名:<input type="text" v-model="secondName"></br>
        监视属性实现全名(姓名等一秒改变):</br>:
        <span>{{fullName}}</span>
    </div>
    <script type="text/javascript">

        const vm = new Vue({
            el: '#root',
            data() {
                return {
                    firstName: '张',
                    secondName: '三',
                    fullName: '张-三'
                }
            },
            //计算属性
            computed: {
                // fullName:{
                //    get(){
                //         console.log('get被调用了');
                //         return this.firstName.slice(0, 2) + '-' + this.secondName.slice(0, 2);
                //     },
                //     set(val){
                //         console.log('set', val);
                //         const arr = val.split('-');
                //         this.firstName = arr[0];
                //         this.secondName = arr[1]
                //     }
                // }
            },
            watch: {
                firstName(newValue, oldValue) {
                    // 这边要写成箭头函数, 写成普通函数会指向window
                    setTimeout(() => {
                        this.fullName = newValue + '-' + this.secondName;
                    }, 1000);
                },
                secondName(newValue, oldValue) {
                    this.fullName = this.firstName + '-' + newValue;
                }
            }
        })
    </script>
</body>

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

syfjava

请博主喝杯蜜雪冰城

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值