【溯源篇】从头看vue(六)——自定义指令之钩子函数(超详细超多示例!!)

news/2024/7/10 1:51:29 标签: vue, html, javascript, css

自定义指令中的钩子函数

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

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

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

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

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

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

钩子函数参数(el、binding、vnode 和 oldVnode)

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

  • el:指令所绑定的元素,可以用来直接操作 DOM。
  • binding:一个对象,包含以下 property:
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive=“1 + 1” 中,绑定值为 2。
    • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    • 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:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

应用示例

1. 自动获取焦点 v-focus

javascript">// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

如果想注册局部指令,组件中也接受一个 directives 的选项:

javascript">directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}

然后可以在模板中任何元素上使用新的 v-focus property,如下:

html"><input v-focus>

2. 自定义指令之动态参数 v-change-font

javascript">	// 实现动态传值的指令(一)——<script>内使用驼峰,<body>内短横线加小写
    Vue.directive('changeFont',{
        bind:function(el, binding){
            el.style.color = binding.value
            el.style.fontSize = '20px'; // 样式也要使用驼峰
            el.style.fontFamily = 'Microsoft YaHei'; // 样式也要使用驼峰
            console.log(binding.value)
        }
    })

此指令可以更改绑定元素的字体、大小,以及动态更改颜色:

html"><input v-change-font="'orange'" type="text"/>

3.动态参数+函数简写 = v-fix 固定定位

javascript">	// 实现动态传值的指令(二)
    Vue.directive('fix',function (el, binding, vnode) { // 函数简写
            el.style.position = 'fixed'
            var s = binding.argument
            el.style[s] = binding.value + 'px'
        }
    )

此指令可以实现绑定元素的固定定位,动态接收参数固定位置top/left及px

html"><divcss"> style="height:100px">
	<p>Scroll dawn the page</p>
	<p v-fix:[direction]='20'>Stick me 200px from the top of this page</p>
</div>

4. 用了各种钩子函数参数的自定义指令 v-demo

javascript">	Vue.directive('demo',{
        bind:function(el, binding, vnode){
            var s = JSON.stringify;
            console.log(binding)
            console.log(vnode)
            el.innerHTML = 
                '自定义指令名称-name:   ' + s(binding.name) + '<br>' + 
                '自定义指令传的参数值-value:    ' + s(binding.value) + '<br>' + 
                '自定义指令传的参数值-expression:  ' + s(binding.expression) + '<br>' + 
                '属性-argument: ' + s(binding.argument) + '<br>' + 
                '包含修饰符的对象-modifiers: ' + s(binding.modifiers) + '<br>' + 
                '虚拟节点-vnode keys:  ' + Object.keys(vnode).join(', ')

        }
    })

这个指令主要为了打印看一下各种钩子函数参数:

html"><!-- 字符串形式参数——记得要加单引号否则报错 -->
<div v-demo:foo.a.b="'1+1'"></div><hr>
            
<!-- 表达式形式参数——表达式不用加单引号 -->
<div v-demo:foo.a.b="1+1"></div><hr>

效果:
在这里插入图片描述
附上全部代码,可以自己调调试试:
在这里插入图片描述

html"><!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style type="text/css">css">
        .bgcolor{
            background: #c5c551;
            padding: 20px;
            width: 100%;
            height: 400px;
            display: flex;
            flex-direction:column;
            justify-content: center;
            align-items: center;
            overflow: scroll;
            padding: 150px 35px;
        }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/html" title=vue>vue/dist/html" title=vue>vue.js" type="text/javascript" charset="UTF-8">javascript"></script>
</head>
<body>
    <template id="example">
        <div>
            <!-- v-focus、动态指令参数v-change-font -->
            <div>
                <input v-focus v-change-font="'orange'" type="text" v-model="multiplierA" />
                <input type="text" v-model="multiplierB">
                <button @click="result = multiplierA*multiplierB">The anwser is {{ result }}</button>
            </div><hr>

            <!-- 动态指令参数v-fix——固定定位 -->
            <divcss"> style="height:100px">
                <p>Scroll dawn the page</p>
                <p v-fix:[direction]='20'>Stick me 200px from the top of this page</p>
            </div><hr>
            
            <!-- 字符串形式参数——记得要加单引号否则报错 -->
            <div v-demo:foo.a.b="'1+1'"></div><hr>
            
            <!-- 表达式形式参数——表达式不用加单引号 -->
            <div v-demo:foo.a.b="1+1"></div><hr>
        </div>
    </template>
    <div class="bgcolor" id="app">
        <div>
            <do-example></do-example>
        </div>
    </div>
