首页 > 其他分享 >Vue 2x 系列之(十七)自定义指令

Vue 2x 系列之(十七)自定义指令

时间:2024-02-29 19:45:29浏览次数:30  
标签:Vue 自定义 2x value element 指令 input bingding

自定义指令

从某种程度上来说,Vue中的自定义指令就是把原生DOM操作进行了一次封装

指令是不能脱离元素【标签】存在的

定义指令:big

使用指令:v-big

值的写法:对象【可以处理一些细节上的问题】和函数

定义指令可以通过两种方式,函数式和对象式

1. 函数式

指令名(真实DOM元素[element], 绑定对象[bingding]){

}

真实DOM元素[element]:指令所在的元素

注:element instanceof HTMLElement 可以证明element是真实DOM元素,除了这种方法可以证明,console.dir(element)也可以看到element拥有所有真实DOM的属性和方法,也能够说明element是真实DOM元素

绑定对象[bingding]有几个重要的属性:

  • value:指令接收到的表达式的值
  • expression:指令接收到的表达式
  • name:指令名
  • rawName:使用指令时要用的名字

函数式指令何时会被调用?

1.指令与元素成功绑定时(一上来)【指令与元素绑定成功仅仅代表着在内存里面建立了指令与元素之间的关系,元素此时还没有被放到页面上】。

2.指令所在的模板被重新解析时。

2. 对象式

DOM操作可分为两类操作

  • 元素放到页面之前和放到页面之后进行该操作效果是一样的,比如给text类型的input框设置value,放到页面之前进行设置value的操作和将input框放到页面之后再进行设置value的操作结果是相同的。

  • 元素放到页面之后进行该操作才能够生效,比如让text类型的input框获取焦点,input框还没放到页面上呢,是不可能进行获取焦点的操作的。【这些操作时机很重要,时机不对,操作不会生效】

    <body>
    	<button type="button" id="btn">点击增加一个input框</button>
    	<script type="text/javascript" charset="utf-8">
    		// 拿到id为btn的element元素
    		const btn = document.getElementById('btn')
    		
    		// 给btn元素绑定单击事件
    		btn.onclick = () =>{
    			
    			// 创建一个input框【此时还没放到页面上】
    			const input = document.createElement('input')
    			
    			// input框放到界面上之前为input框设置值【操作可以生效】
    			input.value = 99
    			
    			// input框放到界面上之前为input框设置类名,引用样式【操作可以生效】
    			input.className = 'demo'
    			
    			// input框放到界面上之前为input框绑定单击事件【操作可以生效】
    			input.onclick = () =>{
    				alert(1)
    			}
    			
    			// input框放到界面上之前设置input框父级元素的背景色样式【操作不可以生效】
    			// input.parentElement.style.backgroundColor = '#FF0000'
                
                
                 // 放在这里是获取不到焦点的,获取焦点的操作有个前提是元素必须已经在页面上了
    			// input框放到界面上之前让input框获取焦点【操作不可以生效】
    			// input.focus()
    			
    			// 将input框放到body中【这一步就放到了页面上】
    			document.body.appendChild(input)
              
    			// input框放到界面上之后设置input框父级元素的背景色样式【操作可以生效】
    			input.parentElement.style.backgroundColor = '#FF0000'
              
              	 // input框已经放到页面上了,所以能够获取到焦点 
              	 // input框放到界面上之后让input框获取焦点【操作可以生效】
              	 input.focus()
    		}
    	</script>
    </body>
    

对象式自定义指令中,包含了若干个钩子函数,这些钩子函数的名称是固定的,Vue在特定时间点会调用我们定义的钩子函数

常用的钩子函数

  • bind(element, bingding):指令与元素成功绑定时(一上来)被Vue调用【此时元素已经有了,指令也与元素进行了绑定,但还没放到页面上】
  • inserted(element, bingding):指令所在元素被插入页面时被Vue调用【此时元素已经被放到了页面上】
  • update(element, bingding):指令所在的模板被重新解析时被Vue调用

注:bind()和update()中的操作一般都是相同的,函数式自定义指令相当于对象式自定义指令的简写方式,这种方式中仅仅定义了bind()和update()两个钩子函数

