Vue的指令系统

230 阅读10分钟

前言

在了解了vue的组件化开发思想后,我们就要来接触vue的指令系统了。

vue的指令系统

Vue.js 的指令系统是框架的一个核心特性,它提供了一种简洁的方式来绑定 DOM 属性到数据模型。Vue 指令以 v- 开头,并且可以在模板中使用。它们通过在元素上添加特定的行为或动态地将数据绑定到 DOM 来工作。

1. v-text

v-text 用于更新元素的文本内容。当使用 v-text 时,Vue 会替换元素中的所有内容,并用指定的数据模型中的值来替代。这与 v-html 不同,后者会直接更新元素的 innerHTML,允许插入 HTML 代码。

使用 v-text 的语法

你可以将 v-text 附加到任何元素上,并且绑定一个表达式,这个表达式的值会被渲染为该元素的文本内容。

示例:

<template>
    <div v-text="msg"></div>
</template>

<script setup>
const msg = 'hello world'
</script>

这样div容器就会把msg以文本字符串的形式加载到dom结构上。

2. v-html

v-html用于更新元素的 innerHTML。这意味着它会直接插入 HTML 字符串,并将其解析为真实的 DOM 节点。与 v-text 不同,v-text 只是简单地将数据模型中的值作为纯文本插入,而不解析 HTML 标签。

使用 v-html 的语法

你可以将 v-html 附加到任何元素上,并绑定一个表达式,该表达式的值将会被渲染为 HTML。

示例:

<template>
    <div v-html= "msg"></div>
</template>

<script setup>
const msg = '<p>床前明月光</p><p>疑是地上霜</p>' // 富文本
</script>

首先像msg这种带HTML标签的字符串被称为富文本,然后就是v-html会把msg认为为HTML代码而解析内部的标签。

注意事项

  1. 安全性与 XSS 攻击:直接使用 v-html 插入 HTML 可能会引入安全风险,特别是当 HTML 内容来自不受信任的来源时。这是因为插入的 HTML 可能包含恶意脚本,导致跨站脚本攻击 (XSS)。为了防止这种攻击,确保始终对用户提供的数据进行适当的转移或清理。

  2. 性能考虑:频繁地使用 v-html 更新大段的 HTML 可能会导致性能下降。这是因为 Vue 需要重新解析和渲染 HTML 内容。

  3. v-text 的区别v-text 只更新元素的 textContent,而不会解析 HTML 标签。如果你不需要解析 HTML 标签,使用 v-text 更加安全和高效。

3. v-if

v-if 是一个非常常用的指令,它用于条件性地渲染一个块。当表达式的值为 true 时,该元素及其子元素才会被渲染到 DOM 中;如果值为 false,则什么都不会被渲染;与常见的if一样,也可以搭配v-else-ifv-else。这是 Vue 提供的一种基于数据驱动的视图更新机制。

基本用法:

<template>
    <div>
        <h2 @click = 'happy'>{{ count }}</h2>
        <h3 v-if="count<30">happy</h3>
        <h3 v-else-if="count<40">unhappy</h3>
        <h3 v-else>very unhappy</h3>
    </div>
</template>

<script setup>
import {ref} from 'vue'
let count = ref(20)
const happy = () =>{
    count.value++
}
</script>

这里的count是作为vue中最关键的响应式数据声明的,vue中有很多声明响应式变量的方法,这里是其中一种,即使用ref声明,当一个变量声明为响应式时,它的值发生变化,与之相关的DOM结构也会发生变化;这里使用h2标签承载点击事件,来对count的值进行递增,需要注意的是,使用ref声明的变量在读取修改时需要加上.value,这样才能修改;然后为v-if加上条件count<30时显示happy,大于30小于40时显示unhappy,大于40时显示very unhappy

注意事项
  1. 避免同时使用 v-if 和 v-for:如果需要同时使用 v-ifv-for,请确保 v-if 放在 v-for 之前,因为这样性能更好。Vue 会尝试优化只使用 v-if 或者只使用 v-for 的情况,但是同时使用的话会导致渲染效率降低。
  2. 初始渲染性能:对于初始渲染,v-if 有更高的切换开销,因为它涉及到元素的添加和移除。如果元素需要频繁切换显示状态,使用 v-show 会更高效。
  3. 惰性计算v-if 是惰性的,也就是说它只在条件第一次改变时运行一次。这意味着如果你使用 v-if 来控制组件的渲染,那么只有当条件改变时组件才会被创建和销毁。

4. v-show

v-show 用于条件性地显示或隐藏 DOM 元素。与 v-if 不同的是,v-show 不会从 DOM 中移除元素,而是通过修改元素的 CSS display 属性来控制其可见性。

示例:

