内置的指令 v-model , v-show

钩子函数

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

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

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

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind:只调用一次,指令与元素解绑时调用。

接下来我们来看一下钩子函数的参数 (即 el、binding、vnode 和 oldVnode)。

钩子函数参数

指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM。
  • binding:一个对象,包含以下 property:
    • 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 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

    除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。

自定义指令应用

在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。
你可以将一些 css 样式抽象到指令中,也可以将一些 js 操作放到指令中去执行。就使用上来说,指令不用像组件一样需要引入和注册,注册后使用非常简洁方便。

图片加载之占位图片

v-imgsrc=”XXX”, 该XXX是真正的图片路径
data-initsrc=”XXX”, 该XXX是在真正的图片资源到达前所有展示的占位图片

  1. import Vue from 'vue'
  2. const initImg = requir("@/assets/images/initImg.png")
  3. Vue.directive('imgsrc', {
  4. bind: function (el, binding, vnode) { // 被绑定
  5. let initImg = el.getAttribute('data-initsrc') || vnode.context.Global.errorImg
  6. el.src = initImg // 初始化图片
  7. let Img = new Image()
  8. if (!binding.value) {
  9. el.src = initImg
  10. return
  11. }
  12. Img.onload = function () {
  13. // 加载成功后的图片
  14. el.src = Img.src
  15. Img = null
  16. }
  17. Img.onerror = function () {
  18. // 加载失败后的图片
  19. el.src = initImg
  20. Img = null
  21. }
  22. Img.src = binding.value
  23. },
  24. inserted: function () { // 绑定到节点
  25. },
  26. update: function (el, binding, vnode) { // 组件更新
  27. let initImg = el.getAttribute('data-initsrc') || vnode.context.Global.errorImg
  28. // 指令数据更新后图片的处理
  29. let Img = new Image()
  30. if (!binding.value) {
  31. el.src = initImg
  32. return
  33. }
  34. Img.onload = function () {
  35. el.src = Img.src
  36. Img = null
  37. }
  38. Img.onerror = function () {
  39. el.src = initImg
  40. Img = null
  41. }
  42. Img.src = binding.value
  43. },
  44. componentUpdated: function () { // 组件更新完成
  45. },
  46. unbind: function () { // 解绑
  47. }
  48. })

使用

  1. <img v-imgsrc="item.img" :data-initsrc="Global.initImg" />

标题样式 v-symbolTitle

1640679028(1).png
src/directive/symbol-title/index.js

  1. // 注册全局指令 `v-symbolTitle`
  2. /* eslint-disable */
  3. import Vue from 'vue';
  4. import { hasOwnProperty } from '@/utils/index.js'
  5. Vue.directive('symbolTitle', {
  6. bind: function(el, binding, vnode) {
  7. const symbolNode = document.createElement('span');
  8. const titleNode = document.createElement('span');
  9. const symbolNodeStyle = {
  10. display: 'inline-block',
  11. verticalAlign: 'middle',
  12. width: '4px',
  13. height: '14px',
  14. background: '#2570e3',
  15. borderRadius: '2px',
  16. }
  17. const titleNodeStyle = {
  18. display: 'inline-block',
  19. verticalAlign: 'middle',
  20. marginLeft: '8px',
  21. height: '22px',
  22. lineHeight: '22px',
  23. fontSize: '16px',
  24. fontWeight: 600,
  25. color: '#2570e3',
  26. }
  27. for (const key in symbolNodeStyle) {
  28. if (hasOwnProperty(symbolNodeStyle, key)) {
  29. symbolNode.style[key] = symbolNodeStyle[key];
  30. }
  31. }
  32. for (const key in titleNodeStyle) {
  33. if (hasOwnProperty(titleNodeStyle, key)) {
  34. titleNode.style[key] = titleNodeStyle[key];
  35. }
  36. }
  37. titleNode.innerText = binding.value;
  38. el.style.paddingBottom = '15px';
  39. el.appendChild(symbolNode)
  40. el.appendChild(titleNode)
  41. },
  42. inserted: function(el) {},
  43. update: function() {},
  44. componentUpdated: function() {},
  45. unbind: function() {},
  46. })

