vue-auto-focus: 控制自动聚焦行为的 vue 指令方法

在网页的表单中,经常需要用程序来控制input和textarea的自动聚焦行为。例如我最近做的一个项目,有个装箱出库的流程,input框自动聚焦的流程如下:页面进入时自动聚焦到订单号输入框->订单号扫描完毕聚焦到商品条码输入框->扫描完一个商品条码后依然停留在条码输入框->所有条码扫描完毕聚焦到订单号输入框。

为了应付这种需求,就做了这个指令,github地址: vue-auto-focus ,欢迎star。

example

<template>
 <form v-auto-focus="focusCtrl" :data-current="currentIndex" :data-action="actionType">
  <input @focus="setFocusIndex(0)" type="text" data-index="0">
  <input @focus="setFocusIndex(1)" type="text" data-index="1">
  <textarea @focus="setFocusIndex(2)" name="" id="" cols="30" rows="10" data-index="2"></textarea>
  <input @focus="setFocusIndex(3)" type="text" data-index="3">
 </form>
</template>
<style scoped>
</style>
<script type="text/babel">
 export default {
  data() {
   return {
    focusCtrl: 0, // 自动聚焦控制,变动时,执行自动聚焦指令
    currentIndex: 0, // 当前聚焦元素的索引
    actionType: 'next', // 自动聚焦的行为类型
   }
  },
  methods: {
   /**
    * 控制自动聚焦指令执行
    * @param actionType {string} 自动聚焦类型 it can be 'next'/'prev'/'first'/'last'/'jump'
    * @param index {string} 当actionType为'jump'时,需要传入将要聚焦元素的索引
    **/
   setFocus(actionType,index) {
    if (actionType === 'jump') {
     this.currentIndex = index
    }
    this.focusCtrl++
    this.actionType = actionType
   },
   /**
    * 元素聚焦时,获取当前聚焦元素的索引
    * @param index {number} 当前聚焦的索引
    **/
   setFocusIndex(index) {
    this.currentIndex = index
   },
  }
 }
</script>

行为控制

next 聚焦到下一个元素

prev 聚焦到上一个元素

first 聚焦到第一个元素

last 聚焦到最后一个元素

jump 聚焦到指定的元素

聚焦行为控制逻辑

/**
 * 聚焦行为控制
 * next 聚焦到下一个元素
 * prev 聚焦到上一个元素
 * first 聚焦到第一个元素
 * last 聚焦到最后一个元素
 * jump 跳转到指定的元素
 * @param el
 */
const focusCtrl = function (el) {
 const action = el.dataset.action
 const allFocusEls = getAllFocusEls(el)
 const focusLen = allFocusEls.length
 let current = getTargetIndex(el,allFocusEls)
 switch (action) {
  case 'next': // 如果action为next,则聚焦到下一个输入框
   if (current >= focusLen - 1) {
    current = focusLen - 1
   } else {
    current++
   }
   autoFocus(allFocusEls[current])
   break
  case 'prev': // 如果action为prev,则聚焦到上一个输入框
   if (current <= 0) {
    current = 0
   } else {
    current--
   }
   autoFocus(allFocusEls[current])
   break
  case 'first': // 如果为first,则聚焦到第一个输入框
   current = 0
   autoFocus(allFocusEls[current])
   break;
  case 'last': // 如果为last,则聚焦到最后一个输入框
   current = focusLen - 1
   autoFocus(allFocusEls[current])
   break
  case 'jump': // 如果为jump,则获取focusIndex,跳转到对应的输入框
   if (current >= 0 && current < focusLen) {
    autoFocus(allFocusEls[current])
   }
   break
 }
}

必须在需要控制的元素上添加data-index属性,需要在父元素上添加data-action属性和data-current属性,data-action为指令行为的类型(值为next,prev等),data-current为当前聚焦元素的data-index值, getAllFocusEls 方法其实就是获取所有属性为data-index的元素,代码如下:

/**
 * 获取需要聚焦的所有元素
 * @param el {Node} 指令挂载的元素
 * @returns {NodeList} 需要聚焦的元素列表
 */
const getAllFocusEls = function (el) {
 return el.querySelectorAll('[data-index]')
}

getTargetIndex 方法用来获取当前聚焦元素的在集合中的索引值,代码如下:

