2024字节青训营笔记(五) Vue核心知识(1)

83 阅读3分钟
<!-- 准备好容器 -->
    <div id="root">
        <h1>hello!{{name}}</h1>
    </div>
    <script>
        //创建vue实例
        const x = new Vue({
            el: '#root',  //指定为哪个容器服务,一般用id
            data: { //先写成一个对象
                name: 'lyt222'
            }
        })
    </script>

先有容器,再有Vue实例

容器和实例只能1-1对应

可以在vue中直接更改值

模板语法

插值语法 解析标签体内容 {{xxx}}

指令语法 用于解析标签 v-bind 这种

v-bind: 简写成 :

数据绑定

单项数据绑定 数据只能从data流向页面 (v-bind)

双向数据绑定 data流向页面,页面流向data (v-model)

v-model 只能用在表单类,输入类元素(都有value值)

<div id="root">
        单向数据绑定<input type="text" v-bind:value="name"><br>
        双向数据绑定<input type="text" v-model:value="name">
    </div>
    <script>
        new Vue({
            el: '#root',
            data: {
                name: '卢玉婷'
            }
        })
    </script>

el有两种写法

data也有两种写法,对象式,函数式

<script>
        const v = new Vue({
            el: '#root',  //el第一种写法
            data: {           //data第一种
                name: 'lyt'

            }
        })

        const v2 = new Vue({
            data() {   //第二种写法
                return {
                    name1: 'lyt'
                }
            }
        })
        v2.$mount('#root2')  //第二种写法
    </script>

MVVM模型

Vue实例用vm表示

data中所有属性,最后都出现在vm身上

vm身上所有属性,在Vue模板中都可以直接使用

数据代理

dafineproperty 方法

let person = {
            name: "张三",
            sex: '男'
        }

        Object.defineProperty(person, 'age', {
            value: 18,
            enumerable: true,
            writable: true,
            configurable: true
        })

get方法 有人读取时调用

let person = {
            name: "张三",
            sex: '男'
        }
        Object.defineProperty(person, 'age', {
            get: function () {
                return 'hello'
            }
        })
        console.log(person)

set方法 有人修改age时

<script>
        let num = 18
        let person = {
            name: "张三",
            sex: '男'
        }
        Object.defineProperty(person, 'age', {
            get: function () {
                return num
            },

            set(value) {
                num = value
            }
        })
        console.log(person)
    </script>

数据代理:通过一个对象代理,对另一个对象中的属性进行操作

<script>
        let obj = {
            x: 1000
        }
        let obj2 = {
            y: 2000
        }
        Object.defineProperty(obj2, 'x', {
            get: function () {
                return obj.x
            },
            set(value) {
                obj.x = value
            }
        })
    </script>

基本原理:通过defineproperty()把data对象中所有属性添加到vm上

为每个添加到vm上的属性,都指定一个getter和setter

在getter setter内部操作,读写对应数据

等于是vue帮我们绑好了

事件处理

v-on:click 简写@click

事件写在methods里面

<div id="root">
        <h1>欢迎你,{{name}}</h1>
        <button v-on:click="showInfo">点我提示信息(不传参)</button>
        <button @click="showInfo2(66,$event)">点我提示信息(传参)</button>
    </div>
    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                name: 'lyt'
            },
            methods: {
                showInfo(event) {
                    alert('同学你好')
                },
                showInfo2(event) {
                    alert('同学你好!!')
                }
            }
        })
    </script>

事件修饰符

prevent阻止默认事件

stop阻止事件冒泡

once只触发一次

capture 事件捕获

self 阻止冒泡

passive 事件的默认行为立即执行,无需等待事件回调执行完毕

wheel(滚动条不会动)和scroll (会动)

<div id="root">
        <ul @wheel.passive="demo" class="list">
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
    </div>

    <script>
        const vm = new Vue({
            el: '#root',

            methods: {
                demo() {
                    for (let i = 0; i < 100000; i++) {
                        console.log('#');
                    }
                    console.log('累坏了');
                }
            }
        })
    </script>

加了passive就不用等待demo函数执行了

键盘事件

<div id="root">
        <input type="text" placeholder="请输入" @keyup.enter="showInfo">
    </div>
    <script>

        const vm = new Vue({
            el: '#root',
            methods: {
                showInfo(e) {
                    console.log(e.target.value)
                }
            }
        })
    </script>

