Vue3---常用Vue指令集锦-及-相关demo运用

62 阅读4分钟

#完整原文地址见简书www.jianshu.com/p/7ae1901d7…



#本文内容提要

  • v-html
  • v-bind
  • 插值表达式的内容可以是js各种表达式,但不能是语句
  • v-once
  • v-on:click指令 与 v-bind指令 的简写
  • 动态属性
  • 表单 事件拦截的 简写
  • ref指令 引用 DOM节点实例【慎用,不够灵活】
  • ref指令 引用 子组件实例 及 子组件函数【慎用,不够灵活】
  • 使用provide和inject 优化 多层DOM组件的props数据传递
    • 常规的props传递方法
    • 使用provide和inject 进行优化
    • 弊端1:要使用data中的字段时候,provide需要使用函数的形式
    • 弊端2:除非使用响应式特性编程,否则无法使用双向绑定特性,数据的传输只能是一次性

##v-html

  • v-html:在指定的标签上, 通过HTML的方式展示配置的变量:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hello World! heheheheheheda</title>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="heheApp"></div>
</body>
  <script>
    const app = Vue.createApp({
        data() {
            return {
                heheString: '<strong>hello world</strong>'
            }
        },
        template: `<div v-html="heheString"></div>`
    });
    const vm = app.mount('#heheApp');
  </script>
</html>


