Vue基础--Vue中的常见基础指令详解

一、指令的概念

Vue中的指令就是带有v-前缀的特殊属性。

它们能扩展HTML标签的功能。

二、Vue中的基础指令

2.1 v-once

v-once用于指定元素或者组件只渲染一次。

当数据发生变化时,元素或者组件以及其所有的子元素将视为静态内容并且跳过。

该指令可以用于性能优化。

<div id="app">

    <!-- 指令: v-once -->
    <h2 v-once>{{ message }}</h2>	<!-- 点击changeMessage按钮 这里的数据不变化 -->	
    <h1>{{message}}</h1>			<!-- 点击changeMessage按钮 这里的数据变为 哈喽 Vue -->
    								<!-- 因此点击changeMessage按钮后,数据`message`是已经发生改变了的 -->
    <button @click="changeMessage">改变message</button>
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data: function() {
            return {
                message: "Hello Vue",
                counter: 100
            }
        },

        methods: {
            changeMessage: function() {
                this.message = "哈喽 Vue"
            }
        }
    })

    // 2.挂载app
    app.mount("#app")
</script>

2.2 v-text

用于更新元素的文本内容。

<div id="app">
    <!-- message对应的Hello Vue会直接被渲染到当前标签当中 -->	
    <h2 v-text="message">aaa</h2>	
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data: function() {
            return {
                message: "Hello Vue"
            }
        },
    })

    // 2.挂载app
    app.mount("#app")  
</script>

2.3 v-html

如果我们展示的内容本身是html 的,Vue并不会对其进行特殊的解析。

如果我们希望这个内容被Vue可以解析出来,那么可以使用 v-html 来标识当前的元素。

<div id="app">
    <h2>{{ content }}</h2>			<!-- 这里的content会原样字符串展示 -->
    <h2 v-html="content"></h2>		<!-- 这里的content会被Vue解析成Html -->
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data: function() {
            return {
                content: `<span style="color: red; font-size: 30px;">v-html演示</span>`
            }
        },
    })

    // 2.挂载app
    app.mount("#app")
</script>

2.4 v-pre

v-pre用于跳过元素和它的子元素的编译过程,显示原始的Mustache标签。

它可以跳过不需要编译的节点,加快编译的速度。

<div id="app">
    <div v-pre>
        <h2>{{ message }}</h2>	<!-- 这里直接原样展示{{ message }},不进行编译 -->
    </div>
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data: function() {
            return {
                message: "Hello Vue",
            }
        },
    })

    // 2.挂载app
    app.mount("#app")
</script>

2.5 v-cloak

给元素加一个斗篷,让元素慢慢渲染,等元素渲染完成后再显示。

  • 这个指令保持在元素上直到关联组件实例结束编译。

  • 这个指令可以隐藏未编译的 Mustache 标签直到组件实例准备完毕。

<style>
    [v-cloak] {
        display: none;
    }
</style>

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

<script src="../lib/vue.js"></script>
<script>
	/*	
		3秒内由于还没有Vue实例,因此{{message}}会原样显示
    	但是这样明显是不太合理的。
    	
    	只要加了v-cloak指令,并且添加在css中添加[v-cloak],
    	那么在{{message}}没有值的时候就会按[v-cloak]中写的一样先把元素 display: none;
    	而是会等Vue实例创建完毕后, message有值了再再移除 display: none,从而把元素渲染出来
    */
    setTimeout(() => {
        // 1.创建app
        const app = Vue.createApp({
            data: function() {
                return {
                    message: "Hello Vue"
                }
            },
        })

        // 2.挂载app
        app.mount("#app")
    }, 3000)

</script>

2.6 v-memo(3.2版本之后才支持)

缓存一个模板的子树。在元素和组件上都可以使用。

为了实现缓存,该指令需要传入一个固定长度的依赖值数组进行比较。

如果数组里的每个值都与最后一次的渲染相同,那么整个子树的更新将被跳过。

<div id="app">
    
    <!-- 
		当组件重新渲染,如果 name 和 age 都保持不变。
		那么这个 <div> 及其子项的所有更新都将被跳过。 

		其它东西变了就直接不管
	-->
    <div v-memo="[name, age]">
        <h2>姓名: {{ name }}</h2>
        <h2>年龄: {{ age }}</h2>
        <h2>身高: {{ height }}</h2>
    </div>
    <button @click="updateInfo">改变信息</button>
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data: function() {
            return {
                name: "lucy",
                age: 18,
                height: 1.88
            }
        },

        methods: {
            updateInfo: function() {
                // this.name = "jack"		//改变它 回去检查 v-memo所在div中的元素是否变化
                // this.age = 20			//改变它 回去检查 v-memo所在div中的元素是否变化
                this.height = 1.76			//改变它 不会检查 v-memo所在div中的元素是否变化
            }
        }
    })

    // 2.挂载app
    app.mount("#app")