<template>
    <div>
        <h2 @click = 'happy'>{{ count }}</h2>
        <h4 v-show="count<30">happy</h4>
    </div>
</template>

<script setup>
import {ref} from 'vue'
let count = ref(20)
const happy = () =>{
    count.value++
}
</script>

与v-if的例子类似,不同点在于使用了v-show来控制显示,如果count符合小于30,则显示happy,而如果count大于30,h4并不会直接消失,而是它的css属性display被设置为none。

与 v-if 的区别

v-showv-if 都可以用来控制元素的显示或隐藏,但它们的工作方式有所不同:

  • v-if:当条件为 false 时,会从 DOM 中完全移除元素。
  • v-show:当条件为 false 时,会通过 CSS 将元素的 display 属性设为 none

这意味着 v-if 更适用于频繁改变条件的情况,因为它涉及到元素的添加和移除。而 v-show 更适合于简单的切换显示状态,因为它不需要重新编译和渲染整个元素。

使用场景
  • 简单的切换:如果只需要简单地切换元素的可见性,使用 v-show 通常更为合适。
  • 性能考虑:如果元素不需要频繁切换显示状态,使用 v-show 可以提高性能,因为它不会涉及 DOM 的重绘和重排。
  • 初始渲染:对于初始渲染,v-if 有更高的切换开销,因为它涉及到元素的添加和移除。如果元素需要频繁切换显示状态,使用 v-show 会更高效。

5. v-for

v-for 是一个非常重要的指令,它用于循环遍历数组或对象,并为每个项目渲染一个模板块。这使得你可以轻松地展示动态生成的数据列表。

基本语法

v-for 的基本语法是 v-for="(item, index) in items",其中:

  • item 是当前项目的别名(通常是变量)。
  • index 是当前项目的索引(可选)。
  • items 是要迭代的数据源(通常是数组或对象)。
示例
<template>
    <ul>
        <li v-for="(item,x) in list" :key = "item.id" @click="showName(item.name)">{{item.id}}.{{ item.name }}</li>
    </ul>
</template>

<script setup>
const list = [
    {id:1,name:"庐州月"},
    {id:2,name:"千百度"},
    {id:3,name:"雅俗共赏"},
    {id:4,name:"多余的解释"}
]
</script>

上面的代码将渲染出一个歌名列表,每个列表项都显示歌名的名字和ID。

6. v-on

v-on 是 Vue.js 中用于监听 DOM 事件的指令。通过 v-on,你可以绑定一个或多个方法到特定的 DOM 事件上,从而实现对用户交互的响应。

基本语法

v-on 的基本语法是 v-on:event="handler",其中:

  • event 是你要监听的 DOM 事件名称。
  • handler 是 Vue 实例中定义的方法名。
示例

假设我们有一个按钮,点击按钮时触发一个名为 greet 的方法:

<template>
    <div id="app"> 
        <button v-on:click="greet">Say Hello</button> 
    </div> 
</template>
<script setup> 
const greet = () =>{
    console.log('hello')
}
</script>

上面的代码中,每当用户点击按钮时,就会在控制台输出 "Hello"。

简写形式

v-on 也可以使用更简洁的语法来书写:

<button @click="greet">Say Hello</button>

这里 @click 等同于 v-on:click

7. v-model

v-model 是一个非常强大的指令,它实现了表单输入元素(如 <input><textarea><select>)与 Vue 实例中的数据属性之间的双向数据绑定。这意味着当用户更改输入字段时,相应的数据模型也会自动更新;反之亦然,当数据模型变化时,输入字段也会随之更新。

基本用法

文本输入

对于文本输入(<input type="text">),v-model 会自动绑定 value 属性和 input 事件。

<div id="app">
  <input type="text" v-model="message">
  <p>{{ message }}</p>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
});
</script>

复选框

对于复选框(<input type="checkbox">),v-model 默认绑定 checked 属性和 change 事件。

<div id="app">
  <input type="checkbox" id="agree" v-model="agreed">
  <label for="agree">I agree</label>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    agreed: false
  }
});
</script>

单选按钮

对于单选按钮(<input type="radio">),v-model 绑定 value 属性和 change 事件。

<div id="app">
  <input type="radio" id="one" value="One" v-model="picked">
  <label for="one">One</label>
  <br>
  <input type="radio" id="two" value="Two" v-model="picked">
  <label for="two">Two</label>
  <br>
  <span>Picked: {{ picked }}</span>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    picked: ''
  }
});
</script>

下拉列表

对于下拉列表(<select>),v-model 也绑定 value 属性和 change 事件。

<div id="app">
  <select v-model="selected">
    <option disabled value="">Please select one</option>
    <option value="one">One</option>
    <option value="two">Two</option>
    <option value="three">Three</option>
  </select>
  <p>Selected: {{ selected }}</p>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    selected: ''
  }
});
</script>

