首頁 web前端 Vue.js 分享一些Vuejs中常用的自訂指令(總結)

分享一些Vuejs中常用的自訂指令(總結)

Jul 08, 2021 am 10:56 AM
vue.js 自訂指令

在Vuejs中,自訂一些指令對底層DOM進行操作。以下這篇文章總結分享一些常用的自訂指令程式碼,可以直接使用,提高開發效率!

分享一些Vuejs中常用的自訂指令(總結)

【相關推薦:《vue.js教學》】

1、元素點選範圍擴充指令v- expandClick

使用此指令可以隱式的擴充元素的點擊範圍,由於借用偽元素實現,故不會影響元素在頁面上的排列佈局。

可傳入的參數為:上右下左擴展的範圍,單位 px,預設向外擴展 10px。指令的程式碼如下:

export default function (el, binding) {
    const s = document.styleSheets[document.styleSheets.length - 1]
    const DEFAULT = -10 // 默认向外扩展10px
    const ruleStr = `content:"";position:absolute;top:-${top || DEFAULT}px;bottom:-${bottom || DEFAULT}px;right:-${right || DEFAULT}px;left:-${left || DEFAULT}px;`
    const [top, right, bottom, left] = binding.expression && binding.expression.split(',') || []
    const classNameList = el.className.split(' ')
    el.className = classNameList.includes('expand_click_range') ? classNameList.join(' ') : [...classNameList, 'expand_click_range'].join(' ')
    el.style.position = el.style.position || "relative"
    if (s.insertRule) {
        s.insertRule('.expand_click_range::before' + '{' + ruleStr + '}', s.cssRules.length)
    } else { /* IE */
        s.addRule('.expand_click_range::before', ruleStr, -1)
    }
}
登入後複製

參數Attributes:

分享一些Vuejs中常用的自訂指令(總結)

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

<div v-expandClick="20,30,40,50" @click="glabClickoutside"> 点击范围扩大</div>
登入後複製

2、文字內容複製指令v-copy

使用該指令可以複製元素的文字內容(指令支援點擊複製v-copy、雙擊複製v- copy.dblclick、點選icon複製v-copy.icon 三種模式),不傳參數時,預設使用點選複製。

指令的程式碼如下:

