vue如何自定义全局/私有按键修饰符、过滤器和指令

一、vue中自定义全局按键修饰符?

前面学习了事件修饰符,那么什么是按键修饰符?

在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

<input v-on:keyup.enter="submit">

只有在键盘按键按 Enter(回车)键时,才会触发调用 submit() 方法。

你也可以直接将 KeyboardEvent.key 暴露的任意有效按键名转换为 kebab-case 来作为修饰符:

<input v-on:keyup.page-down="onPageDown">

在上述示例中,处理函数只会在 $event.key 等于 PageDown 时被调用。

接下来了解一下 按键码

keyCode 的事件用法已经被废弃了并可能不会被最新的浏览器支持。

使用 keyCode attribute 也是允许的:

<input v-on:keyup.13="submit">

为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:

.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right

 有一些按键 (.esc 以及所有的方向键) 在 IE9 中有不同的 key 值, 如果你想支持 IE9,这些内置的别名应该是首选。

如果上面的常用按键都不是想要的,如果想要自定义按键修饰符别名怎么办呢?

此处 113 是 f2 按键对应的键码值

// 自定义全局按键修饰符
Vue.config.keyCodes.f2 = 113

使用的时候:

<input type="text" v-model="name" @keyup.f2="add">

常见键盘按键对应键码值大全可以参考这个链接:https://www.cnblogs.com/wuhua1/p/6686237.html


1.x中自定义键盘修饰符【了解即可】

Vue.directive('on').keyCodes.f2 = 113;

2.x中自定义键盘修饰符

  •  通过`Vue.config.keyCodes.名称 = 按键值`来自定义案件修饰符的别名:

Vue.config.keyCodes.f2 = 113;
  • 使用自定义的按键修饰符:
<input type="text" v-model="name" @keyup.f2="add">

二、自定义全局过滤器

所谓的全局过滤器,就是所有的VM实例都共享的。

Vue.filter('myFilter', function (data) {
    return data + '123'
}) 

 怎么调用?

<h3>{{ dt | myFilter}}</h3>
// data 中 dt: new Date()

过滤器调用时候的格式    {{ name | 过滤器的名称 }} ,其中 | 符号,我们称为 管道符

// 过滤器的定义语法
// Vue.filter('过滤器的名称', function(){})

// 过滤器中的 function ,第一个参数,已经被规定死了,永远都是 过滤器 管道符前面 传递过来的数据
/* 
    Vue.filter('过滤器的名称', function (参数) {
          return 要做的操作
    }) 
*/

过滤器中的 function 可以设置默认参数值,这里 pattern 默认为空值

Vue.filter('dateFormat', function (dateStr, pattern = "") {
      // do something ...
})

三、定义私有过滤器

 有了全局过滤器,当然也可以有私有(局部)过滤器,所谓私有就是只能在 当前 VM 对象所控制的 View 区域进行使用

// 如何自定义一个私有的过滤器(局部)
    var vm2 = new Vue({

      el: '#app2',
      data: {},
      methods: {},
      filters: {
        dateFormat: function (data) {
            return data + '123'
        }
      }

    })

 私有过滤器只需要定义一个 filters 字段,在里面设置过滤器名称然后定义方法即可。

那么当全局过滤器和局部过滤器同时存在且同名时,调用的时候调用的是全局的过滤器还是局部的呢?

答:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!

四、自定义全局指令

前面学过很多关于 vue 的指令:v-cloak, v-text, v-html, v-on, v-bind, v-for, v-if, v-show, v-model等等

有没有发现 vue 中的指令都是以 v- 开头

所以有一个约定就是 Vue中所有的指令,在调用的时候,都以 v- 开头

我们要定义全局指令的时候需要使用到  Vue.directive()

其中:

  • 参数1 : 指令的名称,注意,在定义的时候,指令的名称前面,不需要加 v- 前缀,(但是在调用的时候,必须在指令名称前 加上 v- 前缀来进行调用)
  • 参数2: 是一个对象,这个对象身上,有一些指令相关的函数,这些函数可以在特定的阶段,执行相关的操作

 假设我们进入某个页面,要使某个输入文本框获得焦点,通常用 js 我们的操作是:

document.getElementById('search').focus()

但是在 vue 中,我们可以通过自定义一个 自动获取焦点 的指令来实现

先上代码:

Vue.directive('focus', {
      bind: function (el) { 

      },
      inserted: function (el) {  
        el.focus()
      },
      updated: function (el) {  

      }
})

看不懂代码?那么在这里就要了解一下 钩子函数 这个东西了(参考 vue 官网教程)

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。

接下来我们来看一下钩子函数的参数 (即 elbindingvnodeoldVnode)。


钩子函数参数

指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM 。
  • binding:一个对象,包含以下属性:
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
    • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
  • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
  • oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。

除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 来进行。


回到代码上,为什么 el.focus() 放在了 inserted 函数中?

  • 每当指令绑定到元素上的时候,会立即执行这个 bind 函数,只执行一次。在元素 刚绑定了指令的时候,还没有 插入到 DOM中去,这时候,调用 focus 方法没有作用

  • 一个元素,只有插入DOM之后,才能获取焦点(inserted 表示元素 插入到DOM中的时候,会执行 inserted 函数【触发1次】)

  • 和JS行为有关的操作,最好在 inserted 中去执行

自定义一个 设置字体颜色 的指令,怎么做?

Vue.directive('color', {
     
      bind: function (el, binding) {

        // el.style.color = 'red'
        console.log(binding.name)
        console.log(binding.value)
        console.log(binding.expression)

        el.style.color = binding.value
      }

})

调用:

<h3 v-color="'green'">哈哈</h3>

看看控制台都输出了什么:

那么在这里为什么颜色的设置写在了 bind 函数中呢? 

  • 样式,只要通过指令绑定给了元素,不管这个元素有没有被插入到页面中去,这个元素肯定有了一个内联的样式

  • 将来元素肯定会显示到页面中,这时候,浏览器的渲染引擎必然会解析样式,应用给这个元素

  • 和样式相关的操作,一般都可以在 bind 执行

五、自定义私有指令

和私有过滤器的定义类似,也是加一个字段,这个字段就是 directives

var vm2 = new Vue({
      el: '#app2',
      data: {},
      methods: {},
      directives: { // 自定义私有指令
        'fontweight': { // 设置字体粗细的
          bind: function (el, binding) {
            el.style.fontWeight = binding.value
          }
        },
        'fontsize': function (el, binding) { // 注意:这个 function 等同于 把 代码写到了 bind 和 update 中去
          el.style.fontSize = parseInt(binding.value) + 'px'
        }
      }
    })

注意这里用了两种不同的写法 

调用的时候:

<h3 v-color="'pink'" v-fontweight="900" v-fontsize="50">哈哈</h3>

 关于同名调用的优先级和过滤器中一样,就近原则。

发布了7 篇原创文章 · 获赞 4 · 访问量 556

猜你喜欢

转载自blog.csdn.net/control_ling/article/details/104441779