页面使用
如果使用该指令的元素的兄弟元素存在v-if渲染的场景,appendChild 方法会出现节点插入位置错乱的现象,可以使用div包括一下(或者把必要的逻辑判断转移到 指令里面处理),或者把判断逻辑写到兄弟元素的内层,以保持整体结构的相对位置不变。

  1. <div v-symbolTitle="'基本信息'"></div>

元素点击范围扩展指令 v-expandClick

使用该指令可以隐式的扩展元素的点击范围,由于借用伪元素实现,故不会影响元素在页面上的排列布局。
可传入的参数为:上右下左扩展的范围,单位 px,默认向外扩展 10px。指令的代码如下:

  1. export default function (el, binding) {
  2. const s = document.styleSheets[document.styleSheets.length - 1]
  3. const DEFAULT = -10 // 默认向外扩展10px
  4. const [top, right, bottom, left] = binding.expression && binding.expression.split(',') || []
  5. const ruleStr = `content:"";position:absolute;top:-${top || DEFAULT}px;bottom:-${bottom || DEFAULT}px;right:-${right || DEFAULT}px;left:-${left || DEFAULT}px;`
  6. const classNameList = el.className.split(' ')
  7. el.className = classNameList.includes('expand_click_range') ? classNameList.join(' ') : [...classNameList, 'expand_click_range'].join(' ')
  8. el.style.position = el.style.position || "relative"
  9. if (s.insertRule) {
  10. s.insertRule('.expand_click_range::before' + '{' + ruleStr + '}', s.cssRules.length)
  11. } else { /* IE */
  12. s.addRule('.expand_click_range::before', ruleStr, -1)
  13. }
  14. }

参数 Attributes:

参数 说明 默认值 类型 可选
top, right, bottom, left 上右下左扩展宽度(逗号分割),
单位px
10,10,10,10 String 可填

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

  1. <div v-expandClick="20,30,40,50" @click="glabClickoutside"> 点击范围扩大</div>

文本内容复制指令 v-copy

使用该指令可以复制元素的文本内容(指令支持单击复制 v-copy、双击复制 v-copy.dblclick、点击icon复制 v-copy.icon 三种模式),不传参数时,默认使用单击复制。
指令的代码如下:

  1. export default {
  2. bind (el, binding) {
  3. // 双击触发复制
  4. if (binding.modifiers.dblclick) {
  5. el.addEventListener('dblclick', () => handleClick(el.innerText))
  6. el.style.cursor = 'copy'
  7. }
  8. // 点击icon触发复制
  9. else if (binding.modifiers.icon) {
  10. if (el.hasIcon) return
  11. const iconElement = document.createElement('i')
  12. iconElement.setAttribute('class', 'el-icon-document-copy')
  13. iconElement.setAttribute('style', 'margin-left:5px')
  14. el.appendChild(iconElement)
  15. el.hasIcon = true
  16. iconElement.addEventListener('click', () => handleClick(el.innerText))
  17. iconElement.style.cursor = 'copy'
  18. }
  19. // 单击触发复制
  20. else {
  21. el.addEventListener('click', () => handleClick(el.innerText))
  22. el.style.cursor = 'copy'
  23. }
  24. }
  25. }
  26. function handleClick (text) {
  27. // 创建元素
  28. if (!document.getElementById('copyTarget')) {
  29. const copyTarget = document.createElement('input')
  30. copyTarget.setAttribute('style', 'position:fixed;top:0;left:0;opacity:0;z-index:-1000;')
  31. copyTarget.setAttribute('id', 'copyTarget')
  32. document.body.appendChild(copyTarget)
  33. }
  34. // 复制内容
  35. const input = document.getElementById('copyTarget')
  36. input.value = text
  37. input.select()
  38. document.execCommand('copy')
  39. // alert('复制成功')
  40. }