<body>
	<div id="root">
		<h2>n的值是:{{n}}</h2>
		<h2>n放大后的值是:<span v-bing="n"></span></h2>
		<button type="button" @click="n++">n++</button><br>
		<input type="text" v-fbind:value="n"/>
	</div>
	<script type="text/javascript">
	
		//阻止 vue 在启动时生成生产提示。
		Vue.config.productionTip = false	 
		
		const vm = new Vue({
			el: "#root",
			data:{
				n: 1
			},
			computed: {
			},
			methods: {
			},
			// 定义指令
			directives: {
				bing(element, bingding){
					// element.innerText:当前元素的文本内容
					element.innerText = bingding.value * 10
					console.log(element,bingding)
				},
				// fbind(element, bingding){
				// 	element.value = bingding.value
					
					// 初次加载未成功获取到焦点:该函数初次调用是在指令与元素进行绑定时,此时页面上还没有input框,所以无法绑定
					// 点击按钮修改n值后成功获取到焦点:修改n值后,模板重新解析,该函数重新调用,此时页面上已经存在input框了,所以成功绑定
					// 函数式指令函数执行的时机是固定的,指令与元素成功绑定时(一上来)和指令所在的模板被重新解析时
					// 要想初次加载就能获取到焦点,必须在Vue将元素放到页面上之后再执行获取焦点的操作
				// 	element.focus()
				// }
				
				fbind: {
					bind(element, bingding){
						element.value = bingding.value
					},
					inserted(element, bingding){
						element.focus()
					},
					update(element, bingding){
						element.value = bingding.value
					}
				}
			}
		})
	</script>
</body>

3. 几个坑

  1. 指令名命名,如果指令名包含了多个单词【比如bignumber】,多个单词之间要用'-'连接,'big-number'

    如果对象中的key包含了'-'这个符号,key值就要用引号包裹起来''

  2. 指令回调函数【对象式中的bind、inserted、update和函数式】中的this都是window

  3. Vue实例中定义的directives指令都是局部指令,其他Vue实例中用不了

<body>
	<div id="root">
		<h2>n的值是:{{n}}</h2>
		<h2>n放大后的值是:<span v-bing="n"></span></h2>
		<button type="button" @click="n++">n++</button><br>
		<input type="text" v-fbind:value="n"/>
	</div>
	
	<div id="root2">
		<span v-bing="x"></span>
	</div>
	<script type="text/javascript">
	
		//阻止 vue 在启动时生成生产提示。
		Vue.config.productionTip = false	 
		
		//定义函数式全局指令
		Vue.directive('bing', function(element, bingding){
			element.innerText = bingding.value * 10
		})
		
		//定义对象式全局指令
		Vue.directive('fbind',{
			bind(element, bingding){
				console.log(this)
				element.value = bingding.value
			},
			inserted(element, bingding){
				console.log(this)
				element.focus()
			},
			update(element, bingding){
				console.log(this)
				element.value = bingding.value
			}
		})
		
		const vm = new Vue({
			el: "#root",
			data:{
				n: 1
			},
			computed: {
			},
			methods: {
			},
			// 定义局部指令
			directives: {
				// 定义函数式局部指令
				// bing(element, bingding){
				// 	// element.innerText:当前元素的文本内容
				// 	element.innerText = bingding.value * 10
				// 	console.log(element,bingding)
				// 	console.log(this)
				// },
				
				// 定义对象式局部指令
				// fbind: {
				// 	bind(element, bingding){
				// 		console.log(this)
				// 		element.value = bingding.value
				// 	},
				// 	inserted(element, bingding){
				// 		console.log(this)
				// 		element.focus()
				// 	},
				// 	update(element, bingding){
				// 		console.log(this)
				// 		element.value = bingding.value
				// 	}
				// }
			}
		})
		
		new Vue({
			el: '#root2',
			data:{
				x: 2
			}
		})
	</script>
</body>

4. 总结

