4-玩转动态指令


玩转动态指令

1、知识点

Vue 具有模板编译功能,模板编译生成渲染函数。通过执行渲染函数生成最新的虚拟节点,最后根据虚拟节点进行渲染,编译过程中包含对指令的解析 。

  • 模板插值
  • JavaScript 表达式
  • 动态指令
  • 动态指令计算

2、模板插值

插值,是 Vue.js 数据绑定最基本形式,使用 Mustache 语法,也就是双花括号 {{}}

首先在 src/views 中新建 DynamicArguments.vue,引入响应式计算方法 ref,定义变量 msg

<template>
  <div class="dynamic-arguments">
    <h2>
      模板插值
      <br />
      <input v-model="msg" type="text" />
      <br />
      {{ msg }}
    </h2>
  </div>
</template>

<script>
  import { ref } from "vue";
  export default {
    name: "DynamicArguments",
    setup() {
      let msg = ref("旅行包都买好了,就差一个时机了");
      return {
        msg,
      };
    },
  };
</script>

<style scoped>
  input {
    width: 300px;
  }
</style>

接着在 src/router/index.js 注册路由。

{
    path: '/dynamicArguments',
    name: 'DynamicArguments',
    component: () => import ('../views/DynamicArguments.vue')
}

最后在 src/App.vue 添加 router-view,来控制路由跳转。

<router-link to="/dynamicArguments">DynamicArguments</router-link>

运行 npm run serve 之后,效果如下图:

图片描述

JavaScript 表达式

目前为止,Vue 是支持 JavaScript 中所有表达式的插值使用的。比如像数组操作,字符串操作等。

在上面代码的基础上,我们先在 setup 函数中定义两个变量分别为 numarr

setup() {
   let msg = ref("旅行包都买好了,就差一个时机了");
   let num = ref(0);
   let arr = ref(['zhangsan', '前端开发', 'Python100天'])
   return {
       msg,
       num,
       arr
   }
}

在模板中进行数值计算,字符串分割,数组元素操作。

<h2>
  JavaScript 表达式
  <br />
  字符串 split 操作:{{ msg.split(",")[0] }}
  <br />
  数值计算:{{ num + 1 }}
  <br />
  数组操作:{{ arr[0] }}
</h2>

效果如下图所示:

图片描述

3、动态指令

Vue3 新增了动态指令,简单来说就是我们可以通过定义变量来控制指令的名字,这样可以提高指令操作效率,提高代码可读性。

动态指令有点类似定义变量:

let key = "name";
let obj = {
  [key]: "zhangsan",
};

上面这串代码中的 [key] 会被解析成为 name

v-bind:[varName] 绑定变量

在 Vue 中,我们可以使用 v-bind 来绑定属性。

setup 函数中定义一个 a 变量,将 a 变量绑定在 href 属性上。

<template>
  <h2>
    v-bind: 绑定属性
    <br />
    <a v-bind:href="a">mqxu.top</a>
  </h2>
</template>
<script>
  import { ref } from "vue";
  export default {
    name: "DynamicArguments",
    setup() {
      let a = "syhan.top";
      return {
        a,
      };
    },
  };
</script>

运行效果如下:

图片描述

我们使用变量来替换 href 属性,在 setup 函数中定义一个 urlKey 变量,然后通过 [urlKey] 解析变量。

<template>
  <h2>
    v-bind: 绑定属性
    <br />
    <a v-bind:[urlKey]="a">mqxu.top</a>
  </h2>
</template>
<script>
  import { ref } from "vue";
  export default {
    name: "DynamicArguments",
    setup() {
      let a = ref("mqxu.top");
      let urlKey = ref("href");
      return {
        a,
        urlKey,
      };
    },
  };
</script>

v-bind:[varName] 简写模式

在简写模式中,我们可以将 v-bind 去掉,只剩下 :[varName]

<template>
  <div class="dynamic-arguments">
    <h2>
      v-bind: 简写模式
      <br />
      <a :[urlKey]="a">aaa.com</a>
    </h2>
  </div>
</template>

<script>
  import { ref } from "vue";
  export default {
    name: "DynamicArguments",
    setup() {
      let a = ref("aaa.com");
      let urlKey = ref("href");
      return {
        urlKey,
        a,
      };
    },
  };
</script>

v-on:[handlerEventName] 绑定事件名变量

我们可以设计一个计数器,在 setup 函数定义一个 num 变量,初始化值为 0,定义方法来操作这个变量。

<template>
  <div class="dynamic-arguments">
    <h2>
      v-on:[handlerEventName] 绑定事件名变量
      <br />
      <button v-on:click="increase">{{num}}</button>
    </h2>
  </div>
</template>

<script>
  import { ref } from "vue";
  export default {
    name: "DynamicArguments",
    setup() {
      let num = ref(0);
      const increase = () => {
        num.value++;
      };
      return {
        num,
        increase,
      };
    },
  };