</script>

2.7 v-bind

v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值。

被绑定的值将会被Vue管理。

  • 缩写:: 或者 . (当使用 .prop 修饰符)
  • 期望:any (带参数) |Object(不带参数)
  • 参数:attrOrProp (可选的)
  • 修饰符:
    • .camel ——将短横线命名的 attribute 转变为驼峰式命名。
    • .prop ——强制绑定为 DOM property。3.2+
    • .attr ——强制绑定为 DOM attribute。3.2+
1) 绑定属性
<div id="app">
    <div>
        <button @click="switchImage">切换图片</button>
    </div>

    <!-- 1.绑定img的src属性 -->
    <img v-bind:src="showImgUrl" alt="">
    <!-- 语法糖: v-bind -> : -->
    <img :src="showImgUrl" alt="">

    <!-- 2.绑定a的href属性 -->
    <a :href="href">百度一下</a>

</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data: function() {
            return {
                imgUrl1: "test1.jpg",
                imgUrl2: "test2.jpg",
                showImgUrl: "test3",
                href: "http://www.baidu.com"
            }
        },

        methods: {
            switchImage: function() {
                this.showImgUrl = this.showImgUrl === this.imgUrl1 ? this.imgUrl2: this.imgUrl1
            }
        }
    })

    // 2.挂载app
    app.mount("#app")
</script>
2) 绑定class属性

在开发中,有时候我们的元素class也是动态的。

绑定class有两种方式:

  • 对象语法

  • 数组语法

<div id="app">
    <!-- 1.基本绑定class -->
    <h2 :class="classes">Hello World</h2>

    <!-- 2.动态class可以写对象语法 -->
    <button :class=" isActive ? 'active': '' " @click="btnClick">对象语法1</button>

    <!-- 2.1.对象语法的基本使用(常用) -->
    <button :class="{ active: isActive }" @click="btnClick">对象语法2</button>

    <!-- 2.2.对象语法的多个键值对 -->
    <button :class="{ active: isActive, why: true, kobe: false }" @click="btnClick">多个键值对对象语法</button>

    <!-- 2.3.动态绑定的class是可以和普通的class同时的使用 -->
    <button class="abc cba" :class="{ active: isActive, why: true, kobe: false }" @click="btnClick">动态绑定的class是可以和普通的class同时的使用1</button>

    <!-- 2.4.动态绑定的class是可以和普通的class同时的使用 -->
    <button class="abc cba" :class="getDynamicClasses()" @click="btnClick">动态绑定的class是可以和普通的class同时的使用2</button>

    <!-- 3.了解下动态class可以写数组语法 -->
    <h2 :class="['abc', 'cba']">Hello Array</h2>
    <h2 :class="['abc', className]">Hello Array</h2>
    <h2 :class="['abc', className, isActive? 'active': '']">Hello Array</h2>
    <h2 :class="['abc', className, { active: isActive }]">Hello Array</h2>
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data: function() {
            return {
                classes: "abc cba nba",
                isActive: false,
                className: "why"
            }
        },

        methods: {
            btnClick: function() {
                this.isActive = !this.isActive
            },

            getDynamicClasses: function() {
                return { active: this.isActive, why: true, kobe: false }
            }
        }
    })

    // 2.挂载app
    app.mount("#app")
</script>
3) 绑定style属性

我们可以利用v-bind:style来绑定一些CSS内联样式。

这次因为某些样式我们需要根据数据动态来决定:比如某段文字的颜色,大小等等。

CSS 属性名可以用驼峰式命名或短横线分隔来命名。

<div id="app">
    <!-- 1.普通的html写法 -->
    <h2 style="color: red; font-size: 30px;">啦啦啦</h2>

    <!-- 2.style中的某些值, 来自data中 -->
    <!-- 2.1.动态绑定style, 在后面跟上 对象类型 (常用)-->
    <h2 v-bind:style="{ color: fontColor, fontSize: fontSize + 'px' }">啦啦啦</h2>
    <!-- 2.2.动态的绑定属性, 这个属性是一个对象 -->
    <h2 :style="objStyle">啦啦啦</h2>

    <!-- 3.style的数组语法 -->
    <h2 :style="[objStyle, { backgroundColor: 'purple' }]">啦啦啦</h2>
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data: function() {
            return {
                fontColor: "blue",
                fontSize: 30,
                objStyle: {
                    fontSize: '50px',
                    color: "green"
                }
            }
        },
    })

    // 2.挂载app
    app.mount("#app")

</script>
4) 动态绑定属性

在某些情况下,属性的名称可能也不是固定的。

一般情况下无论绑定srchrefclassstyle,属性名称都是固定的。

