• 模拟元素的title属性,自定义Vue指令


     1 function showTitle(el, title) {
     2   const popover = getPopover()
     3   const popoverStyle = popover.style
     4 
     5   if (title === undefined) {
     6     popoverStyle.display = 'none'
     7   } else {
     8     const elRect = el.getBoundingClientRect()
     9     const elComputedStyle = window.getComputedStyle(el, null)
    10     const rightOffset = parseInt(elComputedStyle.getPropertyValue('padding-right')) || 0
    11     const topOffset = parseInt(elComputedStyle.getPropertyValue('padding-top')) || 0
    12 
    13     popoverStyle.visibility = 'hidden'
    14     popoverStyle.display = 'block'
    15     popover.querySelector('.popover-content').textContent = title
    16     popoverStyle.left = elRect.left - popover.offsetWidth / 2 + (el.offsetWidth - rightOffset) / 2 + 'px'
    17     popoverStyle.top = elRect.top - popover.offsetHeight + topOffset + 'px'
    18     popoverStyle.display = 'block'
    19     popoverStyle.visibility = 'visible'
    20   }
    21 }
    22 
    23 function getPopover() {
    24   let popover = document.querySelector('.title-popover')
    25 
    26   if (!popover) {
    27     const tpl = `
    28       <div class="popover title-popover top fade in" style="position:fixed;">
    29         <div class="arrow"></div>
    30         <div class="popover-content"></div>
    31       </div>
    32     `
    33     const fragment = document.createRange().createContextualFragment(tpl)
    34 
    35     document.body.appendChild(fragment)
    36     popover = document.querySelector('.title-popover')
    37   }
    38 
    39   return popover
    40 }
    41 export default {
    42   bind(el, binding, vnode) {
    43     // 使用 const 声明一个只读的常量,其值是需要监听的事件类型列表
    44     const events = ['mouseenter', 'mouseleave', 'click']
    45     // 声明一个处理器,以根据不同的事件类型传不同的参数
    46     const handler = (event) => {
    47       if (event.type === 'mouseenter') {
    48         // 显示一个提示框
    49         showTitle(el, binding.value)
    50       } else {
    51         // 隐藏一个提示框
    52         showTitle()
    53       }
    54     }
    55 
    56     // 在 el 元素上添加事件监听
    57     events.forEach((event) => {
    58       el.addEventListener(event, handler, false)
    59     })
    60 
    61     // 在 el 元素上添加一个属性,以在其他钩子进行访问
    62     el.destroy = () => {
    63       // 移除 el 元素上的事件监听
    64       events.forEach((event) => {
    65         el.removeEventListener(event, handler, false)
    66       })
    67       // 移除 el 元素上的 destroy
    68       el.destroy = null
    69     }
    70   },
    71   unbind(el) {
    72     // 移除事件监听和数据绑定
    73     el.destroy()
    74   }
    75 }

    使用步骤:

    1.建立指令;

    2.在要使用的组件中引入并注册指令

    1 import title from '@/directives/title'
    2 directives: {
    3   title
    4 }

    3.页面中使用,将原来的:title=""改为v-title:

    1 <a v-for="item in contacts" v-title="item.title" :href="item.link" :style="contactStyle" target="_blank">
    2   <i :class="`fa fa-${item.icon}`"></i>
    3 </a>

    指令的基础知识补充:

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

    • bind:只调用一次,指令第一次绑定到元素时调用,在这里可以进行一次性的初始化设置;
    • inserted:被绑定元素插入父节点时调用;
    • update:所在组件的 VNode(虚拟节点)更新时调用,但是可能发生在其子 VNode 更新之前;
    • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用;
    • unbind:只调用一次,指令与元素解绑时调用,在这里可以移除绑定的事件和其他数据;
    • 指令钩子函数会被传入以下参数:

      • el:指令所绑定的元素,可以用来操作 DOM ;
      • binding:一个对象,binding.value 表示指令的绑定值,如 v-title="'我是标题'" 中,绑定值为'我是标题'
      • vnode:Vue 编译生成的虚拟节点;
      • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。
  • 相关阅读:
    HDU 5883 欧拉回路
    HDU 5889 Barricade (Dijkstra+Dinic)
    网络流Dinic算法模板 POJ1273
    216. Combination Sum III
    211. Add and Search Word
    973. K Closest Points to Origin
    932. Beautiful Array
    903. Valid Permutations for DI Sequence
    514. Freedom Trail
    312. Burst Balloons
  • 原文地址:https://www.cnblogs.com/yangguoe/p/9308737.html
Copyright © 2020-2023  润新知