Ashun's 技術駅 Ashun's 技術駅
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • Vue
  • 现代web布局
  • React
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 技术资源
  • 第一阶段

    • HTML
  • 第二阶段

    • JavaScript
  • 第三阶段

    • Vue
  • 第四阶段

    • 实战项目
  • 每周测试

    • 每周
  • 其他

    • Vue引入UI框架
    • Web前端面试
    • Vue3-resource
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 福利资源
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Ashun

前端界的小学生
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • HTML
  • CSS
  • Vue
  • 现代web布局
  • React
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 技术资源
  • 第一阶段

    • HTML
  • 第二阶段

    • JavaScript
  • 第三阶段

    • Vue
  • 第四阶段

    • 实战项目
  • 每周测试

    • 每周
  • 其他

    • Vue引入UI框架
    • Web前端面试
    • Vue3-resource
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 福利资源
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 01mvvm和mvc
  • 02安装和使用
  • 03模版语法
  • 04生命周期
  • 05指令
  • 06方法-计算属性-监听器
  • 07class和style绑定
  • 08条件渲染
  • 09列表渲染
  • 10事件处理
  • 11表单输入绑定
  • 12组件
  • 13组件之间传递数据
  • 14props验证
  • 15插槽
  • 16动态组件
  • 17处理边界情况
  • 18脚手架
  • 19Vuex
  • 20VueRouter
  • 21自定义指令
    • 一、创建自定义指令
    • 二、钩子函数
    • 三、钩子函数参数
    • 四、函数传参
    • 五、截流函数
    • 六、页面切换
      • 首先安装路由
  • 22渲染函数
  • 23插件
  • 24VueConfig
  • 《Vue》
xugaoyi
2022-02-16
目录

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

# 二、钩子函数

bind; //父组件未加载时调用

inserted; //父组件加载完毕时调用

update; //更新组件前调用

componentUpdated; //更新组件后调用

unbind; //组件销毁时调用
1
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

练习

<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

# 四、函数传参

<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

练习 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

<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

练习 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

# 五、截流函数

<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

练习

// 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

# 六、页面切换

优化练习

# 首先安装路由

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

温馨提示:创建路由对应的文件——比如: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
// 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
// src/App.vue
<router-view></router-view>

//import home from "@/views/home.vue"
//components:{
//   home,
//},
1
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
编辑 (opens new window)
上次更新: 2023/08/06, 00:38:41
20VueRouter
22渲染函数

← 20VueRouter 22渲染函数→

最近更新
01
课件-react路由-V6
01-22
02
课件-国际化
01-22
03
课件-redux-toolkit
01-22
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式