[TOC]

01丶初始vue

  1. 简述:Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。
  2. Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
  3. vue官网:https://cn.vuejs.org
  4. 编辑器:webstorm,Jetbrains全家桶之一,值得信赖 ```vue <!DOCTYPE html>
{{name}}—-{{age}}
<a name="tCMnZ"></a> # 02丶模板语法 vue 模板语法有 2 大类<br />1、插值语法<br />功能:用于解析标签体的内容<br />写法:{{ xxx }} xxx是js表达式,可以直接读取到data中所有属性<br />2、指令语法<br />功能:解析标签(包括:标签属性,标题内容,绑定事件等等)<br />举例:v-bind:href = "xxx" 或者简写为 :href = "xxx" ,xxx同样是js表达式,可以直接读取data中的属性 备注:vue中有很多指令,形式:v-xxxvue


<a name="lDq8K"></a>
# 03丶数据绑定
vue 中有 2 种数据绑定的方式:<br />    1、单向数据绑定:v-bind,数据只能从data流向页面<br />    2、双向数据绑定:v-model,数据不仅能从 data 流向页面,也能从页面向 data 传输

    备注:<br />        1、双向绑定一般应用于表单类元素上面,如(input,select等)<br />        2、v-model:value 可以简写为 v-model,因为 v-model 默认收集的就是 value 值

```vue
<!-- 容器,绑定vue -->
<div id="app">
    <p>
        <label> 单向数据绑定:
            <input type="text" v-bind:value="name">
        </label>
    </p>
    <!--
       v-model 用于双向数据绑定,但是v-model只能用于表单类元素(输入类元素)上
     -->
    <p>
        <label> 双向数据绑定:
            <input type="text" v-model:value="school.name">
        </label>
    </p>
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    new Vue({
        el: "#app",
        data: {
            name: "lz",
            age: 18,
            school: {
                name: 'gdut'
            }
        }
    })
</script>

04丶el和data的两种写法

el:
1、在 new Vue 时直接配置el属性
2、先创建Vue实例对象,随后通过 vm.$mount(‘#root’) 来指定 el 值

data:
1、对象式
data:{}

2、函数式<br />        data(){<br />            return {<br />            }<br />        }
<!-- 容器,绑定vue -->
<div id="app">
    {{name}}
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const x = new Vue({
        // el: "#app",  第一种写法
        // data: {  // (对象式)
        //     name: "lz"
        // }

        // data 的第二种写法,定义为一个函数,返回一个对象(函数式)
        data() {
            return {
                name: 'lz'
            }
        }
    })
    x.$mount('#app')  // 第二种写法
</script>

05丶MVVM模型

M:模型(model):对应data的数据
V:视图(view):模板
VM:视图模型(View Model):vue实例对象

<!-- 容器,绑定vue -->
<div id="app">
    {{name}}
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            name: "lz"
        }
    })

    console.log(vm)
</script>

06丶数据代理

6.1 Object.defineProperty

<script>
    Vue.config.productionTip = false

    let person = {
        'name': 'lz',
        'age': 18
    }

    let num = 10;

    Object.defineProperty(person, 'addr', {
        //value: 'gz',
        // enumerable: false, // 是否可以被枚举,默认值:false
        // writable: true, // 控制属性是否可以被修改,默认值:false
        // configurable: true, // 控制属性是否可以被删除,默认值:false

        // 当有人读取person的addr属性时,get函数就会被调用,且返回值就是addr的值
        get() {
            console.log('start to read number.')
            return num
        },

        // 当有人修改person的addr属性时,set函数就会被调用
        set(value) {
            console.log('start to set number.')
            num = value
        }
    })

    for (x in person) {
        console.log('# ', x)
    }


    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            name: "lz"
        }
    })
</script>

6.2 数据代理

数据代理:通过一个对象代理,对另一个对象中的属性的操作(读写)

6.3 vue中的数据代理

vue实例中的配置对象 data 实际就是 vm._data
1、vue的数据代理
通过 vm 对象来代理 data 对象中的属性操作(读写)
2、vue中数据代理的好处
更加方便的操作 data 中的数据
3、基本原理
通过 Object.defineProperty() 这个方法把 data对象中所有属性添加到 vm 上
为每一个添加到 vm 上的属性,都指定一个 getter/setter
在 getter/setter 内部去操作(读写) data 中对应的属性

07丶事件处理

7.1 基本使用

v-on:click=’fun’ 传入的是函数名,当需要传入参数的时候,需要使用小括号,
可以使用 $event 传入事件对象