/**
 * 获取当前聚焦元素在集合中的位置
 * @param el
 * @param collection
 * @returns {number}
 */
const getTargetIndex = function(el,collection) {
 const target = document.querySelector(`[data-index="${el.dataset.current}"]`)
 return Array.from(collection).indexOf(target)
}

inserted

指令挂载时,自动聚焦到指定的元素

/**
 * 进入页面时,根据设置的data-index索引值,聚焦到对应的输入框
 * @param el
 */
inserted: function (el) {
 const allFocusEls = getAllFocusEls(el) // 获取需要聚焦的input元素组
 let current = getTargetIndex(el,allFocusEls)
 if (!current || current < 0 || current >= allFocusEls.length) { // 如果没有设置data-current,或者current的数值范围不符合要求,则默认聚焦到第一个输入框
  current = 0
 }
 const currentEl = allFocusEls[current]
 autoFocus(currentEl)
},

update

通过指令的value值控制指令的执行,如果值有变动,则执行指定的操作,聚焦到指定的元素

/**
 * 更新时,如果focusCtrl有变动,则根据actionType来判断聚焦的行为,聚焦到对应的元素
 * @param el
 * @param value
 * @param oldValue
 */
update: function (el,{value,oldValue}) {
 if (value !== oldValue) {
  focusCtrl(el)
 }
},