##v-bind - **`v-bind`:`DOM标签`的某个`属性值`要使用data中的变量值的时候使用:** 没有用`v-bind`的效果: ``` Hello World! heheheheheheda
``` **图标展示的是`title`直接指定的字符串:** ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/51d83c5158864574b01835bc0181b22b~tplv-k3u1fbpfcp-zoom-1.image)
**如果使用了`v-bind`指令:** ``` Hello World! heheheheheheda
``` **UI展示的就是`v-bind`指定的`数据变量`的值:**![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d97e7b9dadee4d868c37b8f639195560~tplv-k3u1fbpfcp-zoom-1.image) **再来一例: 同样是通过`v-bind`引用data中的字段值,作为UI节点的属性值:** ``` Hello World! heheheheheheda
``` 效果:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f50b0128e2864cb8b0d064f39d730bda~tplv-k3u1fbpfcp-zoom-1.image) 将字段值改为false: ``` Hello World! heheheheheheda
``` 输入框编程可用状态:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e5f16db55786468e8240c0e75d7459c7~tplv-k3u1fbpfcp-zoom-1.image)
##插值表达式的内容可以是js各种表达式,但不能是语句 **表达式是一个有值的式子,语句则不是;** ``` Hello World! heheheheheheda
``` 效果:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/57482914bf314afdbb6e7f716b99d27e~tplv-k3u1fbpfcp-zoom-1.image)
##v-once **修饰`template`中的UI节点,使得`节点`引用`data()`字段值的时候, 只使用一次字段的值,之后,无论`data字段`怎么被修改, `节点`都不再引用其值(去重新渲染UI); !!开发中可以用于规避没必要的渲染,提高性能;** ``` Hello World! heheheheheheda
``` **效果如下,UI引用data字段的值,但是重新赋值的时候,UI不再做其字段值对应的UI渲染:**![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fd6679f6714443959e5dd93c933b0623~tplv-k3u1fbpfcp-zoom-1.image)
##v-on:click指令 与 v-bind指令 的简写 **`v-on:click =`指令 可以简写成 `@click = `; `v-bind:[var name]` 可以简写成 `:[var name]`;** 例程如下: ``` Hello World! heheheheheheda
``` 效果如下, 点击之后会触发对应的回调函数, 鼠标滞留在文本则可以看到`title`对应绑定的字段值: ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/38aa2147e42d492ca677b630a63947ec~tplv-k3u1fbpfcp-zoom-1.image)
##动态属性 在`template`的DOM节点编写中, 使用方括号`[]`指定`data`中的变量名,实现动态绑定属性; 代码:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8001ac7d69d244f385bfb25f0af41f68~tplv-k3u1fbpfcp-zoom-1.image)效果如下,属性动态绑定:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0442c5fa567741898eba1c54bf174eb4~tplv-k3u1fbpfcp-zoom-1.image)举一反三再来一例:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7f8755a3c1a84f4f8727240bfe50653b~tplv-k3u1fbpfcp-zoom-1.image)![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eb05afb8709e4707bef5ba3c0a4ab815~tplv-k3u1fbpfcp-zoom-1.image)!!!! 同理,事件绑定也可以这样搞, 首先是点击事件的例子:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/184144c279c64e058cf07beb90caaddb~tplv-k3u1fbpfcp-zoom-1.image)同样是点击文本触发事件:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/25a3380a2b684ccc9630348096d759c9~tplv-k3u1fbpfcp-zoom-1.image) 再来一例,把`click`事件改成`mouseenter`事件:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fea7e2d30c7b46a28890328667bad13e~tplv-k3u1fbpfcp-zoom-1.image)则运行之后,鼠标移动到文本DOM节点上,就会触发事件回调函数:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/cb4806097d164f2fadbc8501275c85f9~tplv-k3u1fbpfcp-zoom-1.image)
##表单 事件拦截的 简写 案例的话,我们首先写一个 可以点击跳转到`百度首页`的`表单`: ``` Hello World! heheheheheheda
``` 效果如下,点击`[提交]按钮`可以跳转到`百度首页`:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/70130873587b4869b13a5ac431160d37~tplv-k3u1fbpfcp-zoom-1.image)![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b15410b563d3474083d83066b1659f34~tplv-k3u1fbpfcp-zoom-1.image)
**常规事件拦截写法:** ``` Hello World! heheheheheheda
``` **运行效果如下,点击之后`跳转事件`无响应, 即触发`handleClick()`, 打印相关信息`console.log('你戳到我啦———— 拦截拦截!');`, 同时执行`e.preventDefault();`进行跳转事件拦截, 使得无法正常跳转:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7ee42e7754a64db2852a0d47fb19c562~tplv-k3u1fbpfcp-zoom-1.image) Vue的事件拦截简写: 在`@click`指令后加上`.prevent`修饰符, 这样的话,点击对应的组件之后, 程序会先拦截事件,接着再执行`@click`指令绑定的回调方法:** ``` Hello World! heheheheheheda
``` **运行效果如下,点击之后`跳转事件`无响应, 即触发`.prevent`修饰符(及其内在封装的事件拦截逻辑),使得无法正常跳转, 接着触发`handleClick()`, 打印相关信息`console.log('你戳到我啦———— 拦截拦截 —— .prevent!');`:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/882c3bd5228b403e87122268f100a07d~tplv-k3u1fbpfcp-zoom-1.image)**
####ref指令 引用 DOM节点实例【慎用,不够灵活】 **template中,使用`ref:[指定命名]`指令 修饰一个DOM标签, 之后可以在 该`DOM节点已经挂载好`的`生命周期回调`中, 通过`ref`指定的 `命名(字段属性)`【如下的`countDom`】, 引用到这个DOM节点实例【如下的`this.$refs.countDom`】:** 随后可以做 `更改属性值`,更新 UI相关的`属性值` 等操作; ``` Hello World! heheheheheheda
``` 运行效果:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1a230a4110724761bb8cb7d4b17d64a2~tplv-k3u1fbpfcp-zoom-1.image)![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9c849294991e4760b4915174b50839aa~tplv-k3u1fbpfcp-zoom-1.image)
####ref指令 引用 子组件实例 及 子组件函数【慎用,不够灵活】 **template中,使用`ref:[指定命名]`指令 修饰一个 `子组件引用标签`, 之后可以在 该`DOM节点已经挂载好`的`生命周期回调`中, 通过`ref`指定的 `命名(字段属性)`【如下的`hehedaDom`】, 引用到这个 `子组件实例`【如下的`this.$refs.hehedaDom`】:** 随后还可使用这个 `子组件实例`,做调用其`函数方法` 等操作;
如下, 在根组件中,使用`ref:[hehedaDom]`指定 `子组件引用标签`, 在`mounted`中,拿到其实例, `打印`该子组件实例,同时`调用其函数`: ``` ```
####使用provide和inject 优化 多层DOM组件的props数据传递 三层DOM传递时,

######常规的props传递方法:

<script>
    const app = Vue.createApp({
        data() {
            return {count: 666}
        },
        template: `
            <div>
                <child :countFromRoot="count" />
            </div>`        
    });

    app.component('child',{
        props: ['countFromRoot'],
        template: `<child-child :countFromChild="countFromRoot" />`      
    });

    app.component('child-child',{
        props: ['countFromChild'],
        template: `<div>{{countFromChild}}</div>`      
    });

    const vm = app.mount('#heheApp');
</script>

效果:

#####使用provide和inject 进行优化 只要在 提供数据 和 接收数据 的首尾两个组件中, 使用provide 和 inject 特性 控制数据传递数据即可, 至于这两个组件之间的间接组件,就无需再写数据传递的控制了:

<script>
    const app = Vue.createApp({
        data() {
            return {count: 666}
        },
        provide: {
            myCount: 8888
        },
        template: `
            <div>
                <child :countFromRoot="count" />
            </div>`        
    });

    app.component('child',{
        template: `<child-child />`      
    });

    app.component('child-child',{
        inject: ['myCount'],
        template: `<div>{{myCount}}</div>`      
    });

    const vm = app.mount('#heheApp');
</script>

运行效果:


######弊端1:要使用`data`中的字段时候,`provide`需要使用函数的形式 ``` ``` 运行效果:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/27d538697c2a48eeb237ba6b0639e639~tplv-k3u1fbpfcp-zoom-1.image)
######弊端2:除非使用`响应式特性`编程,否则无法使用`双向绑定`特性,数据的传输只能是`一次性`的 ``` ``` **运行效果,一直点击按钮跌家`provide`组建的数据,但是`inject`组件没反应, 因为数据的传输只能是`一次性`的:![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/23d28e5f45a340498690152bc8b764c5~tplv-k3u1fbpfcp-zoom-1.image)**
####