<!-- 容器,绑定vue -->
<div id="app">

    <button v-on:click="show">点我</button>
    <button @click="show1(44,$event)">点我1</button>

</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            name: "lz"
        },
        methods: {
            show(event) {
                // 事件对象获取到这个元素对象
                console.log(event.target, event.target.innerHTML)
            },
            show1(num, event) {
                console.log(num, event)
            }
        }
    })
</script>

7.2 事件修饰符

vue的事件修饰符
1、prevent:阻止默认事件修饰符(常用)
2、stop:阻止事件冒泡(常用)
3、once:事件只被调用一次(常用)

4、capture:使用事件的捕捉模式
5、self:只有 event.target 是当前操作元素才触发事件
6、passive:事件的默认行为立即执行,无需等待事件回调执行完毕

<!-- 容器,绑定vue -->
<div id="app">
    <!-- 有多个事件修饰符,修饰符可以连着写 -->
    <a href="https://www.baidu.com" @click.stop.prevent="click">click</a>
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            name: "lz"
        },
        methods: {
            click(event) {
                alert('click me.')
            }
        }
    })
</script>

7.3 键盘事件

1、vue中常用的按键别名
1、回车 ==> enter
2、删除 ==> delete
3、推出 ==> esc
4、空格 ==> space
5、换行 ==> tab (特殊,必须配合着 keydown 去使用)
6、上 ==> up
7、下 ==> down
8、左 ==> left
9、右 ==> right

2、vue未提供别名的按键,可以使用按键原始的key值去绑定,但是需要注意转为 key-case(短横线命名)

3、系统修改键(用法特殊) CTRL、ALT、SHIFT、META
配合 keyup 使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发
配合 keydown 使用:正常触发事件

4、也可以使用 keycode 去指定具体的按键(不推荐)

5、Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名

<!-- 容器,绑定vue -->
<div id="app">
    <label>
        <input type="text" placeholder="请输入" @keydown.enter="click">
    </label>
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            name: "lz"
        },
        methods: {
            click(e) {
                console.log(e.target.value)
                console.log(e.key, e.keyCode)
            }
        }
    })
</script>

08丶计算属性

8.1 插值语法实现

<!-- 容器,绑定vue -->
<div id="app">
    <label>
        <input type="text" v-model:value="lastName">
    </label> <br><br>
    <label>
        <input type="text" v-model:value="firstName">
    </label> <br><br>

      <!-- 这里对两个属性进行截取拼接 -->
    姓名:{{lastName.slice(0, 3).concat(firstName)}}
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            firstName: '三',
            lastName: '张'
        }
    })
</script>

8.2 函数实现

<!-- 容器,绑定vue -->
<div id="app">
    <label>
        <input type="text" v-model:value="lastName">
    </label> <br><br>
    <label>
        <input type="text" v-model:value="firstName">
    </label> <br><br>

    姓名:{{fullName()}}
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            firstName: '三',
            lastName: '张'
        },
        methods: {
            fullName() {
                return this.lastName + this.firstName
            }
        }
    })
</script>

8.3 计算属性实现

<!-- 容器,绑定vue -->
<div id="app">
    <label>
        <input type="text" v-model:value="lastName">
    </label> <br><br>
    <label>
        <input type="text" v-model:value="firstName">
    </label> <br><br>

    姓名:
    <label>
        <input type="text" v-model:value="fullName">
    </label> <br><br>
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            firstName: '三',
            lastName: '张'
        },
        computed: {
            fullName: {
                /**
                 * get方法什么时候会被调用
                 * 1、当初次读取fullName的时候,
                 * 2、所依赖的数据发生变化的时候
                 */
                get() {
                    return this.lastName + this.firstName
                },
                /**
                 * set方法什么时候被调用
                 * 1、当fullName被修改时
                 */
                set(value) {
                    console.log('fullName try to change to ', value)
                }
            }
        },
        methods: {}
    })
</script>

09丶监视属性

<!-- 容器,绑定vue -->
<div id="app">
    <label>
        <input type="text" v-model:value="name">
    </label>
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            name: "lz"
        },
        watch: {
            name: {
                handler(newValue, oldValue) {
                    console.log(oldValue, ' ---> ', newValue)
                },
            }
        }
    })
</script>

9.1 深度监视

computed和watch之间的区别
1、computed能完成的功能,watch都能完成
2、watch能完成的功能,computed不一定能完成,例如:watch中可以进行一部操作

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

10丶绑定样式

