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.mzph.cn/news/164390.shtml

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

相关文章

无边界电视点播TVbox壳+源

TBBox可以是个盒子也可以是软件 视频播放的困局新的改变TVBox apk更成熟的熊猫宝盒_3.10还有这个没测试恒星TV 写在最后 视频播放的困局 现在电视上几大平台看剧集都要充会员&#xff0c;而电脑上网页端有很多可以看的网页&#xff0c;只有 随便一搜就测出来&#xff0c;只是经…

数据安全第一:应对[[MyFile@waifu.club]].wis勒索病毒的实用建议与技巧

引言&#xff1a; 在当今数字化时代&#xff0c;[[MyFilewaifu.club]].wis、[[backupwaifu.club]].wis勒索病毒是一种恶意软件&#xff0c;其危害用户数据安全&#xff0c;通过加密文件并勒索赎金来获取经济利益。以下是对[[MyFilewaifu.club]].wis、[[backupwaifu.club]].wis…

PyTorch包

进入PyTorch的官网&#xff1a; pytorch GitHub 点击GitHub&#xff1a; 进入PyTorch的主目录&#xff1a; 进入Vision reference&#xff1a; detection&#xff1a; 这就是我们在训练过程中会使用到的文件了&#xff1a;

objdump反汇编文件解析

命令使用 objdump可以对可执行文件进行反汇编 其常用参数为: objdump -d <file(s)>: 将代码段反汇编&#xff1b;objdump -S <file(s)>: 将代码段反汇编的同时&#xff0c;将反汇编代码与源代码交替显示&#xff0c;编译时需要使用-g参数&#xff0c;即需要调试信…

Hadoop技术与应用的习题

第一章测验 1、下面哪个选项不属于Google的三驾马车&#xff1f; A.HDFS B.MapReduce C.BigTable D.GFS 2、下面哪个思想是为了解决PageRank&#xff08;网页排名&#xff09;的问题&#xff1f; A.GFS B.BigTable C.MapReduce D.YARN 3、GFS 存储的文件都被分割成固定大小的…

CAN基础知识

CAN 简介 CAN 是 Controller Area Network 的缩写&#xff08;以下称为 CAN&#xff09;&#xff0c;是 ISO 国际标准化的串行通信 协议。在当前的汽车产业中&#xff0c;出于对安全性、舒适性、方便性、低公害、低成本的要求&#xff0c;各种 各样的电子控制系统被开发了出来…

简单的用Python采集股票数据,保存表格后分析历史数据

前言 字节跳动如果上市&#xff0c;那么钟老板将成为我国第一个世界首富 趁着现在还没上市&#xff0c;咱们提前学习一下用Python分析股票历史数据&#xff0c;抱住粗大腿坐等起飞~ 好了话不多说&#xff0c;我们直接开始正文 准备工作 环境使用 Python 3.10 解释器Pychar…

如何应用ChatGPT撰写、修改论文及工作报告,提供写作能力及优化工作??

如果我想让gpt从pdf文档中提取相关关键词的内容&#xff0c;可以怎么做呢&#xff1f;&#xff1f;我们评论区讨论 ChatGPT 在论文写作与编程方面也具备强大的能力。无论是进行代码生成、错误调试还是解决编程难题&#xff0c;ChatGPT都能为您提供实用且高质量的建议和指导&am…

爱上C语言:scanf、gets以及getchar输入字符串你真的懂了吗

&#x1f680; 作者&#xff1a;阿辉不一般 &#x1f680; 你说呢&#xff1a;不服输的你&#xff0c;他们拿什么赢 &#x1f680; 专栏&#xff1a;爱上C语言 &#x1f680;作图工具&#xff1a;draw.io(免费开源的作图网站) 如果觉得文章对你有帮助的话&#xff0c;还请点赞…

通过ros系统中websocket中发送sensor_msgs::Image数据给web端显示

通过ros系统中websocket中发送sensor_msgs::Image数据给web端显示 #include <ros/ros.h> #include <signal.h> #include <sensor_msgs/Image.h> #include <message_filters/subscriber.h> #include <message_filters/synchronizer.h> #include &…

