Vue网课笔记(二) 指令介绍

一、v-once

顾名思义,元素和组件只渲染一次,不会随着数据变化而变化

<h2>{{message}}</h2>
<h2 v-once>{{message}}</h2>

第一次渲染完成后,data中的message改变,第一个h2会随之改变,第二个h2不会改变

二、v-html

若字符串是html代码,v-html指令可以将html代码进行解析

<body>

<div id="app">
    <h2>{{url}}</h2>
    <h2 v-html="url"></h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            url: '<a href="http://www.baidu.com">百度一下</a>'
        }
    })
</script>

</body>

在这里插入图片描述

三、v-text

<h2>{{message}}</h2>
<h2 v-text="message"></h2>

这两个语句的效果是一样的
但是一般不会使用v-text指令,因为太不灵活,例如:

<body>

<div id="app">
    <h2>{{message}},世界</h2>
    <h2 v-text="message">,世界</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: '你好'
        }
    })
</script>

</body>

在这里插入图片描述
v-text指令会覆盖标签的内容,不能灵活进行字符串拼接

四、v-pre

跳过这个元素和它的子元素的编译过程,显示原本的内容,一般也不会用

<h2>{{message}}</h2>
<h2 v-pre>{{message}}</h2>

在这里插入图片描述

五、v-cloak

  • 在某些情况下,js代码执行可能遇到卡顿,或js代码执行有延迟,会导致vue没有被及时的加载出来,这会导致浏览器直接显示未编译的Mustache标签
  • 为了避免这种情况,可以加入v-cloak指令,然后给这一指令加入特定css样式
  • 在vue解析之前,标签中有一个属性v-cloak;在vue解析之后,标签中没有一个属性v-cloak
  • 下面的代码中,我们用setTimeout模拟js执行延迟;div没有v-cloak指令会先显示一段{{message}}再显示内容,div有v-cloak指令会先空白一段(这是设置的样式)再显示内容
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        [v-cloak] {
            display: none;
        }
    </style>
</head>
<body>

<div id="app" v-cloak>
    <h2>{{message}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    setTimeout(function () {
        const app = new Vue({
            el: '#app',
            data: {
                message: '你好'
            }
        })
    }, 1000)
</script>

</body>

六、v-bind

用于动态绑定属性

  • 比如动态绑定a元素的href属性
  • 比如动态绑定img元素的src属性
<div id="app">
    <img v-bind:src="imgurl" alt=""><br>
    <a v-bind:href="ahref">百度一下</a>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            imgurl: 'https://img-blog.csdnimg.cn/20200409165249908.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NTU19CZW5qYW1pbg==,size_16,color_FFFFFF,t_70#pic_center',
            ahref: 'http://www.baidu.com'
        }
    })
</script>

</body>

语法糖: v-bind:src简写为:src

 <img :src="imgurl" alt=""><br>
 <a :href="ahref">百度一下</a>

v-bind动态绑定class的对象语法

  • class作为一个属性也可以通过v-bind进行动态绑定
  • 可以使用一种更方便的方式进行class的动态绑定:通过对象
    v-bind:class=""引号中可以放一个对象,对象中是键值对,键值对可以是类名加一个布尔型变量,当布尔型变量为true时这个类添加到该标签,为false时不添加这个类
  • 下面的例子用这种方式实现点击按钮切换文字颜色
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    .active{
        color: red;
    }
</style>
<body>

<div id="app">
    <h2 :class="{active: isActive, line: isLine}">{{message}}</h2>
    <button @click="btnClick">按钮</button>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: '你好!',
            isActive: true,
            isLine: true
        },
        methods: {
            btnClick: function () {
                this.isActive = !this.isActive
            }
        }
    })
</script>

</body>
  • 可以通过函数返回的方式缩短该行标签的长度
<div id="app">
    <h2 :class="{active: isActive, line: isLine}">{{message}}</h2>
    <h2 :class="getClasses()">{{message}}</h2>
    <button @click="btnClick">按钮</button>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: '你好!',
            isActive: true,
            isLine: true
        },
        methods: {
            btnClick: function () {
                this.isActive = !this.isActive
            },
            getClasses: function () {
                return {active: this.isActive, line: this.isLine}
            }
        }
    })
</script>

</body>

两行h2的变化是相同的

v-bind动态绑定class的数组语法

用的很少

<h2 :class="['active','line']">{{message}}</h2>
<!--这两行代码效果是一样的-->
<h2 class="active line">{{message}}</h2>

数组里面也可以是变量,变量的值是字符串,字符串是class的名字

<h2 :class="[active,line]">{{message}}</h2>

标签在动态绑定class的同时还可以有静态绑定的class

解析时会进行合并

<h2 class="title" :class="{active: true, line: false}">{{message}}</h2>

在这里插入图片描述

v-for与v-bind结合

下面实现列表中点击哪条就哪条变色(active类与上面的相同,这不重要)

<body>

<div id="app">
    <ul>
        <li v-for="(m, index) in movies" @click="cur = index" :class="cur == index ? 'active' : ''">{{m}}</li>
    </ul>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            movies: ['大赢家','囧妈','大黄蜂','无问西东'],
            cur: 5
        }
    })
