Vue.directive 实现元素scroll逻辑复用

继上篇Vue 滚动触底 mixins,将对于文档滚动触底的逻辑迁移到某个dom上,将会用到 Vue.directive 来实现代码逻辑复用。

元素滚动

如何实现滚动

元素实现滚动的条件有两个:

  • 有父子两个元素
  • 子元素的高度 > 父元素的高度, 并且父元素设置 overflow:scroll / auto;

scrollHeight 计算

Element.scrollHeight这个只读属性是一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容。

可以简单的理解为,滚动高度是元素可以滚动的最大值,分为两种情况

滚动高度 = 当前元素的 clientHeight = height + padding

滚动高度 = 当前元素的padding + 子元素的clientHeight + 子元素的(padding,margin,border) + 伪元素(:after,:before)
scrollTop

Element.scrollTop 属性可以获取或设置一个元素的内容垂直滚动的像素数。

需要注意的是,scrollTop 是针对产生滚动条的元素而言,所以分为两种情况

  • 不符合滚动条件, scrollTop 为0
  • 符合滚动条件,可以通过 Element.scrollTop 来获取它的子元素的顶部到父级元素顶部的距离,不包括(border,padding)。

判断触底

为了简单起见,假设 father 和 child 都只设置了宽高。

<div class="father" ref="father">
 <div class="child" ref="child"></div>
</div>
// 若为真说明触底
father.clientHeight + father.scrollTop >= child.scrollHeight

抽离成 Vue-directive

基本语法

参数1

指令名称,如focus 使用的时候就通过 v-focus 去绑定指定dom

参数2

options配置项,包含以下的钩子函数,分别在对应的生命周期触发

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
 bind(){
 // 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
 },
 // 当被绑定的元素插入到 DOM 中时……
 inserted: function (el) {
 // 聚焦元素
 el.focus()
 },
 update(){
 // 所在组件的 VNode 更新时调用
 },
 componentUpdated(){
 // 指令所在组件的 VNode 及其子 VNode 全部更新后调用。
 },
 unbind(){
 // 只调用一次,指令与元素解绑时调用。
 }
})

钩子函数的回调参数

上面的钩子函数都接受 el、binding、vnode 和 oldVnode 这些回调参数,对常用的参数做下解释

  • el : 指令所 绑定的元素 ,可以用来直接操作 DOM 。
  • binding : { name,value ,arg}

是绑定组件的data中的变量名

来说下 value 和 arg 的区别,假设我们想向指令传递特定的数据,可以通过下面的方式 arg传递值,和 value绑定值只能使用一种

// 通过 binding.value 接收
<div v-test="title">这里是测试</div>
// 通过 binding.arg 接收
<div v-test:id1>测试2</div>

如何注册指令

全局注册

// 在单独一个文件中单独管理所有 directive
import Vue from 'vue'
import inputClear from './input-clear'
import forNested from './picker-item-for-nested'
import copy from "./copy";

const directives = {
 copy,
 'input-clear':inputClear,
 'for-nested':forNested
}
Object.keys(directives).forEach(key=>{
 Vue.directive(key,directives[key])
})

局部注册,通过directives选项来注册

export default {
 directives:{
 // 自定义指令的名字
 autoFocus:{
  inserted(el){
  el.focus()
  console.log( 'inserted' );
  }
 }
 }
}

Vue.install的方式来安装

// directive.js
export default {
 install(Vue){
 Object.keys(directives).forEach(key=>{
  Vue.directive(key,directives[key])
 })
 }
}

// main.js
import Directives from "./directive/index";
// Vue.use 通过注册插件的方式来注册指令 `Vue 插件中 install 函数接受 Vue构造函数作为第一入参`
Vue.use(Directives);

Vue.use 源码

// 接收一个 plugin 参数可以是 Function 也可以是 Object
 Vue.use = function (plugin: Function | Object) {
 // 如果传入的是对象,需要有一个install 方法,并执行该方法
 if (typeof plugin.install === 'function') {
  plugin.install.apply(plugin, args)
 // 如果传入的是是函数则立即执行
 } else if (typeof plugin === 'function') {
  plugin.apply(null, args)
 }
 }

