vue自定义指令模拟v-model指令
前言通常情况下,vue内置的指令并不能够满足我们日常开发的要求,我们则可以根据实际需要进行自定义指令,本篇博客将记录vue自定义指令模拟v-model的过程,有什么错误的地方欢迎批评指正。这里写目录标题前言创建自定义指令钩子函数bind、update和inserted参数 bindings参数 vnode参数 el数据双向绑定指令参数属性限制数据的长度限制数据内容总结创建自定义指令// 全局创建V
·
前言
通常情况下,vue
内置的指令并不能够满足我们日常开发的要求,我们则可以根据实际需要进行自定义指令,本篇博客将记录vue自定义指令模拟v-model
的过程,有什么错误的地方欢迎批评指正。
创建自定义指令
// 全局创建
Vue.directive("slice",{
bind(el,bindings,vnode){
// 指令绑定上去的时候触发
},
update(el,bindings,vnode){
// 数据更新的时候触发
},
inserted(el){
// 元素插入到页面的时候触发
}
})
// 局部创建
new Vue({
el: "#app",
directives: {
slice: {
bind(el, bindings, vnode) {
// 指令绑定上去的时候触发
},
update(el, bindings, vnode) {
// 数据更新的时候触发
},
inserted(el) {
// 元素插入到页面的时候触发
}
}
}
})
创建自定义指令分为全局创建和局部创建,自定义指令有三个钩子函数( bind、update和inserted )
钩子函数
bind、update和inserted
钩子函数 | 参数 | 描述 |
---|---|---|
bind | el,bindingd,vnode | 绑定指令时触发 |
update | el,bindingd,vnode | 数据更新数触发 |
inserted | el | 插入到页面时触发 |
其中el
代表着当前元素,bindings
为一个对象,vnode
是虚拟DOM
。
比如说当我想要在页面加载完成后input
框获取焦点,我们可以这样写
<div id="app">
<input type="text" v-slice>
</div>
<script>
Vue.directive("slice", {
bind(el, bindings, vnode) {},
update(el, bindings, vnode) {},
inserted(el, bindings, vnode) {
el.focus();
}
})
new Vue({
el: "#app"
})
</script>
参数 bindings
指令可以传递变量,我们可以通过bindings
对象中的expression
获取参数值的变量名。
<div id="app">
<input type="text" v-slice="content">
</div>
<script>
Vue.directive("slice", {
bind(el, bindings, vnode) {
console.log(bindings.expression)
},
update(el, bindings, vnode) {},
inserted(el, bindings, vnode) {
el.focus();
}
})
new Vue({
el: "#app",
data: {
content: 'hello vue'
}
})
</script>
参数 vnode
有了自定义的参数值的变量名,我们就可以在vnode
中获取到变量的数据
<div id="app">
<input type="text" v-slice="content">
</div>
<script>
Vue.directive("slice", {
bind(el, bindings, vnode) {
var context = vnode.context;
console.log(vnode.context);
console.log(vnode.context[bindings.expression]);
},
update(el, bindings, vnode) {},
inserted(el, bindings, vnode) {
el.focus();
}
})
new Vue({
el: "#app",
data: {
content: 'hello vue'
}
})
</script>
参数 el
有了变量的数据,我们可以将数据设置为input
框的value
值。
<div id="app">
<input type="text" v-slice="content"> {{content}}
</div>
<script>
Vue.directive("slice", {
bind(el, bindings, vnode) {
var context = vnode.context;
el.value = context[bindings.expression];
},
update(el, bindings, vnode) {},
inserted(el, bindings, vnode) {
el.focus();
}
})
new Vue({
el: "#app",
data: {
content: 'hello vue'
}
})
</script>
数据双向绑定
我们为元素绑定输入事件,每次输入时将数据更新到data
中。
<div id="app">
<input type="text" v-slice="content"> {{content}}
</div>
<script>
Vue.directive("slice", {
bind(el, bindings, vnode) {
var context = vnode.context;
el.value = context[bindings.expression];
el.oninput = e => {
var value = e.target.value;
context[bindings.expression] = value;
}
},
update(el, bindings, vnode) {},
inserted(el, bindings, vnode) {
el.focus();
}
})
new Vue({
el: "#app",
data: {
content: 'hello vue'
}
})
</script>
指令参数属性
指令可以添加参数和一些指令,这些都被保存在bindings
中。
<div id="app">
<input type="text" v-slice:11.number="content"> {{content}}
</div>
限制数据的长度
<div id="app">
<input type="text" v-slice:11.number="content"> {{content}}
</div>
<script>
Vue.directive("slice", {
bind(el, bindings, vnode) {
var context = vnode.context;
el.value = context[bindings.expression];
// 数据双向绑定
el.oninput = e => {
var value = e.target.value;
context[bindings.expression] = value;
}
// 限制长度
var length = bindings.arg;
if (length) {
var initval = context[bindings.expression].slice(0, length);
context[bindings.expression] = initval;
el.value = initval;
}
},
update(el, bindings, vnode) {
var context = vnode.context;
// 限制长度
var length = bindings.arg;
if (length) {
var initval = context[bindings.expression].slice(0, length);
context[bindings.expression] = initval;
el.value = initval;
}
},
inserted(el, bindings, vnode) {
el.focus();
}
})
new Vue({
el: "#app",
data: {
content: 'hello vue123213213123213213safsadqwewqeqweqwe'
}
})
</script>
限制数据内容
<div id="app">
<input type="text" v-slice:11.number="content"> {{content}}
</div>
<script>
Vue.directive("slice", {
bind(el, bindings, vnode) {
var context = vnode.context;
el.value = context[bindings.expression];
// 数据双向绑定
el.oninput = e => {
var value = e.target.value;
context[bindings.expression] = value;
}
// 限制长度
var length = bindings.arg;
if (length) {
var initval = context[bindings.expression].slice(0, length);
context[bindings.expression] = initval;
el.value = initval;
}
// 设置为number
var IsNumber = bindings.modifiers.number;
if (IsNumber) {
var initval = context[bindings.expression].replace(/[^0-9]/g, '');
context[bindings.expression] = initval;
el.value = initval;
}
},
update(el, bindings, vnode) {
var context = vnode.context;
// 限制长度
var length = bindings.arg;
if (length) {
var initval = context[bindings.expression].slice(0, length);
context[bindings.expression] = initval;
el.value = initval;
}
// 设置为number
var IsNumber = bindings.modifiers.number;
if (IsNumber) {
var initval = context[bindings.expression].replace(/[^0-9]/g, '');
context[bindings.expression] = initval;
el.value = initval;
}
},
inserted(el, bindings, vnode) {
el.focus();
}
})
new Vue({
el: "#app",
data: {
content: 'hello vue123213213123213213safsadqwewqeqweqwe'
}
})
</script>
总结
就这样,一个自定义的指令完成了,我们从以上的自定义中简化的模拟了v-model
的指令,当然也可以你自定义其他的指令,快去试一下吧~
更多推荐
已为社区贡献3条内容
所有评论(0)