参数 Attributes:

参数 说明 默认值 类型 可选
dblclick 双击复制文本内容 / String 可选
icon 单击icon复制文本内容 / String 可选

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

  1. <div v-copy> 单击复制 </div>
  2. <div v-copy.dblclick> 双击复制 </div>
  3. <div v-copy.icon> icon复制 </div>

元素全屏指令 v-screenfull

全屏指令,点击元素进行全屏/退出全屏的操作。支持元素后面是否插入 element-ui 的全屏图标 el-icon-full-screen。
指令的代码如下:

  1. import screenfull from 'screenfull'
  2. export default {
  3. bind (el, binding) {
  4. if (binding.modifiers.icon) {
  5. if (el.hasIcon) return
  6. // 创建全屏图标
  7. const iconElement = document.createElement('i')
  8. iconElement.setAttribute('class', 'el-icon-full-screen')
  9. iconElement.setAttribute('style', 'margin-left:5px')
  10. el.appendChild(iconElement)
  11. el.hasIcon = true
  12. }
  13. el.style.cursor = el.style.cursor || 'pointer'
  14. // 监听点击全屏事件
  15. el.addEventListener('click', () => handleClick())
  16. }
  17. }
  18. function handleClick () {
  19. if (!screenfull.isEnabled) {
  20. alert('浏览器不支持全屏')
  21. return
  22. }
  23. screenfull.toggle()
  24. }

参数 Attributes:

参数 说明 默认值 类型 可选
icon 是否添加 icon / String 可选

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

  1. <div v-screenfull.icon> 全屏 </div>

元素说明指令 v-tooltip

为元素添加说明,如同 element-ui 的 el-tooltip(问号 icon 在鼠标覆盖后,展示说明文字)。
Vue自定义指令 - 图2
指令的代码如下:

  1. import Vue from 'vue'
  2. export default function (el, binding) {
  3. if (el.hasIcon) return
  4. const iconElement = structureIcon(binding.arg, binding.value)
  5. el.appendChild(iconElement)
  6. el.hasIcon = true
  7. }
  8. function structureIcon (content, attrs) {
  9. // 拼接绑定属性
  10. let attrStr = ''
  11. for (let key in attrs) {
  12. attrStr += `${key}=${attrs[key]} `
  13. }
  14. const a = `<el-tooltip content=${content} ${attrStr}><i class="el-icon-question" style="margin:0 10px"></i></el-tooltip>`
  15. // 创建构造器
  16. const tooltip = Vue.extend({
  17. template: a
  18. })
  19. // 创建一个 tooltip 实例并返回 dom 节点
  20. const component = new tooltip().$mount()
  21. return component.$el
  22. }

参数 Attributes:

参数 说明 默认值 类型 可选
content 传给指令的参数。例如 v-tooltip:content 中,参数为 “content” ,tooltip中展示的内容为:”content” / String 可选
tootipParams element-ui 支持的 tooltip 属性 / Object 可选

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

  1. <div v-tooltip:content='tootipParams'> 提示 </div>

举例:

  1. <div v-tooltip:提示内容为XXX1> 提示1</div>
  2. <div v-tooltip:提示内容为XXX='tootipParams'> 提示2 </div>

为指令传入 element-ui 支持的参数:

  1. data() {
  2. return {
  3. tootipParams: {
  4. placement: 'top',
  5. effect: 'light',
  6. }
  7. }
  8. }

文字超出省略指令 v-ellipsis

这个指令可以做成css 类名,而且可以定义2行3行等显示省略号,使用起来更方便。
使用该指令当文字内容超出宽度(默认 100 px)时自动变为省略形式。等同于使用 css:

  1. width: 100px;
  2. whiteSpace: nowrap
  3. overflow: hidden;
  4. textOverflow: ellipsis;

使用指令效果:
Vue自定义指令 - 图3
指令的代码如下:

  1. export default function (el, binding) {
  2. el.style.width = `${binding.arg || 100}px`
  3. el.style.whiteSpace = 'nowrap'
  4. el.style.overflow = 'hidden';
  5. el.style.textOverflow = 'ellipsis';
  6. }