</script>

当然,我们也可以使用变量来定义事件名字。在 setup 函数中定义一个点击事件名字。代码如下:

<template>
  <div class="dynamic-arguments">
    <h2>
      v-on:[handlerEventName] 绑定事件名变量
      <br />
      <button v-on:[clickEventName]="increase">{{ num }}</button>
    </h2>
  </div>
</template>

<script>
  import { ref } from "vue";
  export default {
    name: "DynamicArguments",
    setup() {
      let num = ref(0);
      let clickEventName = ref("click");
      const increase = () => {
        num.value++;
      };
      return {
        num,
        clickEventName,
        increase,
      };
    },
  };
</script>

我们还可以使用 @[clickEventName] 提高效率,减少代码量

<template>
  <div class="dynamic-arguments">
    <h2>
      v-on:[handlerEventName] 简写模式
      <br />
      <button @[clickEventName]="increase">{{num}}</button>
    </h2>
  </div>
</template>

<script>
  import { ref } from "vue";
  export default {
    name: "DynamicArguments",
    setup() {
      let num = ref(0);
      let clickEventName = ref("click");
      const increase = () => {
        num.value++;
      };
      return {
        num,
        clickEventName,
        increase,
      };
    },
  };
</script>

效果一样。

v-slot:[slotName] 具名插槽

src/views 新建 aaa.vue

<template>
  <div class="child">
    <h2>子元素</h2>
  </div>
</template>

<script>
  export default {
    name: "child",
  };
</script>

接着在 src/views 新建 bbb.vue,使用 slot 具名插槽为子组件占住位置。

<template>
  <div class="parent">
    <h1>父级元素</h1>
    <slot name="child"></slot>
  </div>
</template>

<script>
  export default {
    name: "parent",
  };
</script>

将上面两个组件引入到 src/views/DynamicArguments.vue 中。

<template>
  <div class="dynamic-arguments">
    <h2>
      v-slot:[slotName] 具名插槽
      <parent>
        <template v-slot:child>
          <child></child>
        </template>
      </parent>
    </h2>
  </div>
</template>

<script>
  import parent from "./bbb";
  import child from "./aaa";
  export default {
    name: "DynamicArguments",
    components: {
      parent,
      child,
    },
    setup() {
      return {};
    },
  };
</script>

运行效果如下:

图片描述

我们也可以使用动态变量来设置插槽名字。

使用 ref 定义一个响应式变量 child,然后通过 [child] 的方式来绑定插槽的名字。

<template>
  <div class="dynamic-arguments">
    <h2>
      v-slot:[slotName] 具名插槽
      <parent>
        <template v-slot:[child]>
          <child></child>
        </template>
      </parent>
    </h2>
  </div>
</template>

<script>
  import parent from "./bbb";
  import child from "./aaa";
  export default {
    name: "DynamicArguments",
    components: {
      parent,
      child,
    },
    setup() {
      let child = ref("child");
      return {
        child,
      };
    },
  };
</script>

运行效果一样。

接下来我们通过使用 #slotName 的方式给插槽进行标志。

<template>
  <div class="dynamic-arguments">
    <h2>
      #[slotName] 简写模式
      <parent>
        <template #[child]>
          <child></child>
        </template>
      </parent>
    </h2>
  </div>
</template>

<script>
  import parent from "./bbb";
  import child from "./aaa";
  export default {
    name: "DynamicArguments",
    components: {
      parent,
      child,
    },
    setup() {
      let child = ref("child");
      return {
        child,
      };
    },
  };
</script>

运行效果

图片描述

4、动态指令计算

字符串可以互相拼接,数值可以相加,相乘等操作。动态指令也能做这些操作。在 javascript 中,key1key2 可以拼接成 key3,同样可以使用 [key1+key2] 动态计算。

let key1 = "nam";
let key2 = "e";
let key3 = key1 + key2;
let obj1 = {
  [key1 + key2]: "Ken",
};
let obj2 = {
  [key3]: "Ken",
};

图片描述

vue 中,是不是可以这样写呢?

我们先来定义两个变量,key1key2,然后使用 [key1+key2] 来拼接字符串变量。

<template>
  <div class="dynamic-arguments">
    <h2>
      动态指令计算
      <br />
      <a v-bind:[key1 + key2]="a">aaa.com</a>
    </h2>
  </div>
</template>

<script>
  import { ref } from "vue";
  export default {
    name: "DynamicArguments",
    setup() {
      let key1 = ref("nam");
      let key2 = ref("e");
      return {
        key1,
        key2,
      };
    },
  };
</script>

运行 npm run serve 之后,发现控制台报错了,说明 Vue 不能这样使用。

5、总结

学习了以下知识点:

  • v-bind 动态指令
  • v-on 动态指令
  • v-slot 动态指令

文章作者: Syhan
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Syhan !
评论
  目录