举报投诉联系我们 手机版 热门标签 VUE中文网
您的位置:VUE中文网 > vue自定义指令实现 Vue 3.0 自定义指令

vue自定义指令实现 Vue 3.0 自定义指令

2023-02-27 03:17 VUE3教程

vue自定义指令实现 Vue 3.0 自定义指令

vue自定义指令实现

Vue.js 是一个构建数据驱动的 web 界面的库,它可以帮助开发者快速构建出功能丰富的 web 应用。Vue.js 提供了一种自定义指令的方式来扩展 HTML 元素的行为,这样可以让我们在不修改核心代码的情况下,实现一些特定的功能。

Vue.js 自定义指令是一个函数,该函数接受三个参数:el、binding、vnode。el 参数代表当前 DOM 元素;binding 参数包含了一些属性信息;vnode 参数包含 Vue 编译生成的虚拟节点。

要使用 Vue.js 自定义指令,首先要在 Vue 实例中注册该指令。我们可以使用 Vue.directive() 方法来注册自定义指令:

Vue.directive('my-directive', {
  bind(el, binding, vnode) {
    // 这里可以处理 DOM 绑定阶段的逻辑
  },

  inserted(el, binding, vnode) {
    // 这里可以处理 DOM 插入阶段的逻辑
  },

  update(el, binding, vnode) {
    // 这里可以处理 DOM 更新阶段的逻辑
  },

  componentUpdated(el, binding, vnode) {
    // 这里可以处理组件更新阶段的逻辑
  },

  unbind(el, binding, vnode) {
    // 这里可以处理 DOM 解绑阶段的逻辑  
  }  
});

上述代码中,我们使用 Vue.directive() 方法来注册一个名为 my-directive 的自定义指令。该方法有五个回调函数 bind、inserted、update、componentUpdated、unbind (如上所述)分别在不同生命周期中执行相应的回调函数。

当我们在 HTML 页面中使用 my-directive 时(如

))会首先触发 bind 回调函数(即 el、binding、vnode 参数都会传入 bind 回调函数中去执行相应逻辑)。随后会逐步执行 inserted、update、componentUpdated 等回调函数。最后当 my-directive 失去作用时会执行 unbind 回调函数来停止相应逻辑。

#简介

