vue2指令的使用和自定义指令

前言

个人认为vue的指令,对比react来说,给开发者节省了很大的学习成本。比如在react中,你想渲染一个列表,需要用Array.map的方法return<div>,而在vue中,一个简单的v-for就解决了问题。

在学习成本和入手体验上,vue的作者确实后来者居上,能让人更快的使用vue开发。不过也是老生常谈的问题,各有特点,不做过多比较。

vue中的指令是用在标签上或者组件上,是ui层和数据层的交互介质。这个官方没有这么说,是我自己说的,比如你使用v-if,通过data去控制ui,使用v-model实现ui和data的双向交互。

我这里并不是指令的具体教程,只是一些demo的测试效果。

示例

这里我将指令分为三块

简单指令:学习简单,使用简单

复杂指令:可以在组件上使用,或者有修饰符等

自定义指令:自定义一些指令去实现某些业务功能

简单指令

v-text

用来回显常规字符串的

 <h6>v-text使用</h6><p>使用v-text----<span v-text="textValue"></span></p><p>使用模板语法----<span>{{ textValue }}</span></p>//datatextValue: '这是一段常规文字',

 效果

v-html

用来回显html的节点

<h6>v-html使用</h6>
<div v-html="htmlTemplate"></div>//data
htmlTemplate: `<div><input/><button>按钮</button></div>`

效果

v-show

用来控制元素的样式回显

<h6>v-show使用</h6>
<el-checkbox v-model="checkedValue">开关</el-checkbox>
<p v-show="checkedValue">开启</p>
<p v-show="!checkedValue">关闭</p>//data
checkedValue: true,

效果

 v-if & v-else-if & v-else

 用来控制元素的渲染

<h6>v-if && else-if && else的使用</h6>
<p>数字:{{ numValue }}</p>
<el-button @click="addNum">增加</el-button>
<el-button @click="deleteNum">减少</el-button>
<p v-if="numValue > 0">大于0</p>
<p v-else-if="numValue === 0">等于0</p>
<p v-else>小于0</p>//data
numValue: 0,//methods
addNum() {this.numValue++
},
deleteNum() {this.numValue--
},

 

 v-for

渲染数组类型

                    <h6>v-for使用</h6><ul><li v-for="(item, index) in listValue" :key="item.value">{{ item.label }}</li></ul>//datalistValue: [{label: '文字1',value: 'one'},{label: '文字2',value: 'two'},{label: '文字3',value: 'three'}],

v-pre

跳过对js等变量的编译,渲染原始html

                    <h6>v-pre使用</h6><p v-pre>我是不需要编译的<span>{{ textValue }}</span></p>//datatextValue: '这是一段常规文字',

v-cloak

渲染完成之前的一种替代(网速慢优化策略)

                    <h6>v-cloak使用</h6><p v-cloak>{{ textValue }}</p>

v-once

元素只会渲染一次,更新不会重新渲染

                    <h6>v-once使用</h6><el-button @click="changeNumberVal">修改值</el-button><p v-once>不变的:{{ numberVal }}</p><p>变化的的:{{ numberVal }}</p>//data
numberVal: 100,//methodschangeNumberVal() {this.numberVal++},

复杂指令

v-on

用来处理事件的

简写和动态事件
<h6>v-on使用(简写为@)</h6>
<el-button v-on:click="clickFun">常规点击</el-button>
<el-button @click="clickFun">简写常规点击</el-button>
<el-button v-on:[eventName]="clickFun">动态事件</el-button>
<el-button @[eventName]="clickFun">动态事件简写</el-button>
<el-button @click.once="clickFun">只生效一次</el-button>//methodsclickFun() {console.log('常规点击')},

依次点击按钮,最后一个按钮点击只触发依次

 

 阻止默认事件
<a href="http://www.baidu.com" @click="clickFun"><el-button>无限制跳转</el-button></a>
<a href="http://www.baidu.com" @click.prevent="clickFun"><el-button>阻止默认事件</el-button></a>//methodsclickFun() {console.log('常规点击')},