自定义指令总结:
	一、定义语法:
		(1).局部指令:
			new Vue({									new Vue({
				directives:{指令名:配置对象}   或   			directives{指令名:回调函数}
			}) 											})
		(2).全局指令:
			Vue.directive(指令名,配置对象) 或   Vue.directive(指令名,回调函数)

	二、配置对象中常用的3个回调【钩子函数】:
		(1).bind:指令与元素成功绑定时调用。
		(2).inserted:指令所在元素被插入页面时调用。
		(3).update:指令所在模板结构被重新解析时调用。

	三、备注:
		1.指令定义时不加v-,但使用时要加v-;
		2.指令名如果是多个单词,要使用kebab-case命名方式【短横线命名】,不要用camelCase命名。【驼峰命名】

标签:Vue,自定义,2x,value,element,指令,input,bingding
From: https://www.cnblogs.com/wzzzj/p/18045284

相关文章

  • Vue 2x 系列之(十六)内置指令
    内置指令我们学过的指令: v-bind :单向绑定解析表达式,可简写为:xxx v-model :双向数据绑定 v-for :遍历数组/对象/字符串 v-on :绑定事件监听,可简写为@ v-if :条件渲染(动态控制节点是否存存在) v-else :条件渲染(动态控制节点是否存存在) v-show :......
  • Vue 2x 系列之(十九)Vue组件化编程
    Vue组件化编程一、对组件的理解什么是组件?组件的定义:​ 实现应用中局部【组件要拆的尽量细致】功能代码【对于前端来说,就是css+html+js】和资源【mp3、mp4、ttf、.zip...】的集合【组件是一个集合】与传统方式编程相比,组件化编程有什么优势?依赖关系不混乱、好维护、代码......
  • Vue 2x 系列之(十八)生命周期
    生命周期[函数]......
  • Vue 2x 系列之(二十)一些注意点
    一些注意点vue基础vue-cli:工程化开发vue-router:在Vue中实现前端路由vuex:应用足够复杂时,用于保管数据element-uivue3Angular==》React==》Vue生命周期函数中的this都是vm开发中自行向vm身上追加属性时【场景:比如methods中要访问mounted钩子中的变量】,避免追加敏感......
  • Vue2.x生命周期函数
    介绍Vue.js2.x中的生命周期函数是一系列钩子函数,它们允许你在Vue实例的不同阶段执行代码。这些生命周期钩子函数允许你在特定的阶段添加自定义逻辑,以便在应用程序生命周期的不同点执行操作。创建阶段1)beforeCreate(创建前):在Vue实例初始化之后,数据观测(dataobs......
  • Vue中组件和插件有什么区别?
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助一、组件是什么回顾以前对组件的定义:组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式,在Vue中每一个.vue文件都可以视为一个组件组件的优势降低整个系统的耦合度,在保持接口不变的......
  • jsp自定义标签
    一、自定义标签的作用自定义标签主要用于移除Jsp页面中的java代码。二、自定义标签开发和使用2.1、自定义标签开发步骤1、编写一个实现Tag接口的Java类(标签处理器类)1packageme.gacl.web.tag;23importjava.io.IOException;45importjavax.servl......
  • Vue学习笔记25--过滤器(日期格式化)
    日期格式化日期格式化插件:https://www.bootcdn.cn/moment.js、day.js(轻量级moment.js)插件用法:双击day.js==>复制链接并访问==》另存为dayjs.min==》项目中引用https://github.com/iamkun/dayjs/blob/dev/docs/zh-cn/README.zh-CN.md过滤器总结:定义:对要显示的数据进行......
  • Vue源码解读:响应式原理
    Vue一大特点就是数据响应式,数据的变化会作用于视图而不用进行DOM操作。原理上来讲,是利用了Object.defifineProperty(),通过定义对象属性setter方法拦截对象属性的变更,从而将属性值的变化转换为视图的变化。在Vue初始化时,会调用initState,它会初始化props,methods,data,......
  • vue3笔记 computed计算属性
    计算属性有缓存的,方法没有缓存下列的计算案例是只读的,不可修改的 上述代码为只读属性,优化后<scriptsetuplang="ts">import{ref,computed}from'vue'letname=ref("zhang")letxing=ref("sang")console.log(name.value)letfullName=compute......