参数 Attributes:

参数 说明 默认值 类型 可选
width 元素宽度 100 Number 必填

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

  1. <div v-ellipsis:100> 需要省略的文字是阿萨的副本阿萨的副本阿萨的副本阿萨的副本</div>

回到顶部指令 v-backtop

使用该指令可以让页面或指定元素回到顶部。
可选指定元素,如果不指定则全局页面回到顶部。可选在元素偏移多少 px 后显示 backtop 元素,例如在滚动 400px 后显示回到顶部按钮。
Vue自定义指令 - 图4
指令的代码如下:

  1. export default {
  2. bind (el, binding, vnode) {
  3. // 响应点击后滚动到元素顶部
  4. el.addEventListener('click', () => {
  5. const target = binding.arg ? document.getElementById(binding.arg) : window
  6. target.scrollTo({
  7. top: 0,
  8. behavior: 'smooth'
  9. })
  10. })
  11. },
  12. update (el, binding, vnode) {
  13. // 滚动到达参数值才出现绑定指令的元素
  14. const target = binding.arg ? document.getElementById(binding.arg) : window
  15. if (binding.value) {
  16. target.addEventListener('scroll', (e) => {
  17. if (e.srcElement.scrollTop > binding.value) {
  18. el.style.visibility = 'unset'
  19. } else {
  20. el.style.visibility = 'hidden'
  21. }
  22. })
  23. }
  24. // 判断初始化状态
  25. if (target.scrollTop < binding.value) {
  26. el.style.visibility = 'hidden'
  27. }
  28. },
  29. unbind (el) {
  30. const target = binding.arg ? document.getElementById(binding.arg) : window
  31. target.removeEventListener('scroll')
  32. el.removeEventListener('click')
  33. }
  34. }

参数 Attributes:

参数 说明 默认值 类型 可选
id 给需要回到顶部的元素添加的id / String 可选
offset 偏移距离为 height 时显示指令绑定的元素 / Number 可选

然后你可以在模板中任何元素上使用新的 v-backtop property,如下表示在 id 为 app 的元素滚动 400px 后显示绑定指令的元素:

  1. <div v-backtop:app="400"> 回到顶部 </div>

也可以这样使用,表示为一直显示绑定指令的元素,并且是全局页面回到顶部:

  1. <div v-backtop> 回到顶部 </div>

空状态指令 v-empty

使用该指令可以显示缺省的空状态。 可以传入默认图片(可选,默认无图片)、默认文字内容(可选,默认为暂无数据)、以及标示是否显示空状态(必选)。
Vue自定义指令 - 图5
指令的代码如下:

  1. import Vue from "vue";
  2. export default {
  3. update (el, binding, vnode) {
  4. el.style.position = el.style.position || 'relative'
  5. const { offsetHeight, offsetWidth } = el
  6. const { visible, content, img } = binding.value
  7. const image = img ? `<img src="${img}" height="30%" width="30%"></img>` : ''
  8. const defaultStyle = "position:absolute;top:0;left:0;z-index:9999;background:#fff;display:flex;justify-content: center;align-items: center;"
  9. const empty = Vue.extend({
  10. template: `<div style="height:${offsetHeight}px;width:${offsetWidth}px;${defaultStyle}">
  11. <div style="text-align:center">
  12. <div>${image}</div>
  13. <div>${content || '暂无数据'}</div>
  14. </div>
  15. </div>`
  16. })
  17. const component = new empty().$mount().$el
  18. if (visible) {
  19. el.appendChild(component)
  20. } else {
  21. el.removeChild(el.lastChild)
  22. }
  23. },
  24. }

参数 Attributes:

参数 说明 默认值 类型 可选
emptyValue 包含文字内容 content、图片 img、是否显示 visible,仅 visible 必传 / Object 必须

