皓学IT:Vue精讲(第二章)

本文详细介绍了Vue框架中的指令,包括数据绑定(v-bind/v-model)、条件渲染(v-if/v-else/v-else-if)、v-for列表渲染、v-on事件处理以及v-html用于动态插入HTML等内容,展示了Vue指令在控制数据和行为方面的强大功能。
摘要由CSDN通过智能技术生成


Vue指令

什么是Vue的指令?

指令是Vue框架提供的一种特殊的HTML属性,它们帮助我们在HTML中直接操作和控制Vue实例的数据和行为。

指令通过在HTML元素上添加特定的属性来实现,以"v-"开头,后跟指令名称。指令可以绑定到HTML元素、组件、模板或Vue实例上,从而实现不同的功能。

Vue指令有什么用?

指令的作用有以下几个方面:

  1. 数据绑定:最常见的用途是将Vue实例的数据与HTML元素进行绑定。通过指令,我们可以实现双向绑定,即当数据发生变化时,HTML元素会自动更新;反之,当用户在HTML元素上进行输入或操作时,相关的数据也会自动更新。

  2. 条件渲染:指令可以根据条件来控制HTML元素的显示与隐藏。例如,使用v-if指令可以根据条件决定是否渲染某个元素,使用v-show指令可以根据条件决定元素是否显示。

  3. 列表渲染:通过指令,我们可以轻松地遍历数组或对象,生成重复的HTML元素。v-for指令可以循环遍历数据,并根据每个元素生成相应的HTML结构。

  4. 事件处理:指令可以监听并响应HTML元素上的事件。通过v-on指令,我们可以在Vue实例中定义方法,并将这些方法绑定到特定的事件上,从而实现交互和逻辑控制。

  5. 样式和类绑定:指令可以帮助我们根据数据动态地改变HTML元素的样式或类。通过v-bind指令,我们可以将Vue实例的数据绑定到HTML元素的属性上,例如style和class,从而实现样式和类的动态改变。

Vue指令有哪些?
指令作用
v-bind单向绑定解析表达式,可简写为 :xxx (v-bind:xxx),数据只能从data流向页面
v-model双向数据绑定,数据不仅能从data流向页面,还可以从页面流向data
v-for遍历对象、数组、字符串等
v-on绑定事件监听,可简写为 @xxx (v-on:click="")
v-if、v-else-if、v-else条件渲染(动态控制节点是否存在)
v-show条件渲染(动态控制节点是否展示)
v-text向其所在的节点中渲染文本;
v-html向指定节点中渲染包含 html结构 的内容。
v-cloak(没有值)本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
v-oncev-once所在节点在初次动态渲染后,就视为静态内容了
v-pre跳过其所在节点的编译过程

总结,Vue会根据不同的指令,针对标签实现不同的功能


v-html

v-html用来更新元素的 innerHTML,但是存在一定的安全性。

使用方式:

<div id="app">
        <div v-html="message"></div>
    </div>
    <script>
        new Vue({
            el: "#app",
              data: {
                  message: "<h1>Hello, world!</h1>"
              }
        })
    </script>

实现效果

课堂练习

<!--使用vue中的v-html指令把h2标签的“皓学IT”,替换成“a标签链接到百度”-->

<div id="app">
        <h2 v-html="message">皓学IT</h2>
    </div>

实现效果


数据绑定

v-bind指令用于绑定属性(单向数据绑定)

v-model指令为(双向数据绑定)

使用方式:

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

实现效果:

总结:

Vue中有2种数据绑定的方式:

单向绑定(v-bind):数据只能从data流向页面 双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data 备注:

双向绑定一般都应用在表单类元素上(如:<input>、<select>、<textarea>等) v-model:value可以简写为v-model,因为v-model默认收集的就是value值。(重点,后续还有内容)


v-if

v-if 是条件渲染指令,它根据表达式的真假来删除和插入元素,它的基本语法如下:v-if="expression"

expression 是一个返回bool值的表达式,表达式可以是一个bool属性,也可以是一个返回bool的运算式。

提示:v-if指令是根据条件表达式的值来执行元素的插入或者删除行为。

