赞
踩
除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令,
自定义局部指令和自定义全局指令:
1.自定义局部指令:在options api选项中的directives中设置
2.自定义全局指令:在app的directive的方法
官网给出的是一个input框聚焦案例,不太明白怎么用的建议去看一下,链接就是上面的那个
钩子函数:
一个指令定义对象可以提供如下几个钩子函数
1.bind:只调用一次,指令第一次绑定到元素时调用,在这里可以进行一次性的初始化设置
2.inserted:被绑定元素插入父节点时调用(保证父节点存在,但不一定已被插入文档中)
3.update:所在组件的vnode更新时调用,但是可能发生在其子vnode更新之前,指令的值可能发生了改变,也可能没有,但是你可以通过比较更新前后的值来忽略不必要的模板更新
4.componentUpdated:指令所在组件的vnode及其子vnode全部更新后调用
5.unbind:只调用一次,指令与元素解绑时调用
下面是指令的封装:
1.节流 2.防抖 3.element-ui的无限滚动在el-table上使用的封装
1.节流
// 引入节流插件
import throttleCall from 'lodash/throttle'
export default{
bind(el,binding,vnode){
const fn=binding.value // 通过参数拿到click事件触发的函数
// 节流处理后的函数,默认3000ms
const throttled=throttleCall(fn,3000,{leading:true,trailing:false})
el.addEventListener('click',throttled) // 绑定上
el._throttled=throttled // 把函数赋值到el 对象上,方便其他钩子函数访问
},
unbind(el){
// 指令与元素解绑时,解绑事件
el.removeEventListener('click',el_debounced)
}
}
1.全局引入在main.js
import throttleClick from './drectives/throttle-click'
Vue.directive('throttle-click',throttleClick)
然后就可以直接使用
<el-button v-throttle-click="test">节流测试</el-button>
2.局部注册,在用到的组件内注册并使用,使用如上,下面局部注册引用
import throttleClick from '@drectives/throttle-click'
export default{
directives:{throttleClick}
}
2.基于防抖在按钮不可点击的时候同时置灰按钮
export default {
inserted(el,binding){
el.addEventListener('click',(e)=>{
el.classList.add('is-disabled')
el.disabled=true
setTimeout(()=>{
el.disabled=false
el.classList.remove('is-disabled')
},3000)
})
}
}
1.全局引入在main.js
import noMoreClick from './drectives/no-more-click'
Vue.directive('no-more-click',noMoreClick)
然后就可以直接使用
<el-button v-no-more-click="test">节流测试</el-button>
2.局部注册,在用到的组件内注册并使用,使用如上,下面局部注册引用
import noMoreClick from '@drectives/no-more-click'
export default{
directives:{noMoreClick}
}
3.table-infinite-scroll 对element-ui的无限滚动在el-table使用的封装
table表格实现表格数据动态滚动(无限滚动)
// 对element-ui的无限滚动 在el-table上使用的封装 import elInfiniteScroll from 'element-ui/lib/infinite-scroll' const elScope ='ElInfiniteScroll' // scrope name const msgTitle = `[el-table-infinite-scroll]` // messsage title const elTableScrollWrapperClass = '.el-table__body-wrapper' export default{ inserted(el,binding,vnode,oldVnode){ // 获取 table的滚动层 const scrollElem =el.querySelector(elTableScrollWrapperClass) // 如果没找到元素,返回错误 if(!scrollElem){ throw new Error(`${mesTitle}找不到 ${elTableScrollWrapperClass}容器`) } // 设置自动滚动 scrollElem.style.overflowY='auto' // dom渲染后 setTimeout(()=>{ if(!el.style.height){ scrollElem.style.height='400px' console.warn(`${msgTitle}请尽量设置 el-table的高度,可以设置为auto/100%(自适应高度),为设置会取400px的默认值,不然会导致一直加载`) } asyncElOptions(vnode,el,scrollElem) // 绑定 infinote-scroll elInfiniteScroll.inserted(scrollElem,binding,vnode,oldVnode) // 将子集的引入放入el上,用于 unbind中销毁事件 el[elScope]=scrollElem[elScope] },0) }, componentUpdated(el,binding,vnode){ asyncElOptions(vnode,el,el.querySelector(elTableScrollWrapperClass)) }, unbind:elInfiniteScroll.unbind } /** * 同步 el-infinite-scroll 的配置项 * @param sourceVnode * @param sourceElem * @param targetElem */ function asyncElOptions(sourceVnode,sourceElem,targetElem){ const context =sourceVnode.context let value ['diasble','delay','immediate'].forEach((name)=>{ const myName='infinite-scroll-'+name value= sourceElem.getAttribute(myName) if(value!==null){ targetElem.setAttribute(myName,context[value] || value) } }) // 问题解决: window/chrome 的scrollTop+clientHeight 与scrollHeight 不一致的bug const name = 'infinite-scroll-distance' value= sourceElem.getAttribute(name) value =context[value] || value targetElem.setAttribute(name,value<1?1:value) }
局部注册并使用
<template> <el-table v-table-infinite-scroll="loadMore" :data='scrolllist' height="500px"> <el-table-column prop='data' label="日期" align='center'></el-table-column> <el-table-column prop='grade' label="班级" align='center'></el-table-column> <el-table-column prop='name' label="姓名" align='center'></el-table-column> <p v-if="isLoading" align='center'>加载中...</p> <p v-if="noMore" align='center'>没有更多了...</p> </template> export default{ directives:{tableInfiniteScroll} data(){ return { scrolllist:[], // 具体调接口赋值不再展示 loading:false, noMore:false } }, methods:{ // 上拉刷新加载 loadMore(){ if(this.isLoading){ return } if(this.noMore){ // 数组已加载完毕 return } this.isLoading=true setTimeout(()=>{ // 调接口更新数据,如果接口没有数据会设置this.noMore状态 this.isLoading=false },100) } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。