vue 中指令分为全局指令和局部指令
# 先来看全局自定义指令:
第一个参数是指令的名字,第二个参数可以是函数也可以是对象,先来看函数:
<body> | |
<div id="app"> | |
<input type="text" v-slice="content" v-model="content"> | |
</div> | |
<script> | |
Vue.directive('sice', (el, bindings, vnode) => { | |
console.log(el); //el 是指令所在的 dom 元素 | |
console.log(bindings); // 存放绑定的信息 | |
console.log(vnode); // 虚拟节点,指令绑定元素 1 的节点 | |
}); | |
const vm = new Vue({ | |
el: '#app', | |
data: { | |
content: '' | |
} | |
}) | |
</script> | |
</body> |
函数中接收三个参数:
el 在这里是 input 元素
bindings 里是一些绑定信息:
其中 expression 是指绑定的变量名字,这里是 content
name 是指令名字
value 是绑定数据的值,上面 content 为空,所以目前 value 为空
v-slice 上还可以写修饰符
<div id="app"> | |
<input type="text" v-slice.number="content" v-model="content"> | |
</div> |
还可以传参:
<div id="app"> | |
<input type="text" v-slice:9.number="content" v-model="content"> | |
</div> |
vnode 虚拟节点:
vnode 中 contex 是 vue 实例,其中的 content 是 vue 中的 content 值,即通过 vnode.context 拿到 vue 实例
小 demo:规定 input 框中只能输入 5 位
<body> | |||||||||||||||||||||||||||||||||||
<div id="app"> | |||||||||||||||||||||||||||||||||||
<input type="text" v-slice:9.number="content" v-model="content"> | |||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||
</body> |
函数中接收三个参数:
el 在这里是 input 元素
bindings 里是一些绑定信息:
其中 expression 是指绑定的变量名字,这里是 content
name 是指令名字
value 是绑定数据的值,上面 content 为空,所以目前 value 为空
v-slice 上还可以写修饰符
<div id="app"> | |
<input type="text" v-slice.number="content" v-model="content"> | |
</div> |
还可以传参:
<div id="app"> | |
<input type="text" v-slice:9.number="content" v-model="content"> | |
</div> |
vnode 虚拟节点:
vnode 中 contex 是 vue 实例,其中的 content 是 vue 中的 content 值,即通过 vnode.context 拿到 vue 实例
小 demo:规定 input 框中只能输入 5 位
<body> | |
<div id="app"> | |
<input type="text" v-slice:9.number="content" v-model="content"> | |
{{ content }} | |
</div> | |
<script> | |
Vue.directive('sice', (el, bindings, vnode) => { | |
const val = bindings.value.slice(0, 5); | |
vnode.context.content = val; | |
}); | |
const vm = new Vue({ | |
el: '#app', | |
data: { | |
content: '' | |
} | |
}) | |
</script> | |
</body> |
再利用对象的形式实现:
<script> | |
// Vue.directive('sice', (el, bindings, vnode) => { | |
// const val = bindings.value.slice(0, 5); | |
// vnode.context.content = val; | |
// }); | |
Vue.directive('sice',{ | |
bind(el, bindings, vnode) { | |
// 将指令绑定给 dom 元素时执行,只执行一次 | |
}, | |
update(el, bindings, vnode) { | |
// 虚拟 dom 渲染时执行 | |
const val = bindings.value.slice(0, 5); | |
vnode.context.content = val; | |
} | |
}) | |
const vm = new Vue({ | |
el: '#app', | |
data: { | |
content: '' | |
} | |
}) | |
</script> |
bind + update 等于之前的函数
第三个对象:(不常用)
insert(el) { | |
// 当元素插入到页面中执行 | |
el.focus();// 实现聚焦效果 | |
} |
完善一下:在这个 demo 中用到两个指令,v-slice 和 v-model ,不太合适,所以要 v-slice 自己实现双向数据绑定:
<div id="app"> | |
<input type="text" v-slice:9.number="content" v-model="content"> | |
<!--swig1--> | |
</div> | |
<script> | |
Vue.directive('sice',{ | |
bind(el, bindings, vnode) { | |
// 第一步,数据显示在 input 框中 | |
const context = vnode.context; | |
//el.value = context; (content 时动态的,不能写死, 下面形式) | |
el.value = context[bindings.expression]; | |
// 第二步,input 变化,content 也要跟着变化,所以要坚挺 input | |
el.oninput = e => { | |
const value = e.target.value; | |
const val = value.slice(0, 5); | |
context[bindings.expression] = val; | |
//content 内容被约束了,input 中也要被需要被约束 | |
el.value = val; | |
} | |
}, | |
update(el, bindings, vnode) { | |
} |
此功能实现了,但是当 data 中 content 值被提前设置后,出现此情况
const vm = new Vue({ | |
el: '#app', | |
data: { | |
content: 'dsfgfhghgf' | |
} | |
}) |
所以取 value 值时应先对其进行截取
Vue.directive('sice',{ | |
bind(el, bindings, vnode) { | |
// 第一步,数据显示在 input 框中 | |
const context = vnode.context; | |
//el.value = context; (content 时动态的,不能写死, 下面形式) | |
el.value = context[bindings.expression].slice(0, 5); |
又发现 content 值很长
Vue.directive('sice',{ | |
bind(el, bindings, vnode) { | |
const context = vnode.context; | |
let initVal = context[bindings.expression].slice(0, 5); | |
el.value = initVal; | |
context[bindings.expression] = initVal; |
截取想要是长度,可根据
v-slice:9.number 这个属性
<body> | |
<div id="app"> | |
<input type="text" v-slice:9.number="content"> | |
<!--swig2--> | |
</div> | |
<script> | |
Vue.directive('sice',{ | |
bind(el, bindings, vnode) { | |
const context = vnode.context; | |
const length = bindings.arg || 5;//arg 时参数,没有则是 5 | |
let initVal = context[bindings.expression].slice(0, length); | |
el.value = initVal; | |
context[bindings.expression] = initVal; | |
el.oninput = e => { | |
const value = e.target.value; | |
const val = value.slice(0, length); | |
context[bindings.expression] = val; | |
el.value = val; | |
} | |
}, |
这里限制 9 位数
在控制台更改 content 值:
发现 input 中的值没变。要想同步更新,需写在 update 中
el.oninput = e => { | |
const value = e.target.value; | |
const val = value.slice(0, length); | |
context[bindings.expression] = val; | |
el.value = val; | |
} |
增加功能:.number 时不能有字母出现
Vue.directive('sice',{ | |
bind(el, bindings, vnode) { | |
const context = vnode.context; | |
const length = bindings.arg || 5; | |
const numberFlag = bindings.modifiers.number; | |
let initVal = context[bindings.expression]; | |
if (numberFlag) { | |
initVal = initVal.replace(/[^0-9]/g, ''); | |
} | |
el.value = initVal.slice(0, length); | |
el.value = initVal; | |
context[bindings.expression] = initVal; | |
el.oninput = e => { | |
let value = e.target.value; | |
if (numberFlag) { | |
value = value.replace(/[^0-9]/g, ''); | |
} | |
const val = value.slice(0, length); | |
context[bindings.expression] = val; | |
el.value = val; | |
} | |
}, |
update 中也要做处理
update(el, bindings, vnode) { | |
let context = vnode.context; | |
const numberFlag = bindings.modifiers.number; | |
let value = context[bindings.expression]; | |
if (numberFlag) { | |
value = value.replace(/[^0-9]/g, '') | |
} | |
el.value = value; | |
} |
# 局部指令:
<div id="app"> | |
<input type="text" v-slice:9.number="content"> | |
<!--swig3--> | |
</div> | |
<script> | |
const vm = new Vue({ | |
el: '#app', | |
data: { | |
content: 'dsfgfhghgf' | |
}, | |
directives: { | |
slice: (el, bindings, vnode) => { | |
} | |
} | |
}) | |
</script> |
</div>
<script>
Vue.directive('sice', (el, bindings, vnode) => {
const val = bindings.value.slice(0, 5);
vnode.context.content = val;
});
const vm = new Vue({
el: '#app',
data: {
content: ''
}
})
</script>
</body>
再利用对象的形式实现:
<script> | |
// Vue.directive('sice', (el, bindings, vnode) => { | |
// const val = bindings.value.slice(0, 5); | |
// vnode.context.content = val; | |
// }); | |
Vue.directive('sice',{ | |
bind(el, bindings, vnode) { | |
// 将指令绑定给 dom 元素时执行,只执行一次 | |
}, | |
update(el, bindings, vnode) { | |
// 虚拟 dom 渲染时执行 | |
const val = bindings.value.slice(0, 5); | |
vnode.context.content = val; | |
} | |
}) | |
const vm = new Vue({ | |
el: '#app', | |
data: { | |
content: '' | |
} | |
}) | |
</script> |
bind + update 等于之前的函数
第三个对象:(不常用)
insert(el) { | |
// 当元素插入到页面中执行 | |
el.focus();// 实现聚焦效果 | |
} |
完善一下:在这个 demo 中用到两个指令,v-slice 和 v-model ,不太合适,所以要 v-slice 自己实现双向数据绑定:
<div id="app"> | |
<input type="text" v-slice:9.number="content" v-model="content"> | |
<!--swig1--> | |
</div> | |
<script> | |
Vue.directive('sice',{ | |
bind(el, bindings, vnode) { | |
// 第一步,数据显示在 input 框中 | |
const context = vnode.context; | |
//el.value = context; (content 时动态的,不能写死, 下面形式) | |
el.value = context[bindings.expression]; | |
// 第二步,input 变化,content 也要跟着变化,所以要坚挺 input | |
el.oninput = e => { | |
const value = e.target.value; | |
const val = value.slice(0, 5); | |
context[bindings.expression] = val; | |
//content 内容被约束了,input 中也要被需要被约束 | |
el.value = val; | |
} | |
}, | |
update(el, bindings, vnode) { | |
} |
此功能实现了,但是当 data 中 content 值被提前设置后,出现此情况
const vm = new Vue({ | |
el: '#app', | |
data: { | |
content: 'dsfgfhghgf' | |
} | |
}) |
所以取 value 值时应先对其进行截取
Vue.directive('sice',{ | |
bind(el, bindings, vnode) { | |
// 第一步,数据显示在 input 框中 | |
const context = vnode.context; | |
//el.value = context; (content 时动态的,不能写死, 下面形式) | |
el.value = context[bindings.expression].slice(0, 5); |
又发现 content 值很长
Vue.directive('sice',{ | |
bind(el, bindings, vnode) { | |
const context = vnode.context; | |
let initVal = context[bindings.expression].slice(0, 5); | |
el.value = initVal; | |
context[bindings.expression] = initVal; |
截取想要是长度,可根据
v-slice:9.number 这个属性
<body> | |
<div id="app"> | |
<input type="text" v-slice:9.number="content"> | |
<!--swig2--> | |
</div> | |
<script> | |
Vue.directive('sice',{ | |
bind(el, bindings, vnode) { | |
const context = vnode.context; | |
const length = bindings.arg || 5;//arg 时参数,没有则是 5 | |
let initVal = context[bindings.expression].slice(0, length); | |
el.value = initVal; | |
context[bindings.expression] = initVal; | |
el.oninput = e => { | |
const value = e.target.value; | |
const val = value.slice(0, length); | |
context[bindings.expression] = val; | |
el.value = val; | |
} | |
}, |
这里限制 9 位数
在控制台更改 content 值:
发现 input 中的值没变。要想同步更新,需写在 update 中
el.oninput = e => { | |
const value = e.target.value; | |
const val = value.slice(0, length); | |
context[bindings.expression] = val; | |
el.value = val; | |
} |
增加功能:.number 时不能有字母出现
Vue.directive('sice',{ | |
bind(el, bindings, vnode) { | |
const context = vnode.context; | |
const length = bindings.arg || 5; | |
const numberFlag = bindings.modifiers.number; | |
let initVal = context[bindings.expression]; | |
if (numberFlag) { | |
initVal = initVal.replace(/[^0-9]/g, ''); | |
} | |
el.value = initVal.slice(0, length); | |
el.value = initVal; | |
context[bindings.expression] = initVal; | |
el.oninput = e => { | |
let value = e.target.value; | |
if (numberFlag) { | |
value = value.replace(/[^0-9]/g, ''); | |
} | |
const val = value.slice(0, length); | |
context[bindings.expression] = val; | |
el.value = val; | |
} | |
}, |
update 中也要做处理
update(el, bindings, vnode) { | |
let context = vnode.context; | |
const numberFlag = bindings.modifiers.number; | |
let value = context[bindings.expression]; | |
if (numberFlag) { | |
value = value.replace(/[^0-9]/g, '') | |
} | |
el.value = value; | |
} |
# 局部指令:
<div id="app"> | |
<input type="text" v-slice:9.number="content"> | |
<!--swig3--> | |
</div> | |
<script> | |
const vm = new Vue({ | |
el: '#app', | |
data: { | |
content: 'dsfgfhghgf' | |
}, | |
directives: { | |
slice: (el, bindings, vnode) => { | |
} | |
} | |
}) | |
</script> |