除了核心功能默认内置的指令 (v-modelv-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。举个聚焦输入框的例子,如下:

点击此处实现

当页面加载时,该元素将获得焦点 (注意:autofocus 在移动版 Safari 上不工作)。事实上,只要你在打开这个页面后还没点击过任何内容,这个输入框就应当还是处于聚焦状态。此外,你可以单击 Rerun 按钮,输入将被聚焦。

现在让我们用指令来实现这个功能:

const app = Vue.createApp({})
// 注册一个全局自定义指令 `v-focus`
app.directive("focus", {
  // 当被绑定的元素插入到 DOM 中时……
  mounted(el) {
    // Focus the element
    el.focus()
  }
})

如果想注册局部指令,组件中也接受一个 directives 的选项:

directives: {
  focus: {
    // 指令的定义
    mounted(el) {
      el.focus()
    }
  }
}

然后你可以在模板中任何元素上使用新的 v-focus property,如下:

<input v-focus />

#钩子函数

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

  • beforeMount:当指令第一次绑定到元素并且在挂载父组件之前调用。在这里你可以做一次性的初始化设置。
  • mounted:在挂载绑定元素的父组件时调用。
  • beforeUpdate:在更新包含组件的 VNode 之前调用。

提示

我们会在稍后讨论渲染函数时介绍更多 VNodes 的细节。

  • updated:在包含组件的 VNode 及其子组件的 VNode 更新后调用。
  • beforeUnmount:在卸载绑定元素的父组件之前调用
  • unmounted:当指令与元素解除绑定且父组件已卸载时,只调用一次。

接下来我们来看一下在自定义指令 API 钩子函数的参数 (即 elbindingvnodeprevNnode)

#动态指令参数

指令的参数可以是动态的。例如,在 v-mydirective:[argument]="value" 中,argument 参数可以根据组件实例数据进行更新!这使得自定义指令可以在应用中被灵活使用。

例如你想要创建一个自定义指令,用来通过固定布局将元素固定在页面上。我们可以像这样创建一个通过指令值来更新竖直位置像素值的自定义指令:

<div id="dynamic-arguments-example" class="demo">
  <p>Scroll down the page</p>
  <p v-pin="200">Stick me 200px from the top of the page</p>
</div>

const app = Vue.createApp({})


app.directive("pin", {
  mounted(el, binding) {
    el.style.position = "fixed"
    // binding.value is the value we pass to directive - in this case, it"s 200
    el.style.top = binding.value + "px"
  }
})


app.mount("#dynamic-arguments-example")

这会把该元素固定在距离页面顶部 200 像素的位置。但如果场景是我们需要把元素固定在左侧而不是顶部又该怎么办呢?这时使用动态参数就可以非常方便地根据每个组件实例来进行更新。

<div id="dynamicexample">
  <h3>Scroll down inside this section ↓</h3>
  <p v-pin:[direction]="200">I am pinned onto the page at 200px to the left.</p>
</div>

const app = Vue.createApp({
  data() {
    return {
      direction: "right"
    }
  }
})


app.directive("pin", {
  mounted(el, binding) {
    el.style.position = "fixed"
    // binding.arg is an argument we pass to directive
    const s = binding.arg || "top"
    el.style[s] = binding.value + "px"
  }
})


app.mount("#dynamic-arguments-example")

结果:

点击此处实现

我们的定制指令现在已经足够灵活,可以支持一些不同的用例。为了使其更具动态性,我们还可以允许修改绑定值。让我们创建一个附加属性 pinPadding,并将其绑定到 <input type="range">

<div id="dynamicexample">
  <h2>Scroll down the page</h2>
  <input type="range" min="0" max="500" v-model="pinPadding">
  <p v-pin:[direction]="pinPadding">Stick me {{ pinPadding + "px" }} from the {{ direction }} of the page</p>
</div>

const app = Vue.createApp({
  data() {
    return {
      direction: "right",
      pinPadding: 200
    }
  }
})

让我们扩展我们的指令逻辑来重新计算固定元件更新的距离。

app.directive("pin", {
  mounted(el, binding) {
    el.style.position = "fixed"
    const s = binding.arg || "top"
    el.style[s] = binding.value + "px"
  },
  updated(el, binding) {
    const s = binding.arg || "top"
    el.style[s] = binding.value + "px"
  }
})

结果:

点击此处实现

#函数简写

在很多时候,你可能想在 mountedupdated 时触发相同行为,而不关心其它的钩子。比如这样写:

app.directive("pin", (el, binding) => {
  el.style.position = "fixed"
  const s = binding.arg || "top"
  el.style[s] = binding.value + "px"
})

#对象字面量

如果指令需要多个值,可以传入一个 JavaScript 对象字面量。记住,指令函数能够接受所有合法的 JavaScript 表达式。

<div v-demo="{ color: "white", text: "hello!" }"></div>

app.directive("demo", (el, binding) => {
  console.log(binding.value.color) // => "white"
  console.log(binding.value.text) // => "hello!"
})

#在组件中使用

在 3.0 中,有了片段支持,组件可能有多个根节点。如果在具有多个根节点的组件上使用自定义指令,则会产生问题。

要解释自定义指令如何在 3.0 中的组件上工作的详细信息,我们首先需要了解自定义指令在 3.0 中是如何编译的。对于这样的指令:

<div v-demo="test"></div>

将大概编译成:

const vDemo = resolveDirective("demo")


return withDirectives(h("div"), [[vDemo, test]])

其中 vDemo 是用户编写的指令对象,其中包含 mountedupdated 等钩子。

withDirectives 返回一个克隆的 VNode,其中用户钩子被包装并作为 VNode 生命周期钩子注入 (请参见渲染函数更多详情):

{
  onVnodeMounted(vnode) {
    // call vDemo.mounted(...)
  }
}

因此,自定义指令作为 VNode 数据的一部分完全包含在内。当在组件上使用自定义指令时,这些 onVnodeXXX 钩子作为无关的 prop 传递给组件,并以 this.$attrs 结束

这也意味着可以像这样在模板中直接挂接到元素的生命周期中,这在涉及到自定义指令时非常方便:

<div @vnodeMounted="myHook" />

这和 非 prop 的 attribute类似。因此,组件上自定义指令的规则将与其他无关 attribute 相同:由子组件决定在哪里以及是否应用它。当子组件在内部元素上使用 v-bind="$attrs" 时,它也将应用对其使用的任何自定义指令。

阅读全文
以上是VUE中文网为你收集整理的vue自定义指令实现 Vue 3.0 自定义指令全部内容。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。
相关文章
  • vue 3.0 teleport

    vue 3.0 teleport

    2023-02-26 VUE3教程

    Vue 鼓励我们通过将 UI 和相关行为封装到组件中来构建 UI。我们可以将它们嵌套在另一个内部,以构建一个组成应用程序 UI 的树。...

  • vue插件大全 Vue 3.0 插件

    vue插件大全 Vue 3.0 插件

    2023-02-23 VUE3教程

    插件是自包含的代码,通常向 Vue 添加全局级功能。它可以是公开 install() 方法的 object,也可以是 function插件的功能范围没有...

  • vue3.0入门 Vue 3.0 基础

    vue3.0入门 Vue 3.0 基础

    2023-02-25 VUE3教程

    Web 可访问性 (也称为 a11y) 是指创建可供任何人使用的网站的实践方式——无论是身患某种障碍、通过慢速的网络连接访问、使用老...

  • vue 资源路径 Vue 3.0 资源

    vue 资源路径 Vue 3.0 资源

    2023-02-26 VUE3教程

    #文档WCAG 2.0WCAG 2.1可访问的富 Internet 应用程序 (WAI-ARIA) 1.2WAI-ARIA 创作实践 1.2#辅助技术屏幕阅读器NVDAVoiceOver[JA...

  • vue给元素添加自定义属性 Vue 3.0 自定义元素交互

    vue给元素添加自定义属性 Vue 3.0 自定义元素交互

    2023-02-26 VUE3教程

    #概览非兼容:自定义元素白名单现在在模板编译期间执行,应该通过编译器选项而不是运行时配置来配置。非兼容:特定 is prop 用法...

© 2024 VUE中文网 vue88.com 版权所有 联系我们