如果属性名称不是固定的,我们可以使用 :[属性名]=“值” 的格式来定义动态属性。

<div id="app">
     <!-- 动态绑定name动态属性的值为test -->
    <h2 :[name]="'test'">Hello Vue</h2>
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data: function() {
            return {
                name: "class"
            }
        },
    })

    // 2.挂载app
    app.mount("#app")
</script>
4) 动态绑定对象

如果希望将一个对象的所有属性,绑定到元素上的对应属性,可以直接使用 v-bind 绑定一个 对象。

<div id="app">
    <h2 :name="name" :age="age" :height="height">Hello Vue</h2>

    <!-- v-bind绑定对象: 今后可以给组件传递参数, 非常有用;  此时info对象会被拆解成div的各个属性-->
    <h2 v-bind="infos">Hello Bind</h2>
</div>

<script src="../lib/vue.js"></script>
<script>
    // 1.创建app
    const app = Vue.createApp({
        data: function() {
            return {
                infos: { name: "why", age: 18, height: 1.88, address: "广州市" },

                name: "why",
                age: 18,
                height: 1.88
            }
        },
    })

    // 2.挂载app
    app.mount("#app")
</script>

三、如何自定义指令

3.1 概述

通常在某些情况下,需要对DOM元素进行底层操作,这个时候就会用到自定义指令;

**自定义指令分为两种: **

自定义局部指令:组件中通过 directives 选项,只能在当前组件中使用;

自定义全局指令:通过appdirective 方法,可以在任意组件中被使用;

3.2 使用示例–使用自定义指令自动获取元素焦点

1)自定义局部指令

<template>
  <div class="app">
    <input type="text" v-focus>
  </div>
</template>

<!-- vue2 选项式api写法 -->
<script>
    export default {
        directives: {
            focus: {				// 此时指令的命名不需要加上v	
                mounted(el){ 		// 自定义指令的生命周期的函数
                    el?.focus() 	// ?.代表el存在才执行focus()
                },
            }
        }
    }
</script>

<!-- vue3 组合式api写法 -->
<script setup>
    
    // 这里的命名必须以v开头,这样在使用时才可以用v-focus
    const vFocus = {
        mounted(el){ 		// 自定义指令的生命周期的函数
            el?.focus() 	//?.代表el存在才执行focus()
        },
    }
    
</script>

2)自定义全局指令

  • directives文件夹下定义focus.js存放自定义指令:
export default function directiveFocus(app) {
  app.directive("focus", {
    mounted(el) {
      el?.focus()
    }
  })
}
  • directives文件夹下定义index.js作为指令函数统一导出入口:
// 之所以需要这个文件,是因为如果有很多个自定义指令,在main.js中一个个注册是非常难维护的
import directiveFocus from "./focus"

export default function directives(app) {
  directiveFocus(app)
}
  • 在main.js中引入
import { createApp } from 'vue'
import directives from "./directives/index"		// 导入directives文件夹下的index.js

createApp(App).use(directives).mount("#app")	// 使用use注册全部的自定义指令

一般来说,很少去自定义指令,就算是项目中有这个需求,也一般是定义全局的,方便整个项目复用

3.3 自定义指令的生命周期

一个指令定义的对象,Vue提供了如下的几个钩子函数:

created:在绑定元素的 attribute 或事件监听器被应用之前调用;

beforeMount:当指令第一次绑定到元素并且在挂载父组件之前调用;

mounted:在绑定元素的父组件被挂载后调用;

beforeUpdate:在更新包含组件的 VNode 之前调用;

updated:在包含组件的 VNode 及其子组件的 VNode 更新后调用;

beforeUnmount:在卸载绑定元素的父组件之前调用;

unmounted:当指令与元素解除绑定且父组件已卸载时,只调用一次;

3.4 指令的参数和修饰符

比如对于下面的指令用法:

v-test:info.stop = "'message'"
  • v-test:指令名称
  • info:指令参数的名称
  • stop:指令修饰符的名称
<template>
  <div class="app">
    <h2 v-test:info.abc.cba="message">我是h2的默认值</h2>
  </div>
</template>

<script setup>
const message = 'hello directive'
const vTest = {
  // el用于获得dom元素
  // bindings用于获取指令参数或者修饰符
  mounted(el, bindings) {
    /*
    	bindings对象中的arg属性  	 		可以获取到指令参数的名称 info
    	bindings对象中的value属性  		可以获取到指令参数的值 hello directive
    	bindings对象中的modifiers属性  	可以获取到指令的修饰符 abc cba
    */
    console.log(bindings)
    el.textContent = bindings.value		// 用hello directive 替换 我是h2的默认值
  }
}

</script>

四、Vue中的全部内置指令

https://cn.vuejs.org/api/built-in-directives.html
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值