4种写法
1、字符串写法
2、数组写法
3丶对象写法(属性为true则使用)
4丶对象写法(键值对就是样式)

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 引入vue的js库 -->
    <script src="../../js/vue.js"></script>
    <style>
        .basic {
            font: revert;
            color: brown;
        }

        .normal {
            background-color: aqua;
        }

        .happy {
            background-color: chocolate;
        }

        .upset {
            background-color: springgreen;
        }


    </style>
</head>
<body>

<!-- 容器,绑定vue -->
<div id="app">

    <!--
        绑定class样式,字符串写法,适用于:样式的类名不确定,需要动态指定
    -->
    <div class="basic" class="basic" :class="a" @click="changeColor">div test</div>
    <br>

    <!--
         绑定class样式,数组写法,数组有几个就显示几个,适用于:样式的类名不确定,需要动态指定
    -->
    <div class="basic" class="basic" :class="b" @click="changeColor">div test</div>
    <br>

    <!--
        绑定class样式,对象写法,属性为true则使用,适用于:样式的类名不确定,需要动态指定
    -->
    <div class="basic" class="basic" :class="c" @click="changeColor">div test</div>
    <br>

    <!-- 绑定 style 样式,对象写法。但是注意,这里的key不能瞎写,是固定的属性 -->
    <div :style="styleObj">div test</div>

</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            name: "lz",
            a: 'normal',
            b: ['normal', 'happy'],
            c: {
                normal: false,
                happy: true
            },
            styleObj: {
                fontSize: '30px'
            }
        },
        methods: {
            changeColor() {
                // 随机生成 0,1,2 的数字
                const ran = Math.floor(Math.random() * 3)
                let arr = ['normal', 'upset', 'happy']
                this.a = arr[ran]
                console.log(ran)
            }
        }
    })
</script>

11丶条件渲染

v-show做条件渲染,使用js表达式得出布尔值。不是删除元素,只会将当前元素隐藏
v-if做条件渲染,将当前元素删除

<!-- 容器,绑定vue -->
<div id="app">
    {{name}}

    <!-- v-show做条件渲染,使用js表达式得出布尔值。不是删除元素,只会将当前元素隐藏 -->
    <div v-show="boo"> welcome here</div>

    <!-- v-if做条件渲染,将当前元素删除 -->
    <div v-if="boo2">welcome again.</div>

    <!-- v-else-if, v-else,三者可以一起使用,但是要求结构不能被打断,只能连着一起使用 -->
    <div v-if="boo">React</div>
    <div v-else-if="boo">Vue</div>
    <div v-else="boo">Angular</div>

    <!-- 模板,这里使用模板,不会破坏结构,但是只能使用v-if,不能使用v-show -->
    <template v-if="boo2">
        <div>北京</div>
        <div>上海</div>
    </template>

</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            name: "lz",
            boo: false,
            boo2: true
        }
    })
</script>

12丶列表渲染

12.1 基本列表

v-for指令
1、用于展示数据
2、语法:v-for=’(item, index) in xxx’ :key=’yyy’
3、可遍历:数组,对象,字符串(少用),指定册数(更少)

<!-- 容器,绑定vue -->
<div id="app">

    <!-- 遍历数组中的数据 -->
    <ul>
        <li v-for="(p,index) in persons" :key="p.id">
            姓名:{{p.name}} 年龄:{{p.age}} 地址:{{p.addr}} 索引:{{index}}
        </li>
    </ul>


    <!-- 遍历对象的数据 ,-->
    <ul>
        <li v-for="(item,key) of audi" :key="key">
            {{key}}:{{item}}
        </li>
    </ul>

    <!-- 遍历字符串,第一个参数读取每个字符,第二个参数是索引-->
    <ul>
        <li v-for="(a,b) of name" :key="b">
            {{b}}---{{a}}
        </li>
    </ul>

</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            name: "lz",
            persons: [
                {
                    id: '001',
                    name: 'lz',
                    age: 19,
                    addr: 'shenzhen'
                },
                {
                    id: '002',
                    name: 'hj',
                    age: 27,
                    addr: 'guangzhou'
                },
                {
                    id: '003',
                    name: 'sh',
                    age: 18,
                    addr: 'beijing'
                }
            ],
            audi: {
                name: '奥迪',
                price: '70w'
            }
        }
    })
</script>

12.2 略

13丶表单数据

收集表单的数据
若: 则 v-model 收集的是 value 值,用户输入的就是value值
若: 则 v-model 收集的也是 value 值,且要给标签配置上 value 值
若:
1、没有配置input的value属性,那么收集的就是checked,勾选or未勾选,是布尔值
2、配置了input标签的value属性
1、v-model的初始值是非数组,那么收集的就是checked,勾选or未勾选,是布尔值
2、v-model的初始值是数组,那么收集的就是value组成的数组