然后你可以在模板中任何元素上使用新的 v-empty property,如下传入对象 emptyValue:

  1. <div style="height:500px;width:500px" v-empty="emptyValue"> 原本内容

需要传入一个参数对象,例如显示文字为:暂无列表,图片路径为 ../../assets/images/blue_big.png,控制标示 visible:

  1. emptyValue = {
  2. content: '暂无列表',
  3. img: require('../../assets/images/blue_big.png'),
  4. visible: true,
  5. },

徽标指令 v-badge

使用该指令在元素右上角显示徽标。
支持配置徽标的背景颜色、徽标形状;支持传入徽标上显示的数字。
Vue自定义指令 - 图6Vue自定义指令 - 图7
指令的代码如下:

  1. import Vue from 'vue'
  2. const SUCCESS = '#72c140'
  3. const ERROR = '#ed5b56'
  4. const WARNING = '#f0af41'
  5. const INFO = '#4091f7'
  6. const HEIGHT = 20
  7. let flag = false
  8. export default {
  9. update (el, binding, vnode) {
  10. const { modifiers, value } = binding
  11. const modifiersKey = Object.keys(modifiers)
  12. let isDot = modifiersKey.includes('dot')
  13. let backgroundColor = ''
  14. if (modifiersKey.includes('success')) {
  15. backgroundColor = SUCCESS
  16. } else if (modifiersKey.includes('warning')) {
  17. backgroundColor = WARNING
  18. } else if (modifiersKey.includes('info')) {
  19. backgroundColor = INFO
  20. } else {
  21. backgroundColor = ERROR
  22. }
  23. const targetTemplate = isDot
  24. ? `<div style="position:absolute;top:-5px;right:-5px;height:10px;width:10px;border-radius:50%;background:${backgroundColor}"></div>`
  25. : `<div style="background:${backgroundColor};position:absolute;top:-${HEIGHT / 2}px;right:-${HEIGHT / 2}px;height:${HEIGHT}px;min-width:${HEIGHT}px;border-radius:${HEIGHT / 2}px;text-align:center;line-height:${HEIGHT}px;color:#fff;padding:0 5px;">${value}</div>`
  26. el.style.position = el.style.position || 'relative'
  27. const badge = Vue.extend({
  28. template: targetTemplate
  29. })
  30. const component = new badge().$mount().$el
  31. if (flag) {
  32. el.removeChild(el.lastChild)
  33. }
  34. el.appendChild(component)
  35. flag = true
  36. }
  37. }

参数 Attributes:

参数 说明 默认值 类型 可选
normal、dot 徽标形状normal为正常徽标;dot 仅为一个点 normal String 可选
success、error、info、warning 徽标颜色 error String 可选
number 徽标上显示的数字 / Number 可选

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

  1. <div v-badge.dot.info="badgeCount" style="height:50px;width:50px;background:#999"> </div>

拖拽指令 v-drag

使用该指令可以对元素进行拖拽。
指令的代码如下:

  1. export default {
  2. let _el = el
  3. document.onselectstart = function() {
  4. return false //禁止选择网页上的文字
  5. }
  6. _el.onmousedown = e => {
  7. let disX = e.clientX - _el.offsetLeft //鼠标按下,计算当前元素距离可视区的距离
  8. let disY = e.clientY - _el.offsetTop
  9. document.onmousemove = function(e){
  10. let l = e.clientX - disX
  11. let t = e.clientY - disY;
  12. _el.style.left = l + "px"
  13. _el.style.top = t + "px"
  14. }
  15. document.onmouseup = e => {
  16. document.onmousemove = document.onmouseup = null
  17. }
  18. return false
  19. }
  20. }

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

  1. <div v-drag> 支持拖拽的元素 </div>

响应缩放指令 v-resize