将scroll 逻辑添加到 v-directive 中

如果子元素有多个,需要计算每个子元素的 height + padding + border + margin 所以为了方便使用,滚动目标的子元素有多个的情况下,用一个标签统一包裹

function isBottom(el){
 const child = el.children[0]
 if(el.clientHeight + el.scrollTop >= child.scrollHeight){
 console.log('触底了');
 }
}
Vue.directive('scroll',{
 bind(el){
 el.addEventListener('scroll',function(){
  isBottom(el)
 })
 },
 unbind(el){
 el.removeEventListener(isBottom)
 }
})

总结

以上所述是小编给大家介绍的Vue.directive 实现元素scroll逻辑复用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

(0)

相关推荐

  • javascript jscroll模拟html元素滚动条

    主流浏览器默认为html元素提供的滚动条不美观,而且前端开发人员想对其通过css进行统一样式的美化也是不可实现的.比如ie可以通过样式来实现简单的美化.Webkit内核浏览器可以控制滚动条的显示效果,firefox则不允许用户为滚动条定义样式.但是对于追求友好的用户体验的前端开发人员,是不会被这些浏览器的不一致行为所阻止的.我们可以自己通过标准的html元素模拟来实现自定义的滚动条. 这里是自己在工作不太忙的时候写出来了一个用户可以自定义的滚动条jscroll,以下简称jscroll.jscro

  • jQuery固定元素插件scrolltofixed使用指南

    这个插件在前段时间用过一次,当时是改一个网站.要求顶部的菜单栏随着滚动条的滚动而固定.也大体写了一下,不过在文章中也只是提了一下,文章地址:jQuery插件固定元素位置. 在这篇文章中,再进行总结一下. 一.scrolltofixed插件功能 固定某个元素的位置,在页面滚动时,元素仍然显示. 二.scrolltofixed官方地址 https://github.com/bigspotteddog/ScrollToFixed.在官方地址上有使用说明,在下面有插件的属性方法说明.demo中也有详细的

  • Vue.directive使用注意(小结)

    指令钩子函数会被传入以下参数: el:指令所绑定的元素,可以用来直接操作 DOM . binding:一个对象,包含以下属性:vnode:Vue 编译生成的虚拟节点.移步 VNode API 来了解更多详情. ◦name:指令名,不包括 v- 前缀. ◦value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2. ◦oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用.无论值是否改变都可用. ◦e

  • Vue.directive 自定义指令的问题小结

    1.今天复习一下Vue自定义指令的代码,结果出现一个很无语的结果,先贴代码. 2. <div id="example" v-change-by="myColor"></div> <script src="vue.min.js"></script> <script> new Vue({ el:"#example", data:{ msg:"", my

  • Vue.directive自定义指令的使用详解

    很多教程都是在讲自定义指令的概念和语法,看的相当蛋疼.本文不讲语法和概念,只讲用法. 自定义指令基本就是用来操作DOM的,虽然官方推荐数据驱动视图,有时候还是需要自定义指令来操作DOM,指令可复用. 1. 自定义指令实现拖拽 HTML: <div v-drag>我可以拖拽</div> JS: Vue.directive('drag', inserted:function(el){ //inserted 钩子函数:当元素被插入父元素时触发,可省略 let oDiv=el; //el

  • Vue.directive 实现元素scroll逻辑复用

    继上篇Vue 滚动触底 mixins,将对于文档滚动触底的逻辑迁移到某个dom上,将会用到 Vue.directive 来实现代码逻辑复用. 元素滚动 如何实现滚动 元素实现滚动的条件有两个: 有父子两个元素 子元素的高度 > 父元素的高度, 并且父元素设置 overflow:scroll / auto; scrollHeight 计算 Element.scrollHeight这个只读属性是一个元素内容高度的度量,包括由于溢出导致的视图中不可见内容. 可以简单的理解为,滚动高度是元素可以滚动的最

  • Vue.directive()的用法和实例详解

    官网实例: https://cn.vuejs.org/v2/api/#Vue-directive https://cn.vuejs.org/v2/guide/custom-directive.html 指令定义函数提供了几个钩子函数(可选): bind: 只调用一次,指令第一次绑定到元素时调用,用这个钩子函数可以定义一个在绑定时执行一次的初始化动作. inserted: 被绑定元素插入父节点时调用(父节点存在即可调用,不必存在于 document 中). update: 被绑定元素所在的模板更新

  • 详解Vue.directive 自定义指令

    一.什么是全局API? 全局API并不在构造器里,而是先声明全局变量或者直接在Vue上定义一些新功能,Vue内置了一些全局API,比如我们今天要学习的指令Vue.directive.说的简单些就是,在构造器外部用Vue提供给我们的API函数来定义新的功能. 二.Vue.directive自定义指令 我们在第一季就学习了内部指令,我们也可以定义一些属于自己的指令,比如我们要定义一个v-jspang的指令,作用就是让文字变成绿色. 在自定义指令前我们写一个小功能,在页面上有一个数字为10,数字的下面

  • Vue.js+cube-ui(Scroll组件)实现类似头条效果的横向滚动导航条

    本博主在一次个人移动端项目中,遇到这么一个需求:希望自己的项目中,头部导航条的效果可以像今日头条那样,横向滚动! 对于这样的效果,在各大移动端项目中几乎是随处可见,为什么呢? 我们都知道,对于移动端也就是手机上,我们页面的宽度并不像PC端那样大,可以显示很长的导航项,但对于我们移动端来说,由于功能的拓展,或者业务的细分,往往导航项也会随之增多,一旦超过移动端在一行的页面显示宽度,那便会出现导航项换行的现象,虽说也有这样布局,但一旦导航项增多到一定程度的时候,我们的页面(首页)将均被导航项霸占,这

  • vue directive定义全局和局部指令及指令简写

    directive定义全局和局部指令以及指令简写 1.使用Vue.directive()定义一个全局指令    Vue.directive('指令名称',{对象}) 2.参数一:指令的名称,定义时指令前面不需要写v- 3.参数二:是一个对象,该对象中有相关的操作函数 4.在调用的时候必须写v- 5.自定义指令中的常用的3个钩子函数:     5.1bind:       1.指令绑定到元素上回立刻执行bind函数,只执行一次       2.每个函数中第一个参数永远是el,表示绑定指令的元素,e

  • 浅谈React中组件逻辑复用的那些事儿

    基本每个开发者都需要考虑逻辑复用的问题,否则你的项目中将充斥着大量的重复代码.那么 React 是怎么复用组件逻辑的呢?本文将一一介绍 React 复用组件逻辑的几种方法,希望你读完之后能够有所收获.如果你对这些内容已经非常清楚,那么略过本文即可. 我已尽量对文中的代码和内容进行了校验,但是因为自身知识水平限制,难免有错误,欢迎在评论区指正. 1. Mixins Mixins 事实上是 React.createClass 的产物了.当然,如果你曾经在低版本的 react 中使用过 Mixins,

  • Vue 监听元素前后变化值实例

    我就废话不多说了,大家还是直接看代码吧~ export default { data() { return { item: '' } }, watch: { item(now, before){ let remove = before.filter(x => now.indexOf(x) == -1); let add = now.filter(x => before.indexOf(x) == -1); /* 显示字符串或数组元素的增加和减少 */ console.log(add, remo

  • Vue3 composition API实现逻辑复用的方法

    Composition API实现逻辑复用的步骤: 抽离逻辑代码到一个函数,这个函数命令约定为useXXX格式(这点同React Hooks) 在setup中引用函数useXXX 举下例子,定义一个获取当前鼠标位置的方法 第一种,直接使用ref定义的useMousePosition: 这种方式,导出和导入都可以随意解构 // useMousePosition.js import { ref, onMounted, onUnmounted } from 'vue' // 1. 定义一个函数,抽离逻

随机推荐