export default {
  bind (el, binding) {
    // 双击触发复制
    if (binding.modifiers.dblclick) {
      el.addEventListener(&#39;dblclick&#39;, () => handleClick(el.innerText))
      el.style.cursor = &#39;copy&#39;
    }
    // 点击icon触发复制
    else if (binding.modifiers.icon) {
      if (el.hasIcon) return
      const iconElement = document.createElement(&#39;i&#39;)
      iconElement.setAttribute(&#39;class&#39;, &#39;el-icon-document-copy&#39;)
      iconElement.setAttribute(&#39;style&#39;, &#39;margin-left:5px&#39;)
      el.appendChild(iconElement)
      el.hasIcon = true
      iconElement.addEventListener(&#39;click&#39;, () => handleClick(el.innerText))
      iconElement.style.cursor = &#39;copy&#39;
    }
    // 单击触发复制
    else {
      el.addEventListener(&#39;click&#39;, () => handleClick(el.innerText))
      el.style.cursor = &#39;copy&#39;
    }
  }
}

function handleClick (text) {
  // 创建元素
  if (!document.getElementById(&#39;copyTarget&#39;)) {
    const copyTarget = document.createElement(&#39;input&#39;)
    copyTarget.setAttribute(&#39;style&#39;, &#39;position:fixed;top:0;left:0;opacity:0;z-index:-1000;&#39;)
    copyTarget.setAttribute(&#39;id&#39;, &#39;copyTarget&#39;)
    document.body.appendChild(copyTarget)
  }

  // 复制内容
  const input = document.getElementById(&#39;copyTarget&#39;)
  input.value = text
  input.select()
  document.execCommand(&#39;copy&#39;)
  // alert(&#39;复制成功&#39;)
}
登入後複製

參數Attributes:

分享一些Vuejs中常用的自訂指令(總結)

#然後你可以在範本中任何元素上使用新的v-copy property,如下:

<div v-copy> 单击复制 </div>
<div v-copy.dblclick> 双击复制 </div>
<div v-copy.icon> icon复制 </div>
登入後複製

3、元素全螢幕指令v-screenfull
全螢幕指令,點選元素進行全螢幕/退出全螢幕的操作。支援元素後面是否插入 element-ui 的全螢幕圖示 el-icon-full-screen。

指令的程式碼如下:

import screenfull from &#39;screenfull&#39;

export default {
  bind (el, binding) {
    if (binding.modifiers.icon) {
      if (el.hasIcon) return
      // 创建全屏图标
      const iconElement = document.createElement(&#39;i&#39;)
      iconElement.setAttribute(&#39;class&#39;, &#39;el-icon-full-screen&#39;)
      iconElement.setAttribute(&#39;style&#39;, &#39;margin-left:5px&#39;)
      el.appendChild(iconElement)
      el.hasIcon = true
  }
    el.style.cursor = el.style.cursor || &#39;pointer&#39;
    // 监听点击全屏事件
    el.addEventListener(&#39;click&#39;, () => handleClick())
  }
}

function handleClick () {
  if (!screenfull.isEnabled) {
    alert(&#39;浏览器不支持全屏&#39;)
    return
  }
  screenfull.toggle()
}
登入後複製

參數Attributes:

分享一些Vuejs中常用的自訂指令(總結)

#然後你可以在範本中任何元素上使用新的v-screenfull property,如下:

<div v-screenfull.icon> 全屏 </div>
登入後複製

4、元素說明指令v-tooltip

為元素添加說明,如同element-ui 的el-tooltip(問號icon 滑鼠覆蓋後,展示說明文字)。

分享一些Vuejs中常用的自訂指令(總結)

指令的程式碼如下:

import Vue from &#39;vue&#39;
export default function (el, binding) {
    if (el.hasIcon) return
    const iconElement = structureIcon(binding.arg, binding.value)
    el.appendChild(iconElement)
    el.hasIcon = true
}

function structureIcon (content, attrs) {
    // 拼接绑定属性
    let attrStr = &#39;&#39;
    for (let key in attrs) {
        attrStr += `${key}=${attrs[key]} `
    }
    const a = `<el-tooltip content=${content} ${attrStr}><i class="el-icon-question" style="margin:0 10px"></i></el-tooltip>`
    // 创建构造器
    const tooltip = Vue.extend({
        template: a
    })
    // 创建一个 tooltip 实例并返回 dom 节点
    const component = new tooltip().$mount()
    return component.$el
}
登入後複製

參數Attributes:

分享一些Vuejs中常用的自訂指令(總結)

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

<div v-tooltip:content=&#39;tootipParams&#39;> 提示 </div>
登入後複製

範例:

<div v-tooltip:提示内容为XXX1> 提示1</div>
<div v-tooltip:提示内容为XXX=&#39;tootipParams&#39;> 提示2 </div>
登入後複製

為指令傳入element-ui 支援的參數:

data() {
    return {
        tootipParams: {
            placement: &#39;top&#39;,
            effect: &#39;light&#39;,
        }
    }
}
登入後複製

5、文字超出省略指令v-ellipsis

使用該指令當文字內容超出寬度(預設100 px)時自動變成省略形式。等同於使用css:

width: 100px;
whiteSpace: nowrap
overflow: hidden;
textOverflow: ellipsis;
登入後複製

使用指令效果:

分享一些Vuejs中常用的自訂指令(總結)

#指令的程式碼如下:

export default function (el, binding) {
    el.style.width = binding.arg || 100 + &#39;px&#39;
    el.style.whiteSpace = &#39;nowrap&#39;
    el.style.overflow = &#39;hidden&#39;;
    el.style.textOverflow = &#39;ellipsis&#39;;
}
登入後複製
登入後複製

參數Attributes:

分享一些Vuejs中常用的自訂指令(總結)

然後你可以在範本中任何元素上使用新的v-ellipsis property,如下:

<div v-ellipsis:100> 需要省略的文字是阿萨的副本阿萨的副本阿萨的副本阿萨的副本</div>
登入後複製

6、回到頂部指令v-backtop
使用該指令可以讓頁面或指定元素回到頂部。

可選指定元素,如果不指定則全域頁面回到頂部。可選在元素偏移多少 px 後顯示 backtop 元素,例如在捲動 400px 後顯示回到頂部按鈕。

分享一些Vuejs中常用的自訂指令(總結)

指令的程式碼如下:

export default {
  bind (el, binding, vnode) {
    // 响应点击后滚动到元素顶部
    el.addEventListener(&#39;click&#39;, () => {
    const target = binding.arg ? document.getElementById(binding.arg) : window
    target.scrollTo({
      top: 0,
      behavior: &#39;smooth&#39;
      })
    })
  },
  update (el, binding, vnode) {
    // 滚动到达参数值才出现绑定指令的元素
    const target = binding.arg ? document.getElementById(binding.arg) : window
    if (binding.value) {
      target.addEventListener(&#39;scroll&#39;, (e) => {
        if (e.srcElement.scrollTop > binding.value) {
          el.style.visibility = &#39;unset&#39;
        } else {
          el.style.visibility = &#39;hidden&#39;
        }
      })
    }
    // 判断初始化状态
    if (target.scrollTop < binding.value) {
      el.style.visibility = &#39;hidden&#39;
    }
  },
  unbind (el) {
    const target = binding.arg ? document.getElementById(binding.arg) : window
    target.removeEventListener(&#39;scroll&#39;)
    el.removeEventListener(&#39;click&#39;)
  }
}
登入後複製

參數Attributes:

分享一些Vuejs中常用的自訂指令(總結)

然後你可以在模板中任何元素上使用新的v-backtop property,如下表示在id 為app 的元素滾動400px 後顯示綁定指令的元素:

<div  v-backtop:app="400"> 回到顶部 </div>
登入後複製

也可以這樣使用,表示為一直顯示綁定指令的元素,並且是全域頁面回到頂部:

<div  v-backtop> 回到顶部 </div>
登入後複製

7、空狀態指令v-empty

使用該指令可以顯示缺省的空狀態。可傳入預設圖片(可選,預設無圖片)、預設文字內容(可選,預設為暫無資料)、以及標示是否顯示空白狀態(必選)。

分享一些Vuejs中常用的自訂指令(總結)

指令的程式碼如下:

import Vue from "vue";
export default {
  update (el, binding, vnode) {
    el.style.position = el.style.position || &#39;relative&#39;
    const { offsetHeight, offsetWidth } = el
    const { visible, content, img } = binding.value
    const image = img ? `<img  src="/static/imghw/default1.png"  data-src="${img}"  class="lazy"      style="max-width:90%"  style="max-width:90%" alt="分享一些Vuejs中常用的自訂指令(總結)" ></img>` : &#39;&#39;
    const defaultStyle = "position:absolute;top:0;left:0;z-index:9999;background:#fff;display:flex;justify-content: center;align-items: center;"
    const empty = Vue.extend({
    template: `<div style="height:${offsetHeight}px;width:${offsetWidth}px;${defaultStyle}">
      <div style="text-align:center">
        <div>${image}</div>
        <div>${content || &#39;暂无数据&#39;}</div>
      </div>
    </div>`
    })
    const component = new empty().$mount().$el
    if (visible) {
      el.appendChild(component)
    } else {
      el.removeChild(el.lastChild)
    }
  },
}
登入後複製

#參數Attributes:

1分享一些Vuejs中常用的自訂指令(總結)

##然後你可以在範本中任何元素上使用新的v-empty property,如下傳入物件emptyValue:

<div   style="max-width:90%" v-empty="emptyValue"> 原本内容
登入後複製

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

emptyValue = {
  content: &#39;暂无列表&#39;,
  img: require(&#39;../../assets/images/blue_big.png&#39;),
  visible: true,
},
登入後複製

8、徽标指令 v-badge

使用该指令在元素右上角显示徽标。

支持配置徽标的背景颜色、徽标形状;支持传入徽标上显示的数字。

1分享一些Vuejs中常用的自訂指令(總結)

指令的代码如下:

import Vue from &#39;vue&#39;

const SUCCESS = &#39;#72c140&#39;
const ERROR = &#39;#ed5b56&#39;
const WARNING = &#39;#f0af41&#39;
const INFO = &#39;#4091f7&#39;
const HEIGHT = 20
let flag = false
export default {
  update (el, binding, vnode) {
    const { modifiers, value } = binding
    const modifiersKey = Object.keys(modifiers)
    let isDot = modifiersKey.includes(&#39;dot&#39;)
    let backgroundColor = &#39;&#39;
    if (modifiersKey.includes(&#39;success&#39;)) {
      backgroundColor = SUCCESS
    } else if (modifiersKey.includes(&#39;warning&#39;)) {
      backgroundColor = WARNING
    } else if (modifiersKey.includes(&#39;info&#39;)) {
      backgroundColor = INFO
    } else {
      backgroundColor = ERROR
    }

    const targetTemplate = isDot 
        ? `<div style="position:absolute;top:-5px;right:-5px;height:10px;width:10px;border-radius:50%;background:${backgroundColor}"></div>` 
        : `<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>`
        
    el.style.position = el.style.position || &#39;relative&#39;
    const badge = Vue.extend({
      template: targetTemplate
    })
    const component = new badge().$mount().$el
    if (flag) {
      el.removeChild(el.lastChild)
    }
    el.appendChild(component)
    flag = true
  }
}
登入後複製

参数 Attributes:

1分享一些Vuejs中常用的自訂指令(總結)

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

<div v-badge.dot.info="badgeCount"   style="max-width:90%"> </div>
登入後複製

9、拖拽指令 v-drag

使用该指令可以对元素进行拖拽。

指令的代码如下:

export default {
  let _el = el
  document.onselectstart = function() {
    return false  //禁止选择网页上的文字
  }
  
  _el.onmousedown = e => {
    let disX = e.clientX - _el.offsetLeft //鼠标按下,计算当前元素距离可视区的距离
    let disY = e.clientY - _el.offsetTop
    document.onmousemove = function(e){     
      let l = e.clientX - disX
      let t = e.clientY - disY;
      _el.style.left = l + "px"
      _el.style.top = t + "px"
    }
    document.onmouseup = e => {
      document.onmousemove = document.onmouseup = null
    }
    return false
  }
}
登入後複製

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

<div v-drag> 支持拖拽的元素 </div>
登入後複製

10、响应缩放指令 v-resize

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

指令的代码如下:

export default {
  bind(el, binding) {
    let width = &#39;&#39;, height = &#39;&#39;;
    function isReize() {
      const style = document.defaultView.getComputedStyle(el);
      if (width !== style.width || height !== style.height) {
        binding.value();  // 执行传入的方法
      }
      width = style.width;
      height = style.height;
     }
     el.__timer__ = setInterval(isReize, 300); // 周期性监听元素是否改变
  },
  unbind(el) {
    clearInterval(el.__timer__);
  }
}
登入後複製

参数 Attributes:

1分享一些Vuejs中常用的自訂指令(總結)

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

// 传入 resize() 方法
<div v-resize="resize"></div>
登入後複製

11、字符串整形指令 v-format

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

例如将数字 243112.331 变成 243112.33,或 243,112.33。

指令的代码如下:

export default {
  update (el, binding, vnode) {
    const { value, modifiers } = binding
    if (!value) return
    let formatValue = value
    if (modifiers.toFixed) {
      formatValue = value.toFixed(2)
    }
    console.log(formatValue)
    if (modifiers.price) {
      formatValue = formatNumber(formatValue)
    }
    el.innerText = formatValue
  },
}



function formatNumber (num) {
  num += &#39;&#39;;
  let strs = num.split(&#39;.&#39;);
  let x1 = strs[0];
  let x2 = strs.length > 1 ? &#39;.&#39; + strs[1] : &#39;&#39;;
  var rgx = /(\d+)(\d{3})/;
  while (rgx.test(x1)) {
    x1 = x1.replace(rgx, &#39;$1&#39; + &#39;,&#39; + &#39;$2&#39;);
  }
  return x1 + x2
}
登入後複製

参数 Attributes:

1分享一些Vuejs中常用的自訂指令(總結)

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

<div v-format.toFixed.price="123333"> 123 </div>
登入後複製

如何使用这些指令?

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

├── src
|  ├── directive
|  |  ├── index.js
|  |  ├── backtop.js
|  |  ├── badge.js
|  |  ├── copy.js
|  |  ├── ellipsis.js
|  |  ├── empty.js
|  |  ├── expandClick.js
|  |  ├── screenfull.js
|  |  └── tooltips.js
|  ├── main.js
登入後複製

举个例子:

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

export default function (el, binding) {
    el.style.width = binding.arg || 100 + &#39;px&#39;
    el.style.whiteSpace = &#39;nowrap&#39;
    el.style.overflow = &#39;hidden&#39;;
    el.style.textOverflow = &#39;ellipsis&#39;;
}
登入後複製
登入後複製

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

import Vue from &#39;vue&#39;
import ellipsis from &#39;./ellipsis&#39; // 引入指令
// import other directives

const directives = {
  ellipsis
  // other directives
}

Object.keys(directives).forEach(name => Vue.directive(name, directives[name]))
登入後複製

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

import &#39;@/directives/index&#39;
登入後複製
登入後複製

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

import &#39;@/directives/index&#39;
登入後複製
登入後複製

更多编程相关知识,请访问:编程入门!!

以上是分享一些Vuejs中常用的自訂指令(總結)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

深入探討vite是怎麼解析.env檔的 深入探討vite是怎麼解析.env檔的 Jan 24, 2023 am 05:30 AM

使用vue框架開發前端專案時,我們部署的時候都會部署多套環境,往往開發、測試以及線上環境呼叫的介面網域都是不一樣的。如何能做到區分呢?那就是使用環境變數和模式。

vue中組件化和模組化有什麼區別 vue中組件化和模組化有什麼區別 Dec 15, 2022 pm 12:54 PM

組件化和模組化的區別:模組化是從程式碼邏輯的角度進行劃分的;方便程式碼分層開發,確保每個每個功能模組的職能一致。元件化是從UI介面的角度進行規劃;前端的元件化,方便UI元件的重複使用。

圖文詳解如何在Vue專案中整合Ace程式碼編輯器 圖文詳解如何在Vue專案中整合Ace程式碼編輯器 Apr 24, 2023 am 10:52 AM

Ace 是一個用 JavaScript 寫的可嵌入程式碼編輯器。它與 Sublime、Vim 和 TextMate 等原生編輯器的功能和效能相符。它可以很容易地嵌入到任何網頁和 JavaScript 應用程式中。 Ace 被維護為Cloud9 IDE的主要編輯器 ,並且是 Mozilla Skywriter (Bespin) 專案的繼承者。

深入聊聊vue3中的reactive() 深入聊聊vue3中的reactive() Jan 06, 2023 pm 09:21 PM

前言:在vue3的開發中,reactive是提供實現響應式資料的方法。日常開發這個是使用頻率很高的api。這篇文章筆者就來探索其內部運作機制。

探討如何在Vue3中撰寫單元測試 探討如何在Vue3中撰寫單元測試 Apr 25, 2023 pm 07:41 PM

在當今前端開發中,Vue.js 已經成為了一個非常流行的框架。隨著 Vue.js 的不斷發展,單元測試變得越來越重要。今天,我們將探討如何在 Vue.js 3 中編寫單元測試,並提供一些最佳實踐和常見的問題及解決方案。

Vue中JSX語法和模板語法的簡單比較(優劣勢分析) Vue中JSX語法和模板語法的簡單比較(優劣勢分析) Mar 23, 2023 pm 07:53 PM

在Vue.js中,開發人員可以使用兩種不同的語法來建立使用者介面:JSX語法和範本語法。這兩種文法各有優劣,以下就來探討它們的差異和優劣勢。

淺析vue怎麼實現檔案切片上傳 淺析vue怎麼實現檔案切片上傳 Mar 24, 2023 pm 07:40 PM

在實際開發專案過程中有時候需要上傳比較大的文件,然後呢,上傳的時候相對來說就會慢一些,so,後台可能會要求前端進行文件切片上傳,很簡單哈,就是把比如說1個G的檔案流切割成若干個小的檔案流,然後分別請求介面傳遞這個小的檔案流。

解析Vue2實作composition API的原理 解析Vue2實作composition API的原理 Jan 13, 2023 am 08:30 AM

自從Vue3 發布之後,composition API 這個詞走入寫Vue 同學的視野之中,相信大家也一直聽到composition API 比之前的options API 有多好多強,如今由於@vue/composition-api 插件的發布,Vue2的同學也可以上車咯,接下來我們主要以響應式的ref 和reactive 來深入分析一下,這個插件是怎麼實現此

See all articles