什么是自定义指令
以 v- 为前缀,然后加上自己定义好的名字组成的一个指令就是自定义指令。为什么要有自定义指令呢?在有些时候,你仍然需要对普通的dom元素进行底层的操作,这个时候就可以用到自定义指令。
自定义指令的语法
全局自定义指令
// 注册一个全局自定义指令 `v-focus`
vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
局部自定义指令
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}
钩子函数
看了上述的代码,如果你从来没接触过这类内容,你可能会很生疏,下面我给大家讲讲其每一步所需要掌握的东西
首先是钩子函数:
bind :只会调用一次的函数,表示指令第一次绑定元素时调用
inserted :被绑定元素插入到父节点时调用(仅保证父节点存在,但不一定已被插入文档中)。
update :所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。
componentUpdated :指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind :只调用一次,指令与元素解绑时调用。
然后我们看看钩子函数中的参数列表:
el:指令所绑定的元素,可以用来直接操作 DOM 。
binding:一个对象,包含以下属性:
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 来进行。
下面我们来分析几个简单的钩子函数,及其参数
代码如下:(看完代码我再将其)
<div id="app">
<span v-mmm='{color:color, fontSize:"20px"}'>bind的对象形式</span>
<br>
<button @click='changeStyle'>改变颜色</button>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
color: 'cyan',
style1: {color: 'lightblue'},
style2: {fontSize:"20px"}
},
directives: {
mmm: {
bind(el,binding) {
// binding.value = {color:color, fontSize:"20px"}
if(binding.value.constructor === Object) {
Object.keys(binding.value).forEach(key => {
el.style[key] = binding.value[key];
})
}
}
}
},
methods: {
changeStyle() {
this.color = 'lightpink'
}
},
})
</script>
效果图:
下面我们换成 update 钩子函数:
update(el,binding) {
// binding.value = {color:color, fontSize:"20px"}
if(binding.value.constructor === Object) {
Object.keys(binding.value).forEach(key => {
el.style[key] = binding.value[key];
})
}
}
效果图:
我们发现他会随着数据改变而更新,但是他刚开始不会调用它,只有当数据发生改变之后才会调用该钩子函数
如果我们想要要刚开始就调用,并且会跟随数据改变而改变,那么我们就要同时调用 bind 和 update 这两个钩子函数,但是两个钩子函数中的内容又是一样的,那么书写起来就很麻烦。那么我们可以这样写:
mmm: function(el , binding) {
if(binding.value.constructor === Object) {
Object.keys(binding.value).forEach(key => {
el.style[key] = binding.value[key];
})
}
},
这样之后我们就可以达到那样的效果了。
书写一个类似于 v-bind:style 的效果的自定义指令
<div id="app">
<span v-mystyle='{color:color, fontSize:"20px"}'>v-mystyle的对象形式</span>
<p v-mystyle='[style1 , style2]'>我使用的是v-mystyle的数组形式</p>
<button @click='changeStyle'>改变颜色</button>
</div>
<script>
const vm = new Vue({
el: '#app',
data: {
color: 'cyan',
style1: {color: 'lightblue'},
style2: {fontSize:"20px"}
},
directives: {
mystyle: function(el , binding) {
if(binding.value.constructor === Object) {
Object.keys(binding.value).forEach(key => {
el.style[key] = binding.value[key];
})
} else if(binding.value.constructor === Array) {
for(item of binding.value) {
for(key in item) {
el.style[key] = item[key];
}
}
}
},
},
methods: {
changeStyle() {
this.color = 'lightpink'
}
},
})
</script>
效果图:
指令式编程:告诉机器该如何做,并得到自己想要的结果。声明式编程:告诉机器您想得到什么,让机器自己计算该如何做。
整理vue常用的内置指令:v-bind指令、v-text指令、v- html指令、v-show指令、v-if指令、v-else 指令、v-else-if 指令、v-for 指令、v-on 指令、v-model 指令、v-once 指令、v-cloak指令、v-pre指令
本文将解释如何通过按下(或按住)按钮来执行功能和删除输入。首先,我将解释如何在VanillaJS中实现这一目标。然后,为它创建一个Vue指令。那么,让我们开始吧。
全局API并不在构造器里,而是先声明全局变量或者直接在Vue上定义一些新功能,Vue内置了一些全局API,比如我们今天要学习的指令Vue.directive。说的简单些就是,在构造器外部用Vue提供给我们的API函数来定义新的功能。
v-text主要用来更新textContent,可以等同于JS的text属性。v-html双大括号的方式会将数据解释为纯文本,而非HTML。为了输出真正的HTML,可以用v-html指令。它等同于JS的innerHtml属性。
可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:动态参数预期会求出一个字符串,异常情况下值为 null。这个特殊的 null 值可以被显性地用于移除绑定。任何其它非字符串类型的值都将会触发一个警告。
今天使用v-for指令的时候遇到一个错误:[Vue warn]: Error in render: \\\"TypeError: Cannot read property \\\'children\\\' of undefined\\\",猜测使用了嵌套属性的原因,在页面中无法解析出具体属性值
使用场景:代码复用和抽象的主要形式是组件;当需要对普通 DOM 元素进行底层操作,此时就会用到自定义指令;但是,对于大幅度的 DOM 变动,还是应该使用组件
意义就是在组件里留着差值方便后续组件内容新增,而且由于插件是写在父级中数据可以直接父级中传输而不需要传子再传父有些情况会减少写代码量,组件里没有设置插件名称,页面中插槽中写了插槽名称 结果页面中插槽不会被渲染
vue.js官方给自己的定为是数据模板引擎,并给出了一套渲染数据的指令。本文详细介绍了vue.js的常用指令。Vue.js 使用了基于 HTML 的模板语法最简单的使用vue的方式是渲染数据,渲染数据最常见的形式就是
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!