只有按下回车键才会输出

常用别名

enter回车键

delete

esc 退出

tab 换行 (必须用keydown)

space 空格

ctrl,alt,shift,meta (keyup:系统修饰键,要配合别的键使用, keydown:直接使用)

计算属性

就是用原有的属性加工,生成新的属性

姓名案例:

<div id="root">
        姓:<input type="text" v-model="firstName"><br>
        名:<input type="text" v-model="lastName"><br>
        全名:<span>{{fullname()}}</span>
    </div>
    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                firstName: '张',
                lastName: '三'
            },
            methods: {
                fullname() {
                    return this.firstName + '-' + this.lastName
                }
            }
        })

    </script>

用新的配置项

computed

get什么时候会被调用?

1.初次读取时

2.依赖的数据发生改变时

set什么时候调用?fullName被修改

<div id="root">
        姓:<input type="text" v-model="firstName"><br>
        名:<input type="text" v-model="lastName"><br>
        全名:<span>{{fullName}}</span>
    </div>
    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                firstName: '张',
                lastName: '三'
            },
            computed: {
                fullName: {
                    get() {
                        console.log('get被调用了');

                        return this.firstName + '-' + this.lastName
                    },
                    set(value) {
                        console.log('set被调用')
                        const arr = value.split('-')
                        this.firstName = arr[0]
                        this.lastName = arr[1]
                    }
                }
            }
        })
    </script>

简写:记得fullName是计算属性!

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

监视属性

天气案例:

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

    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                isHot: true
            },
            computed: {
                info() {
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            methods: {
                changeWeather() {
                    this.isHot = !this.isHot
                }
            }
        })
    </script>

把方法写得更简单:写在@click后面,前提是语句很简单

<div id="root">
        <h1>今天天气很{{info}}</h1>
        <button @click="isHot = !isHot">切换天气</button>
    </div>
    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                isHot: true
            },
            computed: {
                info() {
                    return this.isHot ? '炎热' : '凉爽'
                }
            }
        })
    </script>

检测isHot属性,用watch:

watch: {
                isHot: {
                    immediate: true,  //初始化时让handler执行一下
                    handler(newValue, oldValue) {
                        console.log('isHot被修改', newValue, oldValue);
                    }

                }
            }

深度监视 (有多级结构)

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

watch: {
                //监视多级结构某个属性变化
                // 'numbers.a': {
                //     handler() {
                //         console.log('a变化了')
                //     }
                // }
                //监视多级结构中所有属性的变化
                numbers: {
                    deep: true,
                    handler() {
                        console.log('numbers的值改变了');

                    }
                }
            }

简写:

不能配置immediate,deep

<div id="root">
        <h1>今天天气很{{info}}</h1>
        <button @click="isHot = !isHot">切换天气</button>
        <hr>

    </div>
    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                isHot: true,
                numbers: {
                    a: 1,
                    b: 1
                }
            },
            computed: {
                info() {
                    return this.isHot ? '炎热' : '凉爽'
                }
            },
            watch: {
                // isHot: {
                //     immediate:true,
                //     handler(newValue, oldValue) {
                //         console.log('isHot被修改', newValue, oldValue);
                //     }

                // }
                isHot() {
                    console.log('isHot被修改了');

                } 
            }
        })
    </script>

watch属性实现姓名案例:

<div id="root">
        姓:<input type="text" v-model="firstName"><br>
        名:<input type="text" v-model="lastName"><br>
        全名:<span>{{fullName}}</span>
    </div>
    <script>
        const vm = new Vue({
            el: '#root',
            data: {
                firstName: '张',
                lastName: '三',
                fullName: '张-三'
            },
            watch: {
                firstName(newValue) {
                    this.fullName = newValue + '-' + this.lastName
                },
                lastName(newValue) {
                    this.fullName = this.firstName + '-' + newValue
                }
            }
        })
    </script>

计算属性不能插入定时器,即异步任务,因为它有return;computed能完成的,wacth都可以完成,但是computed不能实现异步任务

定时器要写成箭头函数,写成普通函数this就变成windows了;

Vue所管理的函数,最好写成普通函数,不是Vue所管理的函数,写成箭头函数(定时器的回调函数,ajax回调函数,promise回调函数)这样this才能指向vm