玩转动态指令
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
函数中定义两个变量分别为 num
、arr
。
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
中,key1
跟 key2
可以拼接成 key3
,同样可以使用 [key1+key2]
动态计算。
let key1 = "nam";
let key2 = "e";
let key3 = key1 + key2;
let obj1 = {
[key1 + key2]: "Ken",
};
let obj2 = {
[key3]: "Ken",
};
在 vue
中,是不是可以这样写呢?
我们先来定义两个变量,key1
,key2
,然后使用 [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 动态指令