</script>

</body>

v-bind动态绑定style的对象语法

与动态绑定class的对象语法类似,键值对是css属性名和属性值

<body>

<div id="app">
    <h2 :style="{fontSize: finalSize + 'px', backgroundColor: finalColor}">{{message}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: '你好!',
            finalSize: 100,
            finalColor: 'red'
        }
    })
</script>

</body>
  • font-sizebackground-color这种属性要写成驼峰命名法的形式fontSizebackgroundColor-会被解析成操作符
  • 属性值为具体数值时要加上单引号写成字符串的形式,否则会当做一个变量去解析
<h2 :style="{fontSize: '50px'}">{{message}}</h2>
  • 也可以通过上面getClasses()函数返回的方式缩短该行标签长度

v-bind动态绑定style的数组语法

与动态绑定class的数组语法类似,更加注重将对象放进数组

<body>

<div id="app">
    <h2 :style="[baseStyle1, baseStyle2]">{{message}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: '你好!',
            baseStyle1: {backgroundColor: 'red'},
            baseStyle2: {fontSize: '100px'}
        }
    })
</script>

</body>

有关methods中函数的写法:ES6中对象字面量的增强写法

七、事件监听 v-on

基本使用

<body>

<div id="app">
    <h2>当前计数:{{counter}}</h2>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
</div>

<script src="../js/vue.js"></script>

<script>
    const app = new Vue({
        el: '#app',
        data: {
            counter: 0
        },
        methods: {
            increment() {
                console.log('increment被执行');
                this.counter++
            },
            decrement() {
                console.log('decrement被执行');
                this.counter--
            }
        }
    })
</script>

</body>

语法糖: 简写 v-on:click简写为@click

<button @click="increment">+</button>
<button @click="decrement">-</button>

如果绑定的操作很简单,无需绑定函数,也可以下面这样

<body>

<div id="app">
    <h2>当前计数:{{counter}}</h2>
    <button @click="counter++">+</button>
    <button @click="counter--">-</button>
</div>

<script src="../js/vue.js"></script>

<script>
    const app = new Vue({
        el: '#app',
        data: {
            counter: 0
        }
    })
</script>

</body>

传递参数

<body>

<div id="app">
    <!--事件调用的方法没有参数-->
    <button @click="btn1Click()">按钮1.1</button>
    <button @click="btn1Click">按钮1.2</button>

    <!--在事件定义时,写方法时省略了小括号,但是方法本身需要参数-->
    <!--这种情况vue会默认将浏览器生成的event事件对象作为参数传入到方法-->
    <button @click="btn2Click(123)">按钮2.1</button>
    <button @click="btn2Click()">按钮2.2</button>
    <button @click="btn2Click">按钮2.3</button>

    <!--方法定义时,我们需要event对象,同时又需要其他参数-->
    <button @click="btn3Click">按钮3.1</button>
    <button @click="btn3Click(123, event)">按钮3.2</button>
    <button @click="btn3Click(123, $event)">按钮3.3</button>
</div>

<script src="../js/vue.js"></script>

<script>
    const app = new Vue({
        el: '#app',
        data: {
        	
        },
        methods: {
            btn1Click() {
                console.log("btn1Click");
            },
            btn2Click(abc) {
                console.log(abc);
            },
            btn3Click(abc, event) {
                console.log(abc, event);
            }
        }
    })
</script>

</body>
1. 事件调用的方法没有参数

按钮1.1 按钮1.2

  • 没有参数时,方法名后面的括号可有可无
2. 事件调用的方法需要参数

按钮2.1 按钮2.2 按钮2.3

  • 按钮2.1可以正常传参
  • 按钮2.2未传入参数,打印出undefined,与普通的JavaScript函数调用未传参是一样的
  • 按钮2.3方法名后没有括号,这种情况vue会默认将浏览器生成的event事件对象作为参数传入到方法
    在这里插入图片描述
3. 需要event对象,同时又需要其他参数

按钮3.1 按钮3.2 按钮3.3

  • 按钮3.1方法名后没有括号,vue将浏览器生成的event传给第一个参数abc后打印,第二个参数event没有东西传入打印出undefined
  • 按钮3.2那样写是错误的,event被当做一个变量,会在data中寻找这个变量,未定义则会报错
  • 按钮3.3是正确写法

修饰符

<body>

<div id="app">
    <!--1. .stop修饰符的使用-->
    <!--阻止事件冒泡-->
    <div @click="divClick">
        aaaaaaa
        <button @click.stop="btnClick">按钮</button>
    </div>

    <!--2. .prevent修饰符的使用-->
    <!--取消默认事件-->
    <br>
    <form action="baidu">
        <input type="submit" value="提交" @click.prevent="submitClick"></input>
    </form>

    <!--3. 监听某个键盘的键帽-->
    <!--特定按键触发时回调-->
    <!--格式:键修饰符.键别名(keyAlias)或键代码(keyCode)-->
    <input type="text" @keyup.enter="keyUp">

    <!--4. .once修饰符的使用-->
    <!--只触发一次回调-->
    <br>
    <button @click.once="btn2Click">按钮2</button>