备注:v-mpdel的三个修饰符
lazy:失去焦点
number:输入字符串转为有效的数字
trim:输入的首尾空格过滤

<!-- 容器,绑定vue -->
<div id="app">
    <form>
        <label for="user"> 账号:<input type="text" id="user" v-model="user"></label><br><br>
        <label for="pass"> 密码:<input type="text" id="pass" v-model="password"></label><br><br>
        性别:
        男<input type="radio" name="sex" v-model="sex" value="male">
        女<input type="radio" name="sex" v-model="sex" value="female"><br><br>

        年龄:<input type="number" v-model.number="age"><br><br>

        爱好:学习<input type="checkbox" name="habit" v-model="habit" value="study">
        运动<input type="checkbox" name="habit" v-model="habit" value="sport">
        娱乐<input type="checkbox" name="habit" v-model="habit" value="entertainment"> <br><br>

        校区:
        <select v-model="school">
            <option value="">请选择校区</option>
            <option value="beijng">北京</option>
            <option value="shanghai">上海</option>
            <option value="shenzhen">深圳</option>
        </select><br><br>
        其他信息:
        <textarea></textarea><br><br>
        <input type="checkbox" v-model="acc">是否阅读并接受《<a href="https://baidu.com">用户协议</a>》<br><br>
        <button @click.prevent="submit">提交</button>
        <br><br>
    </form>
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            user: '',
            password: '',
            age: '',
            sex: '',
            habit: [],
            school: '',
            acc: ''
        },
        methods: {
            submit() {
                console.log('start to submit.', JSON.stringify(this._data))
            }
        }
    })
</script>

14丶过滤器

备注:使用一个时间日期库的js —> dayjs

<!-- 容器,绑定vue -->
<div id="app">
    显示现在的时间 <br><br>
    <!-- 使用管道符进行过略数据,进入fun函数中进行执行这个函数的逻辑
        当fun函数没有参数时,不使用括号,有参数则使用括号
     -->
    {{nowTime | fun('YY_MM_DD')}}
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            name: "lz",
            nowTime: 1634983401803
        },
        // 过滤器,本质上就是一个函数
        filters: {
            fun(val, str) {
                if (str !== '') {
                    return dayjs(val).format(str)
                }
                let time = dayjs(val).format('YYYY-MM-DD HH:mm:ss')
                console.log('---> ', time)
                return time
            }
        }
    })
</script>

15丶内置指令

15.1 v-text

1、作用:向其所在的节点插入渲染文本内容
2、与插值语法的区别:v-text会替换掉节点的内容,{{xxx}} 则不会替换

<!-- 容器,绑定vue -->
<div id="app">
    <div v-text="name">
        name
    </div>
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            name: "lz"
        }
    })
</script>

15.2 v-html

v-html 有严重的安全问题,不建议使用

15.3 v-once

1、v-once所在的节点在初次动态渲染之后,就被视为静态内容了,下次不会再被更新
2、以后的数据改变,也不会引起v-once所在的结构改变,可以用于优化性能

<!-- 容器,绑定vue -->
<div id="app">
    <input v-model="name">
    <br>
    <div v-once>{{name}}</div>
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            name: "lz"
        }
    })
</script>

15.4 v-pre

1、可以跳过所在节点的编译过程
2、可以利用它跳过:没有使用指令语法,没有使用插值语法的节点,会加快编译

16丶自定义指令

1、自定义一个 v-big 指令,将绑定的数值放大10倍
2、自定义一个 v-fbind 指令,和 v-bind类似,但是可以将让其绑定的input元素默认获取其焦点

<!-- 容器,绑定vue -->
<div id="app">
    <div v-big="n"></div>
</div>

<script>
    Vue.config.productionTip = false
    // 创建vue对象
    const vm = new Vue({
        el: "#app",
        data: {
            name: "lz",
            n: 1
        },
        directives: {
            /**
             * @param ele 表示当前使用这个指令的节点DOM元素
             * @param binding 可以当前n相关的值
             */
            big(ele, binding) {
                ele.innerHTML = binding.value * 10
            }
        }
    })
</script>

17丶生命周期

VM的生命周期
1、创建之前:beforeCreate
2、创建完毕:created

3、挂载之前:beforeMount
4、挂载完毕:mounted 【重要】

5、更新之前:beforeUpdate
6、更新完毕:create

7、销毁之前:beforeDestroy 【重要】
8、销毁完毕:destroy