多选下拉列表

对于多选下拉列表(<select multiple>),v-model 会绑定 value 属性和 change 事件,并且 value 必须是一个数组。

<div id="app">
  <select multiple v-model="selectedItems">
    <option value="one">One</option>
    <option value="two">Two</option>
    <option value="three">Three</option>
  </select>
  <p>Selected: {{ selectedItems }}</p>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    selectedItems: []
  }
});
</script>

数值类型

对于数值类型的输入(如 <input type="number">),v-model 会自动进行类型转换。

<div id="app">
  <input type="number" v-model.number="age">
  <p>Your age is: {{ age }}</p>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    age: 25
  }
});
</script>

自定义组件

对于自定义组件,你可以在组件内部使用 v-model,并且通过 model 选项来指定 prop 和 event 的名字。

<!-- MyInput.vue -->
<template>
  <input type="text" :value="value" @input="updateValue">
</template>

<script>
export default {
  model: {
    prop: 'value',
    event: 'input'
  },
  props: {
    value: String
  },
  methods: {
    updateValue(e) {
      this.$emit('input', e.target.value);
    }
  }
}
</script>
<div id="app">
  <my-input v-model="message"></my-input>
  <p>{{ message }}</p>
</div>

<script>
import MyInput from './MyInput.vue';

new Vue({
  el: '#app',
  components: {
    MyInput
  },
  data: {
    message: 'Hello Vue!'
  }
});
</script>

8. v-bind

v-bind 用于动态地将数据绑定到 HTML 元素的属性上。通过 v-bind,你可以将 Vue 实例中的数据属性绑定到 DOM 元素的任何属性,包括 classstyle 以及其他标准的 HTML 属性。

基本语法

v-bind 的基本语法是 v-bind:attribute="expression",其中:

  • attribute 是要绑定的 DOM 属性名称。
  • expression 是 Vue 实例中的数据属性或其他表达式。

简写形式

v-bind 通常可以简写为 :,例如 v-bind:href 可以简写为 :href

示例

假设我们有一个 Vue 实例,并且数据源包含一个 URL,我们可以使用 v-bind 来动态绑定这个 URL 到一个 <a> 标签的 href 属性:

<div id="app">
  <a :href="url">Visit our website</a>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    url: 'https://example.com'
  }
});
</script>

绑定类名 (Class)

你还可以使用 v-bind:class 来动态地绑定类名:

<div id="app">
  <div :class="{ active: isActive }"></div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    isActive: true
  }
});
</script>

在这个例子中,如果 isActivetrue,则 <div> 元素会获得 active 类名。

绑定内联样式 (Style)

同样地,你可以使用 v-bind:style 来动态地绑定内联样式:

<div id="app">
  <div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    activeColor: 'red',
    fontSize: 30
  }
});
</script>

绑定多个属性

你还可以使用对象的形式来绑定多个属性:

<div id="app">
  <a :href="url" :target="target">Visit our website</a>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    url: 'https://example.com',
    target: '_blank'
  }
});
</script>

使用表达式

v-bind 表达式可以是任意有效的 JavaScript 表达式,这意味着你可以执行简单的计算:

<div id="app">
  <a :href="'https://example.com/' + username">Visit my profile</a>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    username: 'john_doe'
  }
});
</script>

绑定组件属性 (Props)

在 Vue 组件中,v-bind 通常用于将父组件的数据传递给子组件的属性(props):

<!-- Parent.vue -->
<child-component :message="message"></child-component>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      message: 'Hello Vue!'
    };
  }
};
</script>
<!-- ChildComponent.vue -->
<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  props: {
    message: String
  }
};
</script>

其他指令

除了这些基本指令之外,Vue 还提供了其他一些有用的指令:

v-pre

  • 跳过编译:告诉 Vue 不要编译包含该指令的元素和子元素。

v-once

  • 一次性渲染:只渲染元素和组件一次。

v-cloak

  • 解决闪烁问题:在 Vue.js 加载完成之前隐藏未编译的 Mustache 标签。

v-slot

  • 插槽(Slot) :用于定义作用域插槽的内容。

自定义指令

  • 扩展功能:允许注册自定义指令,以便为 Vue 添加额外的功能。

修饰符

  • 增强指令行为:例如,在 v-on 上可以使用 .prevent 或 .stop 修饰符来改变事件处理行为。

总结

这就是vue中所有的指令了,如何去使用、理解这些指令就会是往后Vue.js学习过程的一部分了。

如果文章对你有所帮助,就点个赞吧!!

你的赞对我真的很重要。

我是ace,下次分享再见!!!