第一个按钮会先触发函数,再跳往至百度页面。

第二个按钮只会触发函数,不会跳转页面。

阻止事件冒泡
<span @click="clickSpanFun"><el-button @click="clickFun">节点嵌套事件冒泡</el-button></span>
<span @click="clickSpanFun"><el-button @click.stop="clickFun">阻止事件冒泡</el-button></span>//methodsclickFun() {console.log('常规点击')},clickSpanFun() {console.log('点击span标签')},

点击按钮1

点击按钮2

 其他事件和点击组件的修饰符
<input v-model="inputValue" @keyup.enter="inputEventFun" type="text">
<el-input v-model="inputValue" @keyup.native.enter="inputEventFun"></el-input>
<Child @click.native="componentClick"></Child>
v-bind

动态渲染值

<h6>v-bind使用</h6>
<p v-bind:class="className">动态class</p>
<p :style="styleName">动态样式加简写</p>
<el-button :name1="name1" :name2="name2" name3="属性3" ref="btn1" @click="checkBtn1">查看element按钮组件的自定义属性</el-button>
<button :name1="name1" :name2="name2" name3="属性3" ref="btn2" @click="checkBtn2">查看原生dom的自定义属性</button>//dataname1: '属性1',name2: JSON.stringify({value: '属性3'}),

 

依次点击两个按钮

v-model

输入框类型数据视图双向绑定

<h6>v-model使用</h6>
<p>常规v-model<el-input v-model="InputVal"></el-input></p>
<p>lazy修饰符<input v-model.lazy="InputLazyVal" @input="inputLazyFun" /></p>
<p>number修饰符<el-input v-model.number="InputNumberVal"></el-input></p>
<p>trim修饰符<el-input v-model.trim="InputTrimVal"></el-input></p>

v-slot

插槽,这里不说了,看插槽相关的文档吧

自定义指令

语法

全局注册和局部注册

局部注册

局部注册就是在当前组件里面写