<div id="app">
    <p v-if="yes">Hello, vue.js!</p>
    <p v-if="no">Hey, girl!</p>
    <p v-if="age > 18">Welcome!</p>
    <p v-if="name.indexOf('Henry') >= 0">Hello, {{ name }}!</p>
</div>
let vm = new Vue({
    el: "#app",
    data: {
        yes: true,
        no: false,
        age: 16,
        name: "Henry Lee"
    }
});

##

因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个 <template> 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 <template> 元素。

<div id="#app">
    <template v-if="isLogin">
        <a href="#" class="name">木子李</a>
        <a href="#">注销</a>
    </template>
</div>

v-else

v-else 指令可以为 v-if 添加一个 else 模块:

<div id="#app">
    <template v-if="isLogin">
        <a href="#" class="name">木子李</a>
        <a href="#">注销</a>
    </template>
    <template v-else>
        <a href="#" class="go-login">登录</a>
        <a href="#" class="go-register">注册</a>
    </template>
</div>

v-else-if

<div id="app">
    <p v-if="grade >= 90 && score <= 100">优秀</p>
    <p v-else-if="grade >= 70 && score < 90">良好</p>
    <p v-else-if="grade >= 60 && score < 70">及格</p>
    <p v-else-if="grade >=  0 && score < 60">不及格</p>
    <p v-else>成绩有误!</p>
</div>
new Vue({
    el: '#app',
    grade: {
        score: 98
    }
})
用 key 管理可复用元素

Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。这么做除了使 Vue 变得非常快之外,还有其它一些好处。例如,如果你允许用户在不同的登录方式之间切换:

<template v-if="isTel">
    <span>手机:</span>
    <input type="tel" placeholder="请输入手机号">
</template>
<template v-else>
    <span>邮箱:</span>
    <input type="email" placeholder="请输入邮箱">
</template>
<button type="button" @click="isTel = !isTel">切换登陆方式</button>
let vm = new Vue({
    el: "#app",
    data: {
        isTel: true
    }
});

那么在上面的代码中切换 loginType 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,<input> 不会被替换掉——仅仅是替换了它的 placeholder

自己动手试一试,点击上方查看demo,在输入框中输入一些文本,然后按下切换按钮:

这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key 属性即可:

<input type="tel" placeholder="请输入手机号" key="tel-input">
<input type="email" placeholder="请输入邮箱" key="email-input">

v-show

另一个用于根据条件展示元素的选项是 v-show 指令。用法大致一样:

<h1 v-show="ok">Hello!</h1>

不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display

注意:v-show 不支持 <template> 元素,也不支持 v-else

v-if VS v-show

#v-ifv-show
渲染条件成立,才会渲染元素不管条件是否成立,都会渲染元素
切换开销重新渲染元素,开销更大控制display属性,开销更小
使用场景不频繁切换频繁切换

v-on

vue 事件处理通过 v-on 指令实现,其语法形式为:

// 完整形式 -> v-on:事件类型="事件处理"  -> <div v-on:click="alert('Hello!')"></div>
// 缩写形式 -> @事件类型="事件处理"      -> <div @click="alert('Hello!')"><div>
事件处理器
<div id="app">
    <template>
        <!-- 通过内联脚本处理事件 -->
        <button type="button" @click="alert('Hello')">click me</button>
        <!-- 通过监听函数处理事件 -->
        <button type="button" @click="handleBtnClick">click me</button>
    </template>    
</div>
new Vue({
    el: "#app",
    data: {},
    methods: {
        handleBtnClick(event) {
            // event object
            console.log(event);
            // this -> vue
            console.log(this);
        }
    },
})
事件修饰符

在事件处理程序中调用 event.preventDefault()event.stopPropagation() 是非常常见的需求。尽管我们可以在方法中轻松实现这点,但更好的方式是:方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节。

为了解决这个问题,Vue.js 为 v-on 提供了事件修饰符。之前提过,修饰符是由点开头的指令后缀来表示的。

  • .stop *

  • .prevent *

  • .capture

  • .self

  • .once

  • .passive

<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
 