</div>

<script src="../js/vue.js"></script>

<script>
    const app = new Vue({
        el: '#app',
        data: {

        },
        methods: {
            divClick() {
                console.log('divClick');
            },
            btnClick() {
                console.log('btnClick');
            },
            submitClick() {
                console.log('submitClick');
            },
            keyUp() {
                console.log('keyUp')
            },
            btn2Click() {
                console.log('btn2Click');
            },
        }
    })
</script>

</body>

八、条件判断

v-if

<body>

<div id="app">
    <h2 v-if="isShow">
        <div>{{message}}</div>
        <div>{{message}}</div>
        <div>{{message}}</div>
        <div>{{message}}</div>
    </h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            message: '你好啊世界!',
            isShow: true
        }
    })
</script>

</body>

v-else-if与v-else

<body>

<div id="app">
    <h2 v-if="score>=90">优秀</h2>
    <h2 v-else-if="score>=80">良好</h2>
    <h2 v-else-if="score>=60">及格</h2>
    <h2 v-else>不及格</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            score: 66
        }
    })
</script>

</body>
  • 但是这样复杂的逻辑判断如果用v-else-if指令写会显得很麻烦且不易阅读,所以v-else-if指令不常用
  • 可以用计算属性写成下面的形式
<body>

<div id="app">
    <h2>{{result}}</h2>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            score: 66
        },
        computed: {
            result() {
                let showMessage = '';
                if (this.score >= 90) {
                    showMessage = '优秀'
                } else if (this.score >= 80) {
                    showMessage = '良好'
                } else if (this.score >= 60) {
                    showMessage = '及格'
                } else {
                    showMessage = '不及格'
                }
                return showMessage
            }
        }
    })
</script>

</body>

用户登录方式切换的案例

点击按钮实现登录方式的切换
在这里插入图片描述在这里插入图片描述

<body>

<div id="app">
    <span v-if="isUser">
        <label for="username">用户账号</label>
        <input type="text" id="username" placeholder="用户账号">
    </span>
    <span v-else>
        <label for="email">用户邮箱</label>
        <input type="text" id="email" placeholder="用户邮箱">
    </span>
    <button @click="isUser = !isUser">切换类型</button>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            isUser: true
        }
    })
</script>

</body>
案例中的小问题

在本案例中,若在输入框中输入内容之后再点击按钮,会发现切换后输入框中的内容依然存在没有被清除

  • 原因:这是因为Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素
  • 在本案例中,虚拟DOM中会对两个input和label进行对比,将不一样的内容进行修改,剩下的就用之前的
  • 解决方案:如果不希望出现类似重复利用的问题,可以给对应的元素添加key,并且保证key的不同;若key相同,则被认为是可以复用的
<div id="app">
    <span v-if="isUser">
        <label for="username">用户账号</label>
        <input type="text" id="username" placeholder="用户账号" key="username">
    </span>
    <span v-else>
        <label for="email">用户邮箱</label>
        <input type="text" id="email" placeholder="用户邮箱" key="email">
    </span>
    <button @click="isUser = !isUser">切换类型</button>
</div>

v-show

v-show与v-if的用法相同,控制节点的方式不同

<div v-show="isShow">{{msg}}</div>
  • v-show控制的是节点的display属性,v-if是将节点从DOM中删除了,这一点可以通过F12看到
  • 所以如果节点需要频繁的显示隐藏,使用v-show性能更佳;只有一次切换,使用v-if

v-for遍历

1.遍历数组

<body>

<div id="app">
    <!--  遍历过程中没有使用索引值(下标值)  -->
    <ul>
        <li v-for="item in names">{{item}}</li>
    </ul>

    <!--  遍历过程中获取使用索引值(下标值)  -->
    <ul>
        <li v-for="(item, index) in names">{{index + 1}}.{{item}}</li>
    </ul>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: { 
            message: '你好啊世界!',
            names: ['hammer', 'sister', 'hs']
        }
    })
</script>

</body>

2.遍历对象

<body>

<div id="app">
    <!--  只获取一个值,取到的是value  -->
    <ul>
        <li v-for="item in info">{{item}}</li>
    </ul>

    <!--  获取key和value  -->
    <ul>
        <li v-for="(value, key) in info">{{key}}-{{value}}</li>
    </ul>

    <!--  获取key和value和index  -->
    <ul>
        <li v-for="(value, key, index) in info">{{index}}-{{key}}-{{value}}</li>
    </ul>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            info: {
                name: 'hammer',
                age: 20,
                height: 1.81
            }
        }
    })
</script>

</body>

key

<body>

<div id="app">
    <ul>
    <!--    绑定key的时候要绑定和item一一对应唯一性的    -->
    <!--    这个地方不能绑定index,index与item不是一一对应唯一性的,例如在中间插上一个元素,后面的index全都变了    -->
    <!--    但如果有重复元素的数组,也不能绑定item    -->
        <li v-for="item in letters" :key="item">{{item}}</li>
    </ul>
</div>

<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            letters: ['A','B','C','D','E','F']
        }
    })
</script>

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值