wordpress 多站点管理,珠海网站建设 金蝶,网站集约化建设优势,有赞商城vue2 自定义指令
官网链接https://v2.cn.vuejs.org/v2/guide/custom-directive.html
指令注册
这里是一个 Vue2 的指令合集#xff0c;详细的指令移步下面具体的指令文章#xff0c;现在我们在这里要介绍如何在项目中统一管理和使用这些指令。
注册指令
单文件引入注册 …vue2 自定义指令
官网链接https://v2.cn.vuejs.org/v2/guide/custom-directive.html
指令注册
这里是一个 Vue2 的指令合集详细的指令移步下面具体的指令文章现在我们在这里要介绍如何在项目中统一管理和使用这些指令。
注册指令
单文件引入注册
import Vue from vue
import ellipsis from ./ellipsis
// import other directivesconst directives {ellipsis// other directives
}Object.keys(directives).forEach(name Vue.directive(name, directives[name]))全局注册
使用 Vue.deirect 注册。
// 注册一个全局自定义指令 v-focus
Vue.directive(focus, {// 当被绑定的元素插入到 DOM 中时……inserted: function (el) {// 聚焦元素el.focus()}
})使用
div v-指令名称 /1.回到顶部指令 v-backtop
v-backtop
使用该指令可以让页面或指定元素回到顶部。
可选指定元素如果不指定则全局页面回到顶部。可选在元素偏移多少 px 后显示 backtop 元素例如在滚动 400px 后显示回到顶部按钮。
代码 Code
export default {bind (el, binding, vnode) {// 响应点击后滚动到元素顶部el.addEventListener(click, () {const target binding.arg ? document.getElementById(binding.arg) : windowtarget.scrollTo({top: 0,behavior: smooth})})},update (el, binding, vnode) {// 滚动到达参数值才出现绑定指令的元素const target binding.arg ? document.getElementById(binding.arg) : windowif (binding.value) {target.addEventListener(scroll, (e) {if (e.srcElement.scrollTop binding.value) {el.style.visibility unset} else {el.style.visibility hidden}})}// 判断初始化状态if (target.scrollTop binding.value) {el.style.visibility hidden}},unbind (el) {const target binding.arg ? document.getElementById(binding.arg) : windowtarget.removeEventListener(scroll)el.removeEventListener(click)}
}参数 Attributes
参数说明默认值类型可选id给需要回到顶部的元素添加的id/String可选offset偏移距离为 height 时显示指令绑定的元素/Number可选
使用 Usage
然后你可以在模板中任何元素上使用新的 v-backtop property如下表示在 id 为 app 的元素滚动 400px 后显示绑定指令的元素
div v-backtop:app400 回到顶部 /div也可以这样使用表示为一直显示绑定指令的元素并且是全局页面回到顶部
div v-backtop 回到顶部 /div2.徽标指令 v-badge
v-badge
使用该指令在元素右上角显示徽标。
支持配置徽标的背景颜色、徽标形状支持传入徽标上显示的数字。
代码 Code
import Vue from vueconst SUCCESS #72c140
const ERROR #ed5b56
const WARNING #f0af41
const INFO #4091f7
const HEIGHT 20
let flag false
export default {update (el, binding, vnode) {const { modifiers, value } bindingconst modifiersKey Object.keys(modifiers)let isDot modifiersKey.includes(dot)let backgroundColor if (modifiersKey.includes(success)) {backgroundColor SUCCESS} else if (modifiersKey.includes(warning)) {backgroundColor WARNING} else if (modifiersKey.includes(info)) {backgroundColor INFO} else {backgroundColor ERROR}const targetTemplate isDot ? div styleposition:absolute;top:-5px;right:-5px;height:10px;width:10px;border-radius:50%;background:${backgroundColor}/div : div stylebackground:${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}/divel.style.position el.style.position || relativeconst badge Vue.extend({template: targetTemplate})const component new badge().$mount().$elif (flag) {el.removeChild(el.lastChild)}el.appendChild(component)flag true}
}参数 Attributes
参数说明默认值类型可选normal、dot徽标形状normal为正常徽标dot 仅为一个点normalString可选success、error、info、warning徽标颜色errorString可选number徽标上显示的数字/Number可选
使用 Usage
然后你可以在模板中任何元素上使用新的 v-badge property如下
div v-badge.dot.infobadgeCount styleheight:50px;width:50px;background:#999 /div3.文本内容复制指令 v-copy
v-copy
使用该指令可以复制元素的文本内容。
支持单击复制 v-copy、双击复制 v-copy.dblclick、点击icon复制 v-copy.icon 三种模式。默认使用单击复制。
代码 Code
export default {bind (el, binding) {// 双击触发复制if (binding.modifiers.dblclick) {el.addEventListener(dblclick, () handleClick(el.innerText))el.style.cursor copy}// 点击icon触发复制else if (binding.modifiers.icon) {if (el.hasIcon) returnconst iconElement document.createElement(i)iconElement.setAttribute(class, el-icon-document-copy)iconElement.setAttribute(style, margin-left:5px)el.appendChild(iconElement)el.hasIcon trueiconElement.addEventListener(click, () handleClick(el.innerText))iconElement.style.cursor copy}// 单击触发复制else {el.addEventListener(click, () handleClick(el.innerText))el.style.cursor copy}}
}function handleClick (text) {// 创建元素if (!document.getElementById(copyTarget)) {const copyTarget document.createElement(input)copyTarget.setAttribute(style, position:fixed;top:0;left:0;opacity:0;z-index:-1000;)copyTarget.setAttribute(id, copyTarget)document.body.appendChild(copyTarget)}// 复制内容const input document.getElementById(copyTarget)input.value textinput.select()document.execCommand(copy)// alert(复制成功)
}参数 Attributes
参数说明默认值类型可选dblclick双击复制文本内容/String可选icon单击icon复制文本内容/String可选
使用 Usage
然后你可以在模板中任何元素上使用新的 v-copy property如下
div v-copy 单击复制 /div
div v-copy.dblclick 双击复制 /div
div v-copy.icon icon复制 /div4.文字超出省略 v-ellipsis
v-ellipsis
使用该指令当文字内容超出宽度默认100 px时自动变为省略形式。等同于使用 css
width: 100px;
whiteSpace: nowrap
overflow: hidden;
textOverflow: ellipsis;代码 Code
export default function (el, binding) {el.style.width binding.arg || 100 pxel.style.whiteSpace nowrapel.style.overflow hidden;el.style.textOverflow ellipsis;
}参数 Attributes
参数说明默认值类型可选width元素宽度100Number必填
使用 Usage
然后你可以在模板中任何元素上使用新的 v-ellipsis property如下
div v-ellipsis:100 需要省略的文字是阿萨的副本阿萨的副本阿萨的副本阿萨的副本/div5.空状态指令 v-empty
v-empty
使用该指令可以显示缺省的空状态。 可以传入默认图片可选默认无图片、默认文字内容可选默认为暂无数据、以及标示是否显示空状态必选。
代码 Code
import Vue from vue;
export default {update (el, binding, vnode) {el.style.position el.style.position || relativeconst { offsetHeight, offsetWidth } elconst { visible, content, img } binding.valueconst image img ? img src${img} height30% width30%/img : 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 styleheight:${offsetHeight}px;width:${offsetWidth}px;${defaultStyle}div styletext-align:centerdiv${image}/divdiv${content || 暂无数据}/div/div/div})const component new empty().$mount().$elif (visible) {el.appendChild(component)} else {el.removeChild(el.lastChild)}},
}参数 Attributes
参数说明默认值类型可选emptyValue包含文字内容 content、图片 img、是否显示 visible仅 visible 必传/Object必须
使用 Usage
然后你可以在模板中任何元素上使用新的 v-empty property如下传入对象 emptyValue
div styleheight:500px;width:500px v-emptyemptyValue 原本内容
需要传入一个参数对象例如显示文字为暂无列表图片路径为 ../../assets/images/blue_big.png控制标示 visible
emptyValue {content: 暂无列表,img: require(../../assets/images/blue_big.png),visible: true,
},6.元素点击范围扩展指令 v-expandClick
v-expandClick
使用该指令可以扩展元素的点击范围由于借用伪元素实现故不会影响元素在页面上的排列布局。
可传入的参数为上右下左扩展的范围单位 px默认向外扩展 10px。
代码 Code
export default function (el, binding) {const s document.styleSheets[document.styleSheets.length - 1]const DEFAULT -10 // 默认向外扩展10pxconst 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 || relativeif (s.insertRule) {s.insertRule(.expand_click_range::before { ruleStr }, s.cssRules.length)} else { /* IE */s.addRule(.expand_click_range::before, ruleStr, -1)}
}参数 Attributes
参数说明默认值类型可选top, right, bottom, left上右下左扩展宽度逗号分割单位px10,10,10,10String可填
使用 Usage
然后你可以在模板中任何元素上使用新的 v-expandClick property如下
div v-expandClick20,30,40,50 clickglabClickoutside 点击范围扩大/div7.元素全屏指令 v-screenfull
v-screenfull
全屏指令点击元素进行全屏/退出全屏的操作。可选元素后面是否插入 element-ui 的全屏图标 el-icon-full-screen。
代码 Code
import screenfull from screenfullexport default {bind (el, binding) {if (binding.modifiers.icon) {if (el.hasIcon) return// 创建全屏图标const iconElement document.createElement(i)iconElement.setAttribute(class, el-icon-full-screen)iconElement.setAttribute(style, margin-left:5px)el.appendChild(iconElement)el.hasIcon true}el.style.cursor el.style.cursor || pointer// 监听点击全屏事件el.addEventListener(click, () handleClick())}
}function handleClick () {if (!screenfull.isEnabled) {alert(浏览器不支持全屏)return}screenfull.toggle()
}参数 Attributes
参数说明默认值类型可选icon是否添加 icon/String可选
使用 Usage
然后你可以在模板中任何元素上使用新的 v-screenfull property如下
div v-screenfull.icon 全屏 /div8.元素说明指令 v-tooltip
v-tooltip
为元素添加说明如同 element-ui 的 el-tooltip。
代码 Code
import Vue from vue
export default function (el, binding) {if (el.hasIcon) returnconst iconElement structureIcon(binding.arg, binding.value)el.appendChild(iconElement)el.hasIcon true
}function structureIcon (content, attrs) {// 拼接绑定属性let attrStr for (let key in attrs) {attrStr ${key}${attrs[key]} }const a el-tooltip content${content} ${attrStr}i classel-icon-question stylemargin:0 10px/i/el-tooltip// 创建构造器const tooltip Vue.extend({template: a})// 创建一个 tooltip 实例并返回 dom 节点const component new tooltip().$mount()return component.$el
}参数 Attributes
参数说明默认值类型可选content传给指令的参数。例如 v-tooltip:content 中参数为 “content” tooltip中展示的内容为“content”/String可选tootipParamselement-ui 支持的 tooltip 属性/Object可选
使用 Usage
然后你可以在模板中任何元素上使用新的 v-tooltip property如下
div v-tooltip:contenttootipParams 提示 /div举例
div v-tooltip:提示内容为XXX1 提示1/div
div v-tooltip:提示内容为XXXtootipParams 提示2 /div为指令传入 element-ui 支持的参数
data() {return {tootipParams: {placement: top,effect: light,}}
}vue3自定义指令(相比vue2属于破坏性更新)
官网链接https://cn.vuejs.org/api/sfc-script-setup.html#using-custom-directives
1. Vue3指令的钩子函数
created 元素初始化的时候beforeMount 指令绑定到元素后调用 只调用一次mounted 元素插入父级dom调用beforeUpdate 元素被更新之前调用update 这个周期方法被移除 改用updatedbeforeUnmount 在元素被移除前调用unmounted 指令被移除后调用 只调用一次 Vue2 指令 bind inserted update componentUpdated unbind
2.在setup内定义局部指令
但这里有一个需要注意的限制必须以 vNameOfDirective 的形式来命名本地自定义指令以使得它们可以直接在模板中使用。
templatebutton clickshow !show开关{{show}} ----- {{title}}/buttonDialog v-move-directive{background:green,flag:show}/Dialog
/templateconst vMoveDirective: Directive {created: () {console.log(初始化);},beforeMount(...args: Arrayany) {// 在元素上做些操作console.log(初始化一次);},mounted(el: any, dir: DirectiveBindingValue) {el.style.background dir.value.background;console.log(初始化);},beforeUpdate() {console.log(更新之前);},updated() {console.log(更新结束);},beforeUnmount(...args: Arrayany) {console.log(args);console.log(卸载之前);},unmounted(...args: Arrayany) {console.log(args);console.log(卸载完成);},
};3.生命周期钩子参数详解
第一个 el 当前绑定的DOM 元素
第二个 binding
instance使用指令的组件实例。 value传递给指令的值。例如在 v-my-directive“1 1” 中该值为 2。 oldValue先前的值仅在 beforeUpdate 和 updated 中可用。无论值是否有更改都可用。 arg传递给指令的参数(如果有的话)。例如在 v-my-directive:foo 中arg 为 “foo”。 modifiers包含修饰符(如果有的话) 的对象。例如在 v-my-directive.foo.bar 中修饰符对象为 {foo: truebar: true}。 dir一个对象在注册指令时作为参数传递。例如在以下指令中 第三个 当前元素的虚拟DOM 也就是Vnode 第四个 prevNode 上一个虚拟节点仅在 beforeUpdate 和 updated 钩子中可用
函数简写
你可能想在 mounted 和 updated 时触发相同行为而不关心其他的钩子函数。那么你可以通过将这个函数模式实现
templatedivinput v-modelvalue typetext /A v-move{ background: value }/A/div
/templatescript setup langts
import A from ./components/A.vue
import { ref, Directive, DirectiveBinding } from vue
let value refstring()
type Dir {background: string
}
const vMove: Directive (el, binding: DirectiveBindingDir) {el.style.background binding.value.background
}
/scriptstyle
/style1.自定义拖拽指令
templatediv v-move classboxdiv classheader/divdiv内容/div/div
/templatescript setup langts
import { Directive } from vue;
const vMove: Directive {mounted(el: HTMLElement) {let moveEl el.firstElementChild as HTMLElement;const mouseDown (e: MouseEvent) {//鼠标点击物体那一刻相对于物体左侧边框的距离点击时的位置相对于浏览器最左边的距离-物体左边框相对于浏览器最左边的距离console.log(e.clientX, e.clientY, -----起始, el.offsetLeft);let X e.clientX - el.offsetLeft;let Y e.clientY - el.offsetTop;const move (e: MouseEvent) {el.style.left e.clientX - X px;el.style.top e.clientY - Y px;console.log(e.clientX, e.clientY, ---改变);};document.addEventListener(mousemove, move);document.addEventListener(mouseup, () {document.removeEventListener(mousemove, move);});};moveEl.addEventListener(mousedown, mouseDown);},
};
/scriptstyle langless
.box {position: fixed;left: 50%;top: 50%;transform: translate(-50%, -50%);width: 200px;height: 200px;border: 1px solid #ccc;.header {height: 20px;background: black;cursor: move;}
}
/style2.自定义权限指令
templatediv classbtnsbutton v-has-showshop:create创建/buttonbutton v-has-showshop:edit编辑/buttonbutton v-has-showshop:delete删除/button/div
/templatescript setup langts
import { ref, reactive, } from vue
import type {Directive} from vue
//permission
localStorage.setItem(userId,xiaoman-zs)//mock后台返回的数据
const permission [xiaoman-zs:shop:edit,xiaoman-zs:shop:create,xiaoman-zs:shop:delete
]
const userId localStorage.getItem(userId) as string
const vHasShow:DirectiveHTMLElement,string (el,bingding) {if(!permission.includes(userId: bingding.value)){el.style.display none}
}/scriptstyle scoped langless
.btns{button{margin: 10px;}
}
/style3.图片懒加载 滑动到可是区域加载图片 templatedivdiv v-foritem in arrimg height500 :data-indexitem v-lazyitem width360 alt/div/div
/templatescript setup langts
import { ref, reactive } from vue
import type { Directive } from vue
const images: Recordstring, { default: string } import.meta.globEager(./assets/images/*.*)
let arr Object.values(images).map(v v.default)let vLazy: DirectiveHTMLImageElement, string async (el, binding) {let url await import(./assets/vue.svg)el.src url.default;let observer new IntersectionObserver((entries) {console.log(entries[0], el)if (entries[0].intersectionRatio 0 entries[0].isIntersecting) {setTimeout(() {el.src binding.value;observer.unobserve(el)}, 2000)}})observer.observe(el)
}/scriptstyle scoped langless/style以上个别内容收集与网络