<!-- 提交事件不再重载页面/阻止表单默认行为 -->
<form v-on:submit.prevent="onSubmit"></form>
 
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
 
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
​
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
​
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>

提示:使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 @click.prevent.self 会阻止所有的点击,而 @click.self.prevent 只会阻止对元素自身的点击。


v-for

v-for 迭代数组

循环使用 v-for 指令

v-for 指令需要以 item in items 形式的特殊语法, items 是源数据数组并且 item 是数组元素迭代的别名。

<div id="app">
    <ol>
        <li v-for="(hero, index) in heros" :key="index">
            <h3>{{ hero.name }}</h3>
        </li>
    </ol>
</div>
var app = new Vue({
    el: '#app',
    data: {
        heros: [
            {name:"张良"},
            {name:"露娜"},
            {name:"妲己"},
            {name:"甄姬"},
            {name:"虞姬"}
        ]
    }
})

提示:在控制台输入 app.heros.push({name:"亚瑟"}) 你将会发现页面上将添加一个列表项。

v-for 迭代对象
<div id="app">
    <div v-for="value in hero">
        <p>{{ value }}</p>
    </div>
</div>
var app = new Vue({
    el: '#app',
    data: {
        hero: {
            // 英雄名
            name: "露娜",
            // 定位
            position: "战士/法师",
            // 特长
            specialSkil: "突进/收割",
            // 技能
            skill:"月光之舞、玄月斩、炙热剑芒、新月突击"
        }
    }
})

你也可以提供第二个参数(key)以及第三个参数(index),修改html部分代码,如下所示:

<div id="app">
    <div v-for="(value, key, index) in hero">
        <p>{{ index }}.  {{ key }} -> {{ value }} </p>
    </div>
</div>

v-for 迭代整数
<div id="app">
    <h3 v-for="idx in 5">{{ idx }}</h3>
</div>
var vm = new Vue({
    el: '#app'
})
// 结果:1 2 3 4 5

数组更新检测

1、变异方法

会改变原始数组的方法被称为变异方法。Vue 包含一组观察数组的变异方法,所以它们也将会触发视图更新。这些方法如下:push()pop()shift()unshift()splice()sort()reverse()

2、非变异方法

不会改变原始数组的方法被称为非变异方法。例如:filter(), concat()slice() 。这些不会改变原始数组,但 总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组以达到数据响应。

3、注意事项

由于 JavaScript 的限制,Vue 不能检测以下变动的数组:

  1. 通过下标修改数据时

  2. 修改数组的长度时

解决第一类问题:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue);
vm.$set(vm.items, indexOfItem, newValue);
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue);

解决第二类问题:

vm.items.splice(newLength)

对象更改检测注意事项

还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除

let vm = new Vue({
  data: { a: 1 }
}
// => "vm.a" 现在是响应式的
vm.b = 2
// => "vm.b" 不是响应式的

对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。但是,可以向嵌套对象添加响应式属性。

// 1
this.$set(this.user, "tel", "17398888669");
// 2
Vue.set(this.user, "job", "前端工程师");
// 3
this.user = Object.assign(this.user, {
    name: "木子李",
    tel: "17398888669",
    job: "前端工程师"
});
// 4
this.user = {
    ...this.user,
    address: "四川省成都市高新区"
};

显示过滤/排序结果

有时,我们想要显示一个数组的过滤或排序副本,而不实际改变或重置原始数据。在这种情况下,可以创建返回过滤或排序数组的计算属性。

例如:

<li v-for="n in evenNumbers"> {{ n }}</li>
data: {
    numbers: [ 1, 2, 3, 4, 5 ]
},
// 计算属性
computed: {
    // 筛选偶数
    eventNumbers() {
        return this.numbers.filters((num) => {
            return num % 2 === 0;
        });
    }
}

在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中) 你可以使用一个 method 方法:

<li v-for="n in even(numbers)">{{ n }}</li>
data: {
     numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
     event() {
         return this.numbers.filter((num) => {
                return num % 2 === 0;
         });
    }
}

提示:

如果是使用计算属性实现过滤,在调用计算属性方法时,无需加圆括号,

如果是使用方法实现过滤,在调用方法时,必须加圆括号。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皓学IT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值