</body>
<script type="text/javascript">javascript">
    Vue.component("doExample",{
        data:function(){
            return{
                multiplierA: 0,
                multiplierB: 0,
                result: 0,
                direction: 'right'
            }
        },
        // 局部指令
        directives:{
            focus2:{
                inserted: function(el){
                    el.focus();
                }
            }
        },
        template: "#example"
    })

    // 全局指令
    Vue.directive('focus',{
        inserted:function(el){
            el.focus();
        }
    })

    // 实现动态传值的指令(一)——<script>内使用驼峰,<body>内短横线加小写
    Vue.directive('changeFont',{
        bind:function(el, binding){
            el.style.color = binding.value
            el.style.fontSize = '20px'; // 样式也要使用驼峰
            el.style.fontFamily = 'Microsoft YaHei'; // 样式也要使用驼峰
            console.log(binding.value)
        },
        inserted:function(el){}
    })

    // 实现动态传值的指令(二)
    Vue.directive('fix',function (el, binding, vnode) { // 函数简写
            el.style.position = 'fixed'
            var s = binding.argument
            el.style[s] = binding.value + 'px'
        }
    )

    // 用了各种钩子函数参数的自定义指令
    Vue.directive('demo',{
        bind:function(el, binding, vnode){
            var s = JSON.stringify;
            console.log(binding)
            console.log(vnode)
            el.innerHTML = 
                '自定义指令名称-name:   ' + s(binding.name) + '<br>' + 
                '自定义指令传的参数值-value:    ' + s(binding.value) + '<br>' + 
                '自定义指令传的参数值-expression:  ' + s(binding.expression) + '<br>' + 
                '暂时不存在的属性-argument: ' + s(binding.argument) + '<br>' + 
                '包含修饰符的对象-modifiers: ' + s(binding.modifiers) + '<br>' + 
                '虚拟节点-vnode keys:  ' + Object.keys(vnode).join(', ')

        }
    })

    var vm = new Vue({
        el: '#app',
        // 数据
        data:{}
    });
</script>
</html>


http://www.niftyadmin.cn/n/1486204.html

相关文章

模版引擎XTemplate与代码生成器XCoder(源码)

为什么80%的码农都做不了架构师&#xff1f;>>> 模版引擎XTemplate是一个仿T4设计的引擎&#xff0c;功能上基本与T4一致&#xff08;模版语法上完全兼容T4&#xff0c;模版头指令部分兼容&#xff09;。 自己设计模版引擎&#xff0c;就是为了代码生成器、网站模版…

如何确定所打Patch是否需要停机

Oracle在11g中提出了online patching(也可以叫做hot patch)的概念&#xff0c;有效减少了因实施one-off patch而导致的系统停机时间。但我们如何得知哪些Patch是可以online apply的&#xff0c;而哪些Patch是必须关闭实例(shutdown instance)后应用的呢&#xff1f; 下面我们就…

【溯源篇】从头看vue(七)——过滤器基础

官方文档&#xff1a;https://cn.vuejs.org/v2/guide/filters.html#ad 过滤器 自定义过滤器&#xff0c;可被用于一些常见的文本格式化。注意全局定义过滤器要在创建 Vue 实例之前。 Vue.filter(capital, function(val){value val.toString()return value.charAt(0).toUpperC…

深度工作:充分使用每一份脑力

</div><!--end: blogTitle 博客的标题和副标题 --> <div class"postBody"> <div id"cnblogs_post_body" class"blogpost-body cnblogs-markdown"><p>浮躁已经成了普遍的社会现象。判断一个人是否浮躁非常容…

VSCode生成HTML格式快捷方式

方法一&#xff1a;英文状态输入&#xff01;&#xff0c;然后按回车; 方法二&#xff1a; 输入html&#xff0c;在出来的提示中选择html:5;

Ubuntu安装UFW防火墙

sudo apt-get install ufw 一般用户&#xff0c;只需如下设置&#xff1a;sudo apt-get install ufw sudo ufw enable sudo ufw default deny 以上三条命令已经足够安全了&#xff0c;如果你需要开放某些服务&#xff0c;再使用sudo ufw allow开启。 启用 sudo ufw enable su…

【js 】通过replace看正则表达式

1. 正则表达式常用标识符 var str " welcom to Microsoft. We are proud to join that Microsoft to learn javascript. lets go on"标识符含义示例无只匹配第一个str.replace(/Microsoft/, “W3School”)/gglobal&#xff0c;全局查找&#xff0c;全局替换str.rep…

脚本 用户密码修改

一、有关用户密码的修改管理&#xff1a; 1 #!/bin/bash 2 # Description: 3 # Date: 2010-12-25 10:04:00 4 # Auth: 5 # 6 7 [ ! $USERroot ] && echo "Only root can execute " && exit 1 8 9 FILE/etc/shadow 10 let TODAY$[…