四时宝库

程序员的知识宝库

VUE教程-(三)Vue核心(vue核心技术)

3.1 事件

3.1.1 事件的基本使用:

  • 使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名
  • 事件的回调需要配置在methods对象中,最终会在vm上
  • methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象(不要用箭头函数!!!)
  • @click='demo' 和 @click='demo($event)' 效果一致,但后者可以传参
<div id="root">
        <h3>欢迎学习{{name}}</h3>
        <button v-on:click="showInfo1">点我提示信息1(不传参)</button>
        <!-- event用来占位,这样丢不了 -->
        <button @click="showInfo2($event,66)">点我提示信息2(传参)</button>

</div>

<script src="./js/vue2.7.14.js"></script>
<script>
        const vm = new Vue({
            el: '#root',
            data: {
                name: 'vue'
            },
            methods: {
                showInfo1(event) {
                    alert('你好')
                    // console.log(event.target.innerText)  //点我提示信息
                    // console.log(this === vm)   //true
                },
                showInfo2(event, number) {
                    console.log(event, number)
                    alert('你好!!')
                    // console.log(event.target.innerText)  //点我提示信息
                    // console.log(this === vm)   //true
                }
            }
        })
</script>

3.1.2 事件修饰符

  • prevent:阻止默认事件(常用)
  • stop:阻止事件冒泡(常用)
  • once:事件只触发一次(常用)
<div id="root">
        <h3>欢迎{{name}}</h3>
        <!-- 阻止默认行为 -->
        <a href="http://www.baidu.com" @click.prevent="showInfo">点我到百度</a>

        <!-- 阻止冒泡 -->
        <div class="demo1" @click="showInfo">
            <button @click.stop="showInfo">点我</button>
        </div>

        <!-- 事件只触发一次(once) -->
        <button @click.once="showInfo">只触发一次</button>
    </div>

    <script src="./js/vue2.7.14.js"></script>
    <script>
        new Vue({
            el: '#root',
            data: {
                name: 'zz'
            },
            methods: {
                showInfo() {
                    //阻止默认行为
                    // e.preventDefault()
                    alert('你好')

                }
            }
        })
    </script>

3.1.3 键盘事件

@keydown,@keyup

Vue中常用的按键别名:

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

例:@keyup.enter="showInfo”
@keyup.caps-lock="showInfo”

<div id="root">
        <h2>欢迎{{name}}</h2>
        <input type="text" placeholder="按下回车提示键入" @keyup.caps-lock="showInfo">
    </div>

    <script>
        // 创建 vm 实例对象
        const vm = new Vue({
            el: '#root',
            data: {
                name: 'zz'
            },
            methods: {
                showInfo(e) {
                    // 按下回车(13)才能控制台输出
                    // if (e.keyCode !== 13) return
                    console.log(e.target.value)
                }
            }
        });
    </script>

3.2 计算属性——computed

--3.2.1插值语法实现{{}}

<div id="root">
        姓: <input type="text" v-model:value="firstName"><br>
        名: <input type="text" v-model:value="lastName"><br>
        姓名:<span>{{firstName}}-{{lastName}}</span>
    </div>

    <script>
        // 创建 vm 实例对象
        const vm = new Vue({
            el: '#root',
            data: {
                firstName: '张',
                lastName: '三'
            }
        });
    </script>

--3.2.2 methods

<div id="root">
        姓: <input type="text" v-model:value="firstName"><br>
        名: <input type="text" v-model:value="lastName"><br>
        姓名:<span>{{fullName()}}</span>
    </div>

    <script>
        // 创建 vm 实例对象
        const vm = new Vue({
            el: '#root',
            data: {
                firstName: '张',
                lastName: '三'
            },
            methods: {
                fullName() {
                    console.log('@---fullName')  //每次输入都更新模板,效率不高
                    return this.firstName + '-' + this.lastName
                }
            }
        });
    </script>

methods 读5次被调用5次

--3.2.3 computed

计算属性:拿着已经写完的属性去加工,生成一个全新的属性

属性=>计算属性

