前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Vue3 从入门到实战 进阶式掌握完整知识体系】025-Vue中的高级语法:自定义vue指令

【Vue3 从入门到实战 进阶式掌握完整知识体系】025-Vue中的高级语法:自定义vue指令

作者头像
訾博ZiBo
发布2025-01-06 14:16:55
发布2025-01-06 14:16:55
11300
代码可运行
举报
运行总次数:0
代码可运行

2、自定义vue指令

使用ref获焦点

可以通过 ref 获得 DOM ,然后操作 DOM 实现获取焦点

代码语言:javascript
代码运行次数:0
运行
复制
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>hello vue</title>
  <!-- 引入Vue库 -->
  <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
  <div id="root"></div>
</body>

<script>

  const app = Vue.createApp({
    mounted(){
      this.$refs.input.focus();
    },
    template: `
        <div>
          <input ref="input" />
        </div>
    `
  });


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

</html>
运行结果

使用ref也能实现,但无法复用!

image-20210614104922045.png
image-20210614104922045.png
自定义指令实现获取焦点
代码语言:javascript
代码运行次数:0
运行
复制
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>hello vue</title>
  <!-- 引入Vue库 -->
  <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
  <div id="root"></div>
</body>

<script>

  const app = Vue.createApp({
    // 使用 v-focus
    template: `
        <div>
          <input v-focus />
        </div>
    `
  });

  // 自定义指令
  app.directive("focus",{
    // 时间:2021年06月15日 16时39分43秒
    // 这里接收一个参数,参数就是 DOM 节点
    mounted(el){
      el.focus();
    }
  });

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

</html>
运行结果
image-20210614105243711.png
image-20210614105243711.png
局部自定义指令

类似组件、mixin,上面是全局自定义指令,我们来写一个局部自定义指令(写法有差异)

代码语言:javascript
代码运行次数:0
运行
复制
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>hello vue</title>
  <!-- 引入Vue库 -->
  <script src="https://unpkg.com/vue@next"></script>
</head>

<body>
  <div id="root"></div>
</body>

<script>

  // 局部自定义指令
  const directives = {
    focus: {
      mounted(el){
        el.focus();
      }
    }
  }

  const app = Vue.createApp({
    // 引入自定义指令
    // 理论写法
    // directives: directives,
    // 解构写法(简化)
    directives,
    // 使用 v-focus
    template: `
        <div>
          <input v-focus />
        </div>
    `
  });

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

</html>
运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2JgpKwtB-1625061243455)(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/06c7ba050c314771a39f6347c15e8b65~tplv-k3u1fbpfcp-watermark.image)]

说明

我们上面使用了生命周期函数 mounted ,实际上其他的生命周期函数也可以使用在自定义指令里面

带属性值的自定义指令
代码语言:javascript
代码运行次数:0
运行
复制
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>hello vue</title>
  <!-- 引入Vue库 -->
  <script src="https://unpkg.com/vue@next"></script>
  <!-- 样式 -->
  <style>
    .header{
      position: absolute;
    }
  </style>
</head>

<body>
  <div id="root"></div>
</body>

<script>

  // 局部自定义指令
  const directives = {
    pos: {
      mounted(el, binding){
        el.style.top = binding.value + 'px';
      }
    }
  }

  const app = Vue.createApp({
    // 引入自定义指令
    directives,
    // 使用 v-pos
    template: `
        <div v-pos='50' class="header">
          <input />
        </div>
    `
  });

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

</html>
运行结果
image-20210614110924832.png
image-20210614110924832.png
修改数据并使数据生效
代码语言:javascript
代码运行次数:0
运行
复制
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>hello vue</title>
  <!-- 引入Vue库 -->
  <script src="https://unpkg.com/vue@next"></script>
  <!-- 样式 -->
  <style>
    .header{
      position: absolute;
    }
  </style>
</head>

<body>
  <div id="root"></div>
</body>

<script>

  // 局部自定义指令
  const directives = {
    pos: {
      // mounted只会执行一次,因此 data 里面的 top 改变不会反映到页面上
      mounted(el, binding){
        el.style.top = binding.value + 'px';
      },
      // 我们写一个 updated 生命周期函数
      updated(el, binding){
        el.style.top = binding.value + 'px';
      }
    }
  }

  const app = Vue.createApp({
    // 引入自定义指令
    directives,
    // 使用数据代替 50
    data(){
      return {
        top: 60
      }
    },
    // 使用 v-pos
    template: `
        <div v-pos='top' class="header">
          <input />
        </div>
    `
  });

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

</html>
运行结果
image-20210614111541278.png
image-20210614111541278.png
简写
代码语言:javascript
代码运行次数:0
运行
复制
// 下面写法1等价于写法2,只要这两种等价,再加生命周期函数就不等价了
// 写法1
app.directive("focus", (el, binding) => {
    el.style.top = binding.value + 'px';
});

// 写法2
app.directive("focus",{
    mounted(el, binding){
        el.style.top = binding.value + 'px';
    },
    updated(el, binding){
        el.style.top = binding.value + 'px';
    }
});
自定义指令的属性

类似 v-ops:abc,abc即是属性,下面我们来看看如何获取这个abc

代码语言:javascript
代码运行次数:0
运行
复制
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>hello vue</title>
  <!-- 引入Vue库 -->
  <script src="https://unpkg.com/vue@next"></script>
  <!-- 样式 -->
  <style>
    .header{
      position: absolute;
    }
  </style>
</head>

<body>
  <div id="root"></div>
</body>

<script>

  // 局部自定义指令
  const directives = {
    pos: {
      mounted(el, binding){
        console.log(binding);
        console.log(binding.arg);
        el.style.top = binding.value + 'px';
      },
    }
  }

  const app = Vue.createApp({
    // 引入自定义指令
    directives,
    // 使用数据代替 50
    data(){
      return {
        top: 60
      }
    },
    // 使用 v-pos
    template: `
        <div v-pos:abc='top' class="header">
          <input />
        </div>
    `
  });

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

</html>
运行结果
image-20210614112247871.png
image-20210614112247871.png
优化上面的距离设置
代码语言:javascript
代码运行次数:0
运行
复制
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>hello vue</title>
  <!-- 引入Vue库 -->
  <script src="https://unpkg.com/vue@next"></script>
  <!-- 样式 -->
  <style>
    .header{
      position: absolute;
    }
  </style>
</head>

<body>
  <div id="root"></div>
</body>

<script>

  // 局部自定义指令
  const directives = {
    pos: {
      mounted(el, binding){
        el.style[binding.arg] = binding.value + 'px';
      },
    }
  }

  const app = Vue.createApp({
    // 引入自定义指令
    directives,
    // 使用数据代替 50
    data(){
      return {
        top: 60
      }
    },
    // 使用 v-pos
    template: `
        <div v-pos:left='top' class="header">
          <input />
        </div>
    `
  });

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

</html>
运行结果

我们把left改成right等,也能够实现同样的效果!

image-20210614112540115.png
image-20210614112540115.png
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2、自定义vue指令
    • 使用ref获焦点
    • 运行结果
    • 自定义指令实现获取焦点
    • 运行结果
    • 局部自定义指令
    • 运行结果
    • 说明
    • 带属性值的自定义指令
    • 运行结果
    • 修改数据并使数据生效
    • 运行结果
    • 简写
    • 自定义指令的属性
    • 运行结果
    • 优化上面的距离设置
    • 运行结果
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档