以上这篇vue-auto-focus: 控制自动聚焦行为的 vue 指令方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Vue自定义指令详解

    在 AngularJs 中,它的指令使用 directive ( name,factor_function)来实现: angular.module( 'myapp' ,[]) .directive (myDirective,function (){ return{ template : '', restrict: '', replace: '', ........ } }) 除了内置指令,Vue.js 也允许组件自定义指令. + 自定义指令提供一种机制将数据的变化映射为 DOM 行为 + Vue

  • vue 自定义指令自动获取文本框焦点的方法

    HTML: <p><b v-show="show">{{tag}}</b><input v-focus v-model="tag" :hidden="show" type="text"></p> js: 官方例子: directives: { focus: { // 指令的定义 inserted: function (el) { el.focus() } } } 我的

  • Vue自定义指令使用方法详解

    Vue自定义指令的使用,具体内容如下 1.自定义指令的语法 Vue自定义指令语法如下: Vue.directive(id, definition) 传入的两个参数,id是指指令ID,definition是指定义对象.其中,定义对象可以提供一些钩子函数 2.钩子函数 定义对象的钩子函数如下: 钩子函数的参数 el: 指令所绑定的元素,可以用来直接操作 DOM . binding: 一个对象,包含以下属性: *name: 指令名,不包括 v- 前缀. *value: 指令的绑定值, 例如: v-my

  • vue-auto-focus: 控制自动聚焦行为的 vue 指令方法

    在网页的表单中,经常需要用程序来控制input和textarea的自动聚焦行为.例如我最近做的一个项目,有个装箱出库的流程,input框自动聚焦的流程如下:页面进入时自动聚焦到订单号输入框->订单号扫描完毕聚焦到商品条码输入框->扫描完一个商品条码后依然停留在条码输入框->所有条码扫描完毕聚焦到订单号输入框. 为了应付这种需求,就做了这个指令,github地址: vue-auto-focus ,欢迎star. example <template> <form v-aut

  • vue实现权限控制路由(vue-router 动态添加路由)

    用户登录后返回权限菜单,前端根据权限菜单动态添加路由,然后再动态生成菜单栏. 思路如下: 一.定义初始化默认路由. 二.动态配置路由,这里是把所有组件中相应的路由配置成一个个的对象,根据后台返回的菜单tree一个个去匹配. 三.通过匹配,把匹配好的路由数据addRoutes到路由中. 四.为了防止刷新页面后路由数据被清空,这里用判断是否登录的方式,再次加载动态路由. 具体代码如下: router.js import Vue from 'vue' import {router} from './i

  • Vue 页面权限控制和登陆验证功能的实例代码

    页面权限控制 页面权限控制是什么意思呢? 就是一个网站有不同的角色,比如管理员和普通用户,要求不同的角色能访问的页面是不一样的.如果一个页面,有角色越权访问,这时就得做出限制了. Vue 动态添加路由及生成菜单 这是我写过的一篇文章, 通过动态添加路由和菜单来做控制,不能访问的页面不添加到路由表里,这是其中一种办法. 另一种办法就是所有的页面都在路由表里,只是在访问的时候要判断一下角色权限.如果有权限就让访问,没有权限就拒绝,跳转到 404 页面. 思路: 在每一个路由的 meta 属性里,将能

  • 解决vue点击控制单个样式的问题

    既然是控制单个样式,我们的html里面的内容一定是v-for="":渲染出来,一定要养成一个好习惯,v-for="(item,index) in items";index就是我们所说的索引. <div class="border" v-for="(item,index) in tolos" :key="index"> 我做的项目类似于微信朋友圈,弹出赞与评论按钮,点击一个全体都会弹出:我们要解决

  • Vue 技巧之控制父类的 slot

    首先来思考一个问题:是否有一种方法可以从子组件填充父组件的插槽? 最近一位同事问我这个问题,答案很简单:可以的.但我的解决方案可能和你想的完全不一样,这是涉及一个棘手的Vue架构问题,但也是一个非常有趣的问题. 为什么会有这个问题 在我们的应用程序中,我们有一个顶部栏,其中包含不同的按钮.搜索栏和其他一些控件.根据每个人所在的页面,它可能略有不同,因此我们需要一种基于每个页面配置它的方法. 为此,我们希望每个页面都能够配置操作栏.看起来很简单,但这里有个问题 这个顶部栏(我们称之为ActionB

  • vue 按钮 权限控制介绍

    目录 一.步骤 1.定义buttom权限 2.定义store 3.创建permission指令 4.使用permission指令 5.删除无权限数据 6.传入状态管理数据 二.概况 前言: 在日常项目中,会碰到需要根据后台接口返回的数据,来判断当前用户的操作权限.必须当有删除权限时,就显示删除按钮.没有这个权限时,就不显示或者删除这个按钮.通过查找资料,通过vuex来实现这个功能. 一.步骤 1.定义buttom权限 在state中创建buttomPermission,用于保存后台接口返回的权限

  • Vue路由权限控制解析

    前言 本人在公司主要负责中后台系统的开发,其中路由和权限校验算是非常重要且最为基本的一环.实际开发项目中,关于登录和路由权限的控制参照了vue-element-admin这个明星项目,并在此基础上基于业务进行了整合,接下来我会以这个项目为例,仔细地剖析整个路由和权限校验的过程,也算是对这个知识点的一些总结. 项目总体目录结构 进入今天主题之前,我们先来梳理下整个项目,src目录下的. api: 接口请求 assets: 静态资源 components: 通用组件 directive: 自定义指令

  • vue实现数据控制视图的原理解析

    这篇主要讲的就是vue很重要的一块知识点,双向数据绑定是如何实现的.一开始看这一块的内容的时候比较迷茫,迷茫在以下几个点: 这块内容该从哪边入手 数据变化是如何驱动视图层更新的 做题深化知识点 从哪边着手去看响应式原理 我这边提供三个方向,从这三个方向,你都可以看到watcher的使用,然后watcher的使用过程中,会掺杂到observer以及dep,然后以点带面,对整体进行梳理 初始化的render流程去看 在lifecycle这个文件中的mountComponent这个方法里,创建了一个w

  • vue 通过下拉框组件学习vue中的父子通讯

    如果说vue组件化开发中第一步应该了解的是什么的话,那无疑是父子组件之间是如何实现通讯的(说白了就是父子组件中数据是如何传递的),只有理解了这一步,才能更好的开发组件 这里先提出两个关键词: props 与 emit : 写这个组件之前,先看看效果图: 组件开发分析: 既然是组件: 首先组件内部数据内容肯定是可变的(如上图中的"按时间排序"之类的),这必须由父组件传入(即父组件如何将数据传个父组件); 在选择了内容之后,如何将数据传出来(即子组件如何将数据传给父组件) 先写结构: 父组

  • Vue实现Excel本地下载及上传的方法详解

    相信大家在项目中经常会遇到一些上传下载文件的相关功能,本文就Excel的相关功能进行简述: 咱直接看代码: <div class="import-main-content"> <div class="import-main-button" @click="checkFile"> <div class="import-center" style="cursor: hand">

随机推荐