<template><div><h6>固定颜色指令</h6><p v-color>固定红色的指令效果</p></div>
</template><script>export default{data(){return{
}
},directives: {color: {// 指令的定义inserted: function (el) {el.style.color = 'red'}}},
}</script>

全局注册

创建一个js文件并在main.js中引入 

import Vue from 'vue'Vue.directive('setColor',{//初始化钩子inserted:function(el,val,vnode){console.log(el,val,vnode,'???自定义函数')el.style.color = val.value || '#000'},//更新钩子update:function(el,val,vnode){console.log(el,val,vnode,'???自定义函数')el.style.color = val.value || '#000'},
})

引入后,任意组件内都可以使用

<h6>自定义颜色</h6>选择一个颜色吧:<el-color-picker v-model="colorValue"></el-color-picker><p v-setColor="colorValue">我是一段可选择颜色的字段</p>//data
colorValue:'#000'

 定义一个可拖拽的指令

vue组件

<h6>可拖拽指令</h6>
<div class="dragBox"><div class="dragContent" v-draggable></div>
</div><style lang="less">.dragBox {position: relative;width: 800px;height: 200px;border: 1px solid #000;.dragContent {position: absolute;width: 50px;height: 50px;background: red;cursor: move;left: 10px;top: 10px;}
}
</style>

定义指令

Vue.directive('draggable',{inserted: function (el) {el.onmousedown = function (e) {var disx = e.pageX - el.offsetLeft;var disy = e.pageY - el.offsetTop;document.onmousemove = function (e) {el.style.left = e.pageX - disx + 'px';el.style.top = e.pageY - disy + 'px';}document.onmouseup = function () {document.onmousemove = document.onmouseup = null;}}},
})

 

自定义指令在实际的项目中还是很重要的,可以实现很多的业务场景。

比如我个人就用指令完成过水印效果,拖拽,按钮权限的控制等,学会自定义指令,也是多少需要复习一下很多人抛弃已久的dom基础知识。

全部代码

vue组件

<template><div class="box"><el-tabs v-model="activeName"><el-tab-pane label="简单指令(不需要修饰符)" name="first"><div class="content1"><h6>v-text使用</h6><p>使用v-text----<span v-text="textValue"></span></p><p>使用模板语法----<span>{{ textValue }}</span></p></div><div class="content1"><h6>v-html使用</h6><div v-html="htmlTemplate"></div></div><div class="content1"><h6>v-show使用</h6><el-checkbox v-model="checkedValue">开关</el-checkbox><p v-show="checkedValue">开启</p><p v-show="!checkedValue">关闭</p></div><div class="content1"><h6>v-if && else-if && else的使用</h6><p>数字:{{ numValue }}</p><el-button @click="addNum">增加</el-button><el-button @click="deleteNum">减少</el-button><p v-if="numValue > 0">大于0</p><p v-else-if="numValue === 0">等于0</p><p v-else>小于0</p></div><div class="content1"><h6>v-for使用</h6><ul><li v-for="(item, index) in listValue" :key="item.value">{{ item.label }}</li></ul></div><div class="content1"><h6>v-pre使用</h6><p v-pre>我是不需要编译的<span>{{ textValue }}</span></p></div><div class="content1"><h6>v-cloak使用</h6><p v-cloak>{{ textValue }}</p></div><div class="content1"><h6>v-once使用</h6><el-button @click="changeNumberVal">修改值</el-button><p v-once>不变的:{{ numberVal }}</p><p>变化的的:{{ numberVal }}</p></div></el-tab-pane><el-tab-pane label="复杂指令" name="second"><div class="content2"><h6>v-on使用(简写为@)</h6><el-button v-on:click="clickFun">常规点击</el-button><el-button @click="clickFun">简写常规点击</el-button><el-button v-on:[eventName]="clickFun">动态事件</el-button><el-button @[eventName]="clickFun">动态事件简写</el-button><el-button @click.once="clickFun">只生效一次</el-button><br><a href="http://www.baidu.com" @click="clickFun"><el-button>无限制跳转</el-button></a><a href="http://www.baidu.com" @click.prevent="clickFun"><el-button>阻止默认事件</el-button></a><br><p @click="clickPFun"><span @click="clickSpanFun"><el-button @click="clickFun">节点嵌套事件冒泡</el-button></span><span @click="clickSpanFun"><el-button @click.stop="clickFun">阻止事件冒泡</el-button></span></p><br><input v-model="inputValue" @keyup.enter="inputEventFun" type="text"><el-input v-model="inputValue" @keyup.native.enter="inputEventFun"></el-input><Child @click.native="componentClick"></Child><br><button v-on="{ mousedown: mousedownFun, mouseup: mouseUpFun }">对象语法</button></div><div class="content2"><h6>v-bind使用</h6><p v-bind:class="className">动态class</p><p :style="styleName">动态样式加简写</p><el-button :name1="name1" :name2="name2" name3="属性3" ref="btn1"@click="checkBtn1">查看element按钮组件的自定义属性</el-button><button :name1="name1" :name2="name2" name3="属性3" ref="btn2" @click="checkBtn2">查看原生dom的自定义属性</button></div><div class="content2"><h6>v-model使用</h6><p>常规v-model<el-input v-model="InputVal"></el-input></p><p>lazy修饰符<input v-model.lazy="InputLazyVal" @input="inputLazyFun" /></p><p>number修饰符<el-input v-model.number="InputNumberVal"></el-input></p><p>trim修饰符<el-input v-model.trim="InputTrimVal"></el-input></p></div><div class="content2"><h6>v-slot使用</h6>具体参考插槽吧,这里不做演示了</div></el-tab-pane><el-tab-pane label="自定义指令" name="third"><h6>固定颜色指令</h6><p v-color>固定红色的指令效果</p><hr><h6>自定义颜色</h6>选择一个颜色吧:<el-color-picker v-model="colorValue"></el-color-picker><p v-setColor="colorValue">我是一段可选择颜色的字段</p><hr><h6>可拖拽指令</h6><div class="dragBox"><div class="dragContent" v-draggable></div></div></el-tab-pane></el-tabs></div>
</template>
<script>
import Child from './child.vue'
export default {name: 'instructions',data() {return {activeName: 'first',textValue: '这是一段常规文字',htmlTemplate: `<div><input/><button>按钮</button></div>`,checkedValue: true,numValue: 0,numberVal: 100,inputValue: '输入框的值',listValue: [{label: '文字1',value: 'one'},{label: '文字2',value: 'two'},{label: '文字3',value: 'three'}],eventName: 'click',className: 'classP',styleName: {color: 'green'},name1: '属性1',name2: JSON.stringify({value: '属性3'}),InputVal: '常规输入框的值',InputLazyVal: 'lazy输入框的值',InputNumberVal: 1,InputTrimVal: '去空输入框的值',colorValue: '#000',}},directives: {color: {// 指令的定义inserted: function (el) {el.style.color = 'red'}}},components: {Child},methods: {addNum() {this.numValue++},deleteNum() {this.numValue--},changeNumberVal() {this.numberVal++},clickFun() {console.log('常规点击')},clickPFun() {console.log('点击p标签')},clickSpanFun() {console.log('点击span标签')},inputEventFun() {console.log(this.inputValue, '输入框的值')},componentClick(e) {console.log(e, '点击了组件')},mousedownFun() {console.log('鼠标按下')},mouseUpFun() {console.log('鼠标抬起')},checkBtn1() {let btn1 = this.$refs.btn1console.log(btn1, 'element组件按钮')console.log(btn1.$attrs['name1'], JSON.parse(btn1.$attrs['name2']), btn1.$attrs['name3'], '按钮的属性')},checkBtn2() {let btn2 = this.$refs.btn2console.log(btn2, 'btn的节点')console.log(btn2.getAttribute('name1'), JSON.parse(btn2.getAttribute('name2')), btn2.getAttribute('name3'), '按钮的属性')},inputLazyFun() {console.log(this.InputLazyVal, 'lazy值')},},
}
</script>
<style lang="less" scoped>
.box {padding: 14px;.content1 {float: left;width: 30%;height: 200px;margin: 10px;padding: 8px;box-shadow: 1px 1px 1px 1px #837e7e;h6 {font-size: 14px;font-weight: 600;}}.content2 {float: left;width: 40%;height: 350px;margin: 10px;padding: 8px;box-shadow: 1px 1px 1px 1px #837e7e;h6 {font-size: 14px;font-weight: 600;}}}[v-cloak] {display: none;
}.classP {color: red;
}.dragBox {position: relative;width: 800px;height: 200px;border: 1px solid #000;.dragContent {position: absolute;width: 50px;height: 50px;background: red;cursor: move;left: 10px;top: 10px;}
}
</style>

自定义指令文件

import Vue from 'vue'
import _ from 'lodash'
Vue.directive('setColor',{inserted:function(el,val,vnode){console.log(el,val,vnode,'???自定义函数')el.style.color = val.value || '#000'},update:function(el,val,vnode){console.log(el,val,vnode,'???自定义函数')el.style.color = val.value || '#000'},
})Vue.directive('draggable',{inserted: function (el) {el.onmousedown = function (e) {var disx = e.pageX - el.offsetLeft;var disy = e.pageY - el.offsetTop;document.onmousemove = function (e) {el.style.left = e.pageX - disx + 'px';el.style.top = e.pageY - disy + 'px';}document.onmouseup = function () {document.onmousemove = document.onmouseup = null;}}},
})

那个child组件我没有写,随便定义一个就行,这些代码可以直接复制测试

感觉有用就给个赞吧!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/214990.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

长征故事vr互动教育体验系统让师生感同身受

红色文化是贯穿于新民主主义革命、社会主义建设的各个时期&#xff0c;具有深厚的历史价值和文化内涵的先进文化&#xff0c;是高效、优质的教育资源。思政课vr红色数字展馆充分开发和大力弘扬红色文化资源&#xff0c;发挥其独特资源优势和教育功能&#xff0c;应用到教学中&a…

如何巧用拨测监控中的自定义维度?

在拨测监控的场景中&#xff0c;用户往往很关心拨测的资源对象是否正常。在当前拨测采集策略中&#xff0c;拨测采集对象本身可能无法反映出配置的拨测地址&#xff0c;用户可能还需要找到具体的拨测采集策略后才能确认拨测地址。 本期EasyOps产品使用最佳实践&#xff0c;我们…

酵母双杂交服务专题(一)

酵母双杂交系统是一种在酵母这种真核生物模型中执行的实验方法&#xff0c;用于探索活细胞内部蛋白质间的相互作用。这种技术能够敏感地捕捉蛋白质间的细微和短暂相互作用&#xff0c;通过检测报告基因的表达产物来实现。作为一种高度灵敏的技术&#xff0c;酵母双杂交系统被广…

缓存组件状态,提升用户体验:探索 keep-alive 的神奇世界

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

【STM32单片机】LED点阵花样显示设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用STM32F103C8T6单片机控制器&#xff0c;使用8*8LED点阵模块、按键模块等。 主要功能&#xff1a; 系统运行后&#xff0c;默认以静态模式显示&#xff0c;此时点阵左右循环切换图像。 当按下K…

元宇宙现已开放!

在 2023 年 11 月 3 日 The Sandbox 首个全球创作者日上&#xff0c;The Sandbox 联合创始人 Arthur Madrid 和 Sebastien Borget 宣布元宇宙已开放&#xff0c;已创作完整体验的 LAND 持有者可以自行将体验发布至 The Sandbox 地图上。 精选速览 LAND 持有者&#xff1a;如果…

SpringBoot——感谢尚硅谷官方文档

SpringBoot——感谢尚硅谷官方文档 1 Spring与SpringBoot1、Spring能做什么1.1、Spring的能力1.2、Spring的生态1.3、Spring5重大升级1.3.1、响应式编程1.3.2、内部源码设计 2、为什么用SpringBoot2.1、SpringBoot优点2.2、SpringBoot缺点 3、时代背景3.1、微服务3.2、分布式分…

**QT与目标板联合调试_断点仿真**

原文地址: https://blog.csdn.net/u012851408/article/details/86715626

vue2:组件中extends的使用

上一篇文章中我对mixin的使用进行了一个使用和测试,这里对extend进行一个使用,其实extend和mixin还是有区别的。 上一篇文章:vue2:mixin混入的使用-CSDN博客 不过也是看实际的业务场景,我们也可以使用extend完成和mixin几乎一摸一样的操作。 不废话,上代码 创建extendTest.…

django(千锋教育)

创建一个django项目 官网下载python最新版本 配置到环境变量中 打开intlij编辑器 创建django项目 安装django&#xff1a;pip install django 创建django项目: django-admin startproject django01 创建djangoAPP&#xff1a;python manage.py startapp App 启动&#xff1a…

室内卫星定位信号弱?——看时间服务器与GNSS模拟器如何实现区域内可靠的室内定位!

方案介绍 GNSS是当前最常用、覆盖最广泛、效率最高的定位导航技术&#xff0c;几乎各个领域都依赖它。然而&#xff0c;在室内或地下&#xff0c;GNSS信号通常非常弱甚至不可用。德思特采用时间服务器与GNSS模拟器相结合&#xff0c;提供了一种基于区域的室内定位方案。这个方…

Python 哈希表的实现——字典

哈喽大家好&#xff0c;我是咸鱼 接触过 Python 的小伙伴应该对【字典】这一数据类型都了解吧 虽然 Python 没有显式名称为“哈希表”的内置数据结构&#xff0c;但是字典是哈希表实现的数据结构 在 Python 中&#xff0c;字典的键&#xff08;key&#xff09;被哈希&#x…