21自定义指令
# 自定义指令
# 一、创建自定义指令
<input type="text" v-focus>
export default {
name: 'App',
directives:{
focus:{//自定义指令的名称
inserted(el){//生命周期,代表渲染后执行,类似于mounted
el.focus()//el是添加了该指令的元素
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 二、钩子函数
bind; //父组件未加载时调用
inserted; //父组件加载完毕时调用
update; //更新组件前调用
componentUpdated; //更新组件后调用
unbind; //组件销毁时调用
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 三、钩子函数参数
<template>
<div id="app">
<input type="text" v-focus:click.self="1+1" />
</div>
</template>
<script>
export default {
name: "App",
directives: {
focus: {
inserted(el,binding) {
el.focus();
el.style.background="red" //背景颜色
console.log(binding);//指令详情
console.log(binding.name);//指令名称(不包含v-)
console.log(binding.value);//1+1=2
console.log(binding.expression);//1+1
console.log(binding.arg);//click
console.log(binding.modifiers);//self
let arg=binding.arg
if(arg==="click"){
el.onclick=function(){
document.querySelector("body").style.background="red"; //鼠标点击选框,背景为红色
}
}
},
},
},
};
</script>
el //指令所绑定的元素,可以用来直接操作 DOM 。
binding
name //指令名,不包括 v- 前缀。
value //指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
oldValue //指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
expression //字符串形式的指令表达式。例如 v-my-directive="1 + 1"中,表达式为 "1 + 1"。
arg //传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。
modifiers //一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。
vnode //Vue 编译生成的虚拟节点。
oldVnode //上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
动态指令参数 //v-mydirective:argument=[dataproperty]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
练习
<template>
<div id="app">
<input type="text" v-mydirective:mouseover="'red'" />
</div>
</template>
<script>
export default {
name: "App",
directives: {
mydirective: {
inserted(el, binding) {
el[`on${binding.arg}`] = function () {
el.style.background = binding.value;//鼠标点击选框,选框内为红色
};
},
},
},
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 四、函数传参
<div v-test="fn(1)">内容</div>;
export default {
name: "App",
directives: {
test: {
inserted(el, binding) {
console.log(binding.value);
},
},
},
methods: {
fn(num) {
return num;
},
},
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
练习 1
<input type="text" v-mydirective="fn(123)" />; //网页刷新就打印出来123了
//钩子函数参数
export default {
name: "App",
methods: {
fn(arg) {
return arg;
},
},
directives: {
mydirective: {
inserted(el, binding) {
console.log(binding.value);
},
},
},
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
练习 2
<input type="text" v-mydirective="fn(1)" />; //鼠标点击的时候就触发效果=2
//钩子函数参数
export default {
name: "App",
methods: {
fn(arg) {
return arg;
},
},
directives: {
mydirective: {
inserted(el, binding) {
el[`on${binding.arg}`] = function () {
console.log(binding.value);
};
},
},
},
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
练习 3
<input type="text" v-mydirective:click="fn(1)" />; //鼠标点击的时候就触发效果=2
//钩子函数参数
export default {
name: "App",
methods: {
fn(arg) {
return function () {
console.log(1 + arg);
};
},
},
directives: {
mydirective: {
inserted(el, binding) {
el[`on${binding.arg}`] = function () {
binding.value();
};
},
},
},
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 五、截流函数
<div v-throttle:click="{ handlerFn: fn, delayTime: 3000, instance: this }">
内容
</div>;
export default {
name: "App",
directives: {
throttle: {
inserted: (el, binding) => {
let eventHanlder = binding.arg; //事件
let eventHandlerFn = binding.value.handlerFn; //执行的函数
let delayTime = binding.value.delayTime; //延迟时间
let self = binding.value.instance._self; //获取当前组件
let handler = self.throttle(eventHandlerFn, delayTime);
el.addEventListener(eventHanlder, handler);
},
},
},
methods: {
throttle(fn, time) {
//节流函数
let endTime = 0;
return function () {
let nowTime = +new Date();
if (nowTime - endTime > time) {
fn();
endTime = nowTime;
}
};
},
fn() {
console.log(123);
},
},
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
练习
// src/App.vue
<input type="text" v-mythrottle:click="{ fn, time: 2000 }" />;
// src/directives/mythrottle.js
import Vue from "vue";
import { throttle } from "../utils/throttle.js";
Vue.directive("mythrottle", {
inserted(el, binding) {
let f = binding.value.fn; //传入的函数
let time = binding.value.time; //传入的时间
let event = binding.arg; //传入的事件类型
let callback = throttle(f, time);
el.addEventListener(event, callback);
},
});
// src/utils/throttle.js
export const throttle = (fn, time) => {
let endTime = 0;
return function () {
let nowTime = Date.now();
if (nowTime - endTime >= time) {
fn();
endTime = nowTime;
}
};
};
// src/main.js
import "@/directives/mythrottle.js"; //全局指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 六、页面切换
优化练习
# 首先安装路由
npm i vue-router -S
1
// src/router/index.js
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
export const router = new VueRouter({
routes: [
{
path: "/",
component: () => import("@/views/home.vue"),
},
{
path: "/list",
component: () => import("@/views/list.vue"),
},
{
path: "/shop",
component: () => import("@/views/shop.vue"),
},
],
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
温馨提示:创建路由对应的文件——比如:
src/views/home.vue
// src/views/home.vue
<div>
首页
<router-link to="/list">去列表页</router-link>
<button v-goback>返回上一页</button>
</div>
// src/views/list.vue
<div>
列表
<router-link to="/shop">去购物车页</router-link>
<button v-goback>返回上一页</button>
</div>
// src/views/home.vue
<div>
购物车
<router-link to="/shop">去首页页</router-link>
<button v-goback>返回上一页</button>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// src/main.js
import { router } from "@/router/index.js";
new Vue({
router,
render: (h) => h(App),
}).$mount("#app");
1
2
3
4
5
6
7
2
3
4
5
6
7
// src/App.vue
<router-view></router-view>
//import home from "@/views/home.vue"
//components:{
// home,
//},
1
2
3
4
5
6
7
2
3
4
5
6
7
js 文件
// src/directives/goBack.js
import Vue from "vue";
import { router } from "@/router/index.js";
Vue.directive("goback", {
inserted(el) {
el.onclick = function () {
router.go(-1);
};
},
});
// src/main.js
import "@/directives/goBack.js"; //返回上一步指令
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
编辑 (opens new window)
上次更新: 2023/08/06, 00:38:41