<div id="root">
        姓: <input type="text" v-model:value="firstName"><br>
        名: <input type="text" v-model:value="lastName"><br>
        测试: <input type="text" v-model:value="x"><br>
        姓名:<span>{{fullName}}</span>
    </div>

    <script>
        // 创建 vm 实例对象
        const vm = new Vue({
            el: '#root',
            data: {
                firstName: '张',
                lastName: '三',
                x: 'hello'
            },
            computed: {
                fullName: {
                    //get的作用:当有人读取fullName时,get就会被调用,返回值就作为fullName的值
                    //get什么时候调用:1、初次读取fullName时,2、所依赖的数据发生变化时
                    get() {
                        console.log('get被调用了')
                        return this.firstName + '-' + this.lastName
                    },
                    //set什么时候调用:当fullName被修改时
                    set(value) {
                        console.log('set', value)
                        const arr = value.split('-')
                        this.firstName = arr[0]
                        this.lastName = arr[1]
                    }
                }
            }
        })
    </script>

计算属性读5次,但只调用1次,因为缓存
如果这个fullName只是读取给别人用的,那就可以只写get()。但是以后需要修改,就需要加上set()。

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

(1)计算属性最终会出现在vm上,直接读取使用即可

(2)如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变


只读不改就可以使用简写模式

 // 简写:
                fullName() {
                    console.log('get被调用了')
                    return this.firstName + '-' + this.lastName
                }

3.3 监视属性——watch

--3.3.1 天气案例

<div id="root">
        <h2>今天天气很{{info}},{{x}}</h2>
        <button @click='changeWeather'>切换天气</button>
        <!-- <button @click='isHot = !isHot'>切换天气</button> -->