使用该指令可以响应元素宽高改变时执行的方法。
指令的代码如下:

  1. export default {
  2. bind(el, binding) {
  3. let width = '', height = '';
  4. function isReize() {
  5. const style = document.defaultView.getComputedStyle(el);
  6. if (width !== style.width || height !== style.height) {
  7. binding.value(); // 执行传入的方法
  8. }
  9. width = style.width;
  10. height = style.height;
  11. }
  12. el.__timer__ = setInterval(isReize, 300); // 周期性监听元素是否改变
  13. },
  14. unbind(el) {
  15. clearInterval(el.__timer__);
  16. }
  17. }

参数 Attributes:

参数 说明 默认值 类型 可选
resize() 传入元素改变 size 后执行的方法 / Function 必选

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

  1. // 传入 resize() 方法
  2. <div v-resize="resize"></div>

字符串整形指令 v-format

使用该指令可以修改字符串,如使用 v-format.toFixed 保留两位小数、 v-format.price 将内容变成金额(每三位逗号分隔),可以同时使用,如 v-format.toFixed.price。
例如将数字 243112.331 变成 243112.33,或 243,112.33。
指令的代码如下:

  1. export default {
  2. update (el, binding, vnode) {
  3. const { value, modifiers } = binding
  4. if (!value) return
  5. let formatValue = value
  6. if (modifiers.toFixed) {
  7. formatValue = value.toFixed(2)
  8. }
  9. console.log(formatValue)
  10. if (modifiers.price) {
  11. formatValue = formatNumber(formatValue)
  12. }
  13. el.innerText = formatValue
  14. },
  15. }
  16. function formatNumber (num) {
  17. num += '';
  18. let strs = num.split('.');
  19. let x1 = strs[0];
  20. let x2 = strs.length > 1 ? '.' + strs[1] : '';
  21. var rgx = /(\d+)(\d{3})/;
  22. while (rgx.test(x1)) {
  23. x1 = x1.replace(rgx, '$1' + ',' + '$2');
  24. }
  25. return x1 + x2
  26. }

参数 Attributes:

参数 说明 默认值 类型 可选
toFixed 保留两位小数 / String 可选
price 整形成金额(三位逗号分隔) / String 可选

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

  1. <div v-format.toFixed.price="123333"> 123 </div>

如何使用这些指令?

为了便于管理指令,我们将每个指令都存在于单独的 js 文件中。在项目的 src 下建一个 directives 目录,目录下新建 index.js 文件用于引入并注册指令。

  1. ├── src
  2. | ├── directive
  3. | | ├── index.js
  4. | | ├── backtop.js
  5. | | ├── badge.js
  6. | | ├── copy.js
  7. | | ├── ellipsis.js
  8. | | ├── empty.js
  9. | | ├── expandClick.js
  10. | | ├── screenfull.js
  11. | | └── tooltips.js
  12. | ├── main.js

举个🌰:
directives 目录下新建 ellipsis.js 文件:

  1. export default function (el, binding) {
  2. el.style.width = binding.arg || 100 + 'px'
  3. el.style.whiteSpace = 'nowrap'
  4. el.style.overflow = 'hidden';
  5. el.style.textOverflow = 'ellipsis';
  6. }

directives 的 index.js 文件中引入 ellipsis 指令并注册:

  1. import Vue from 'vue'
  2. import ellipsis from './ellipsis' // 引入指令
  3. // import other directives
  4. const directives = {
  5. ellipsis
  6. // other directives
  7. }
  8. Object.keys(directives).forEach(name => Vue.directive(name, directives[name]))

最后在 mian.js 中引入 index.js 文件:

  1. import '@/directives/index'

这样就可以正常使用这些指令了:

  1. <div v-指令名称 />

总结

我们常常在引入全局功能时,主要都是写于 js 文件、组件中。不同于他们在使用时每次需要引用或注册,在使用上指令更加简洁。
除了将功能封装成组件,还可以多多考虑将一些简洁实用的功能放到 deirect 中。例如:常用的 css 样式、js 的一些操作、utils 中的一些工具方法、甚至是一个完整的组件都可以放进去(不过需要考虑一下性能和复杂度)。

作者:Huup_We
链接:https://juejin.cn/post/6963840401899782175
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。