spring 是如何开启事务的, 核心原理是什么

文章目录 spring 是如何开启事务的核心原理1 基于注解开启事务2 基于代码来开启事务 spring 是如何开启事务的 核心原理 Spring事务管理的实现有许多细节&#xff0c;如果对整个接口框架有个大体了解会非常有利于我们理解事务&#xff0c;下面通过讲解Spring的事务接口来了解…

建行广东省江门市分行走进农村地区开展反假货币宣传

人民对美好生活的向往&#xff0c;涉及方方面面&#xff0c;小至“钱袋子”安全。建行广东省江门市分行落实当地监管部门部署&#xff0c;积极扛起维护国家金融安全的重要政治责任&#xff0c;深入农村地区开展反假货币宣传工作&#xff0c;助力构建农村反假货币工作长效机制。…

Hyper-V系列:windows11开启系统自带安卓虚拟机并安装apk包

本文记录了Windows11系统下开启系统自带的安卓虚拟机,并通过安装包安装自定义应用的过程。开启系统自带的安卓虚拟机流程为:开启Hyper-V、安装Windows11子系统;安装apk安装包的流程为:安装adb调试工具、开启子系统的开发者模式、安装apk应用包。 一. 开启Hyper-V Hyper-V…

[BJDCTF2020]The mystery of ip1

提示 ssti模板注入head头x-forwarded-for 每一次做题的最开始流程都大致因该是 信息收集找可以操控的地方 查看hint页面的源代码又发现它提示说 ####你知道为什么会知道你的ip吗 查看flag页面 从刚才给我的提示以及他这里显示的我的ip&#xff0c;大概找到了我可操作的可控点 …

【Vue】创建第一个实例

步骤&#xff1a; 1.创建容器 2.引包 3.创建实例 4.添加配置项 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><!--准备容器 --> <di…

【C语言:深入理解指针二】

文章目录 1. 二级指针2. 指针数组3. 字符指针变量4. 数组指针变量5. 二维数组传参的本质6. 函数指针变量7. 函数指针数组8. 转移表9. 回调函数10. qsort函数的使用与模拟实现 1. 二级指针 我们知道&#xff0c;指针变量也是变量&#xff0c;它也有自己的地址&#xff0c;使用什…

【面试】jvm中堆是分配对象存储的唯一选择吗

目录 一、说明二、逃逸分析2.1 说明2.2 参数设置 一、说明 1.在《深入理解Java虚拟机》中关于Java堆内存有这样一段描述:随着JIT编译期的发展与逃逸分析技术逐渐成熟&#xff0c;栈上分配、标量替换优化技术将会导致一些微妙的变化&#xff0c;所有的对象都分配到堆上也渐渐变得…

牛客 最小公配数 golang版实现

题目请参考: HJ108 求最小公倍数 题解: 在大的数的倍数里面去找最小的能整除另外一个数的数&#xff0c;就是最小公倍数&#xff0c;按照大的来找&#xff0c;循环次数能够降到很少&#xff0c;提升效率 golang实现: package mainimport ("fmt" )func main() {a : …

CSDN最新最全python+pytest接口自动化(12)-自动化用例编写思路 (使用pytest编写一个测试脚本)

经过之前的学习铺垫&#xff0c;我们尝试着利用pytest框架编写一条接口自动化测试用例&#xff0c;来厘清接口自动化用例编写的思路。 我们在百度搜索天气查询&#xff0c;会出现如下图所示结果&#xff1a; 接下来&#xff0c;我们以该天气查询接口为例&#xff0c;编写接口测…

JVM 之 class文件详解

目录 一. 前言 二. class文件结构 2.1. 文件格式 2.2. 魔数与版本号 2.3. 常量池 2.4. 访问标志 2.5. 类索引、父类索引和接口索引集合 2.6. 字段表集合 2.7. 方法表集合 2.8. 属性表集合 2.8.1. Code 属性表 2.8.2. Exceptions 属性 2.8.3. LineNumberTable 属性…