</div>

    <script>
        // 创建 vm 实例对象
        const vm = new Vue({
            el: '#root',
            data: {
                isHot: true,
                x: 1
            },
            computed: {
                info() {
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            methods: {
                changeWeather() {
                    this.isHot = !this.isHot
                    x++
                }
            }
        });
    </script>

--3.3.2 天气案例-监视属性

  • 当被监视的属性变化时, 回调函数自动调用, 进行相关操作
  • 监视的属性必须存在,才能进行监视!!‘info’
  • 监视的两种写法:
    • (1) new Vue时传入watch配置
    • (2) 通过vm.$watch监视
<div id="root">
        <h2>今天天气很{{info}}</h2>
        <button @click='changeWeather'>切换天气</button>
    </div>

    <script>
        // 创建 vm 实例对象
        const vm = new Vue({
            el: '#root',
            data: {
                isHot: true
            },
            computed: {
                info() {
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            methods: {
                changeWeather() {
                    this.isHot = !this.isHot
                }
            },
            // watch: {
            //     isHot: {
            //         immediate: true,  //初始化时让handler调用一下
            //         // handler什么时候被调用:当isHot发生改变时。
            //         handler(newValue, oldValue) {
            //             console.log('isHot被修改了', newValue, oldValue)
            //         }
            //     }
            // }
        });

        vm.$watch('isHot', {
            immediate: true,  //初始化时让handler调用一下
            handler(newValue, oldValue) {
                console.log('isHot被修改了', newValue, oldValue)
            }
        })
    </script>

--3.3.3 深度监视

  • Vue中的watch默认不监测对象内部值的改变(一层)
  • 配置deep:true可以监测对象内部值改变(多层)

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

<div id="root">
        <h2>今天天气很{{info}}</h2>
        <button @click='changeWeather'>切换天气</button>
        <hr>
        <h3>a的值是:{{numbers.a}}</h3>
        <button @click="numbers.a++">点我让a+1</button>
        <h3>b的值是:{{numbers.b}}</h3>
        <button @click="numbers.b++">点我让b+1</button>
        <button @click="numbers={a:123,b:456}">彻底替换掉numbers</button>
        {{numbers.c.d.e}}

    </div>

    <script>
        // 创建 vm 实例对象
        const vm = new Vue({
            el: '#root',
            data: {
                isHot: true,
                // key:value
                numbers: {
                    a: 1,
                    b: 1,
                    c: {
                        d: {
                            e: 300
                        }
                    }
                }
            },
            computed: {
                info() {
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            methods: {
                changeWeather() {
                    this.isHot = !this.isHot
                }
            },
            watch: {
                isHot: {
                    // immediate: true,  //初始化时让handler调用一下
                    // handler什么时候被调用:当isHot发生改变时。
                    handler(newValue, oldValue) {
                        console.log('isHot被修改了', newValue, oldValue)
                    }
                },
                // 监视多级结构中某个属性的变化
                // 
                // 'numbers.a': {
                //     handler() {
                //         console.log('a被改变了')
                //     }
                // }

                // 监视多级结构中所有属性的变化
                numbers: {
                    deep: true,
                    handler() {
                        console.log('numbers被改变了')
                    }
                }
            }
        });
    </script>

--3.3.4 监视简写

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

    <script>
        // 创建 vm 实例对象
        const vm = new Vue({
            el: '#root',
            data: {
                isHot: true
            },
            computed: {
                info() {
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            methods: {
                changeWeather() {
                    this.isHot = !this.isHot
                }
            },
            watch: {
                // 正常写法
                // isHot: {
                //     // immediate: true,  //初始化时让handler调用一下
                //     // deep:true,   //深度监视
                //     // handler什么时候被调用:当isHot发生改变时。
                //     handler(newValue, oldValue) {
                //         console.log('isHot被修改了', newValue, oldValue)
                //     }
                // }
                // 简写
                isHot(newValue, oldValue) {
                    console.log('isHot被修改了', newValue, oldValue)
                }
            }

        });
    </script>

3.4computed和watch之间的区别:

  • computed能完成的功能,watch都可以完成
  • watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作

两个重要的小原则:
1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象
2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,这样this的指向才是vm 或 组件实例对象

<div id="root">
        姓: <input type="text" v-model:value="firstName"><br>
        名: <input type="text" v-model:value="lastName"><br>
        姓名:<span>{{fullName}}</span>
    </div>

    <script>
        // 创建 vm 实例对象
        const vm = new Vue({
            el: '#root',
            data: {
                firstName: '张',
                lastName: '三',
                fullName: '张-三'
            },
            watch: {
                // watch 监视器里可以写 异步函数
                firstName(val) {
                    setTimeout(() => {
                        console.log(this)
                        this.fullName = val + '-' + this.lastName
                    }, 1000)

                },
                lastName(val) {
                    this.fullName = this.firstName + '-' + val
                }
            }
        })
    </script>

3.5 class与style绑定

--3.5.1 绑定class样式

正常的样式正常写,变化的样式v-bind绑定写

写法::class=“xxx” xxx可以是字符串、对象、数。

所以分为三种写法,字符串写法,数组写法,对象写法

<style>
        .basic {
            width: 200px;
            height: 100px;
            border: 1px black solid;
        }

        .happy {
            background-image: linear-gradient(to right, red, yellow);
        }

        .sad {
            background-color: gray;
        }

        .normal {
            background-color: skyblue;
        }

        .zz1 {
            background-color: lightcoral;
        }

        .zz2 {
            font-size: 22px;
            text-shadow: 2px 5px rgb(227, 76, 101);
        }

        .zz3 {
            border-radius: 25px;
        }
</style>
<div id="root">
        <!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 -->
        <div class="basic" :class="mood" @click="changeMood">{{name}}</div>
        <br><br><br>

        <!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 -->
        <div class="basic" :class="classArr">{{name}}</div>
        <br><br><br>

        <!-- 绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用 -->
        <div class="basic" :class="classObj">{{name}}</div>
</div>

<script src="js/vue2.7.14.js"></script>

<script>
        const vm = new Vue({
            el: '#root',
            data: {
                name: 'zz',
                mood: 'normal',
                classArr: ['zz1', 'zz2', 'zz3'],
                classObj: {
                    zz1: false,
                    zz2: false
                }

            },
            methods: {
                changeMood() {
                    // this.mood = 'happy'
                    const arr = ['happy', 'sad', 'normal']
                    const index = Math.floor(Math.random() * 3)
                    this.mood = arr[index]
                }
            }
        })
</script>

--3.5.2 绑定style样式

<div class="basic" :style="styleObj">{{name}}</div>
<div class="basic" :style="[styleObj,styleObj2]">{{name}}</div>

 const vm = new Vue({
            el: '#root',
            data: {
                name: 'zz',
                mood: 'normal',
               
                styleObj: {
                    fontSize: '30px',
                    color: 'red'
                },
                styleObj2: {
                    backgroundColor: 'pink'
                }

            }

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接