内置指令
v-text指令
- 作用:向其所在的节点中渲染文本内容。
- 与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}不会。
<div id="vtext">
<div>你好,{{name}}</div>
<div v-text="name">你好,</div>
<div v-text="name"></div>
</div>
<script>
new Vue({
el: '#vtext',
data: {
name: 'nepu',
str: '<h3>你好哈哈哈哈</h3>'
}
})
</script>
v-html指令
- 作用:向指定节点中渲染包含html结构的内容
- 与插值语法的区别:
- v-html会替换掉节点中所有的内容,{{xx}}不会。
- v-html可以识别html结构。
- ⭐严重注意:v-html有安全性问题
- 再网站上动态渲染任意html是非常危险的,容易导致XXS攻击。
- 一定要在可信的内容上使用v-html,永不要在用户提交的内容上!!!
v-cloak指令
vue.js脚本引入在vue模板和vue实例之间时,当网络较慢,网页还在加载 Vue.js ,而导致 Vue 来不及渲染,这时页面就会显示出 Vue 源代码。我们可以使用 v-cloak 指令来解决这一问题。
<div id="cloak">
<h2 v-cloak>{{name}}</h2>
</div>
<style>
[v-cloak] {
display: none;
}
</style>
<script src="http://localhost:8080/resource/5s/vue.js"></script>
<script>
console.log(1)
new Vue({
el: '#cloak',
data: {
name: 'hhhhhhhh'
}
})
</script>
加入v-cloak之后的运行结果,打开浏览器运行,缓冲5s后显示内容,缓冲过程页面无内容。
小结v-cloak
v-cloak指令(没有值):
- 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
- 使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
v-once
- v-once所在节点在初次动态渲染后,被视为静态内容了。
- 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
<div id="vonce">
<h2 v-once>初始n值:{{n}}</h2>
<h2>当前n值:{{n}}</h2>
<button @click="n++">点我n+1</button>
</div>
<script>
new Vue({
el: '#vonce',
data: {
n: 1
}
})
</script>
v-pre
v-pre指令:
- 跳过其所在节点的编译过程
- 可利用它跳过:没有使用指令语法、没使用插值语法的节点,会加快编译。
<div id="vpre">
<h2 v-pre>hello大家好</h2>
<h2 v-pre>当前值为:{{n}}</h2>
<button v-pre @click="n++">n+1</button>
</div>
<script>
new Vue({
el: '#vpre',
data: {
n: 1
}
})
</script>
运行结果截图
自定义指令
需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。 代码:
<div id="vbig">
<h2>当前n值:<span v-text="n"></span></h2>
<h2>放大10倍之后的n值为:<span v-big="n"></span></h2>
<button @click="n++">n+1</button>
</div>
<script>
new Vue({
el: '#vbig',
data: {
n: 1
},
directives: {
big(element, binding) {
element.innerText = binding.value * 10
}
}
})
</script>
难点:
- directives对象的形式可以处理一些细节,函数不可以。
- big函数被调用的两种情况: (1) 指令与元素成功绑定时(一上来) (2) 指令所在的模板被重新解析
- big函数不能通过返回值返回结果。 big函数接收的两个参数是啥,可以运行如下代码查看
big(a, b) {
console.log(a, b)
}
运行截图
span是真实DOM元素,console.dir(a)可以证明
console.log(a instanceof HTMLElement)运行结果为true也可以证明span是真实DOM元素
所以参数a是真实DOM元素span,b是包含很多属性的对象。
需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其绑定的input元素默认获取焦点。
<input type="text" v-fbind:value="n" autofocus>
fbind(element, binding) {
element.value = binding.value
element.focus()
}
以chrome浏览器为例,autofocus会使得输入框内光标聚焦,去掉autofocus就不会聚焦了,但是一些浏览器中autofocus并不好使。就不会聚焦了。第二个input输入框交给vue,指令与元素绑定成功,关系建立页面没有input,点击按钮n发生变化,模板重新解析,重新调用fbind,element已经存在,所以会成功聚焦。vue将元素放入页面不能被fbind捕捉,所以考虑使用对象式自定义指令。 代码中获取焦点的功能没有实现,原因可以通过如下代码解释
<button id="btn">点我创建一个输入框</button>
<script>
const btn = document.getElementById('btn')
btn.onclick = () => {
const input = document.createElement('input')
document.body.appendChild(input)
input.focus()
}
</script>
运行截图
成功添加了输入框并且获取焦点。input.focus()必须放在最后.
对象式自定义指令代码
fbind: {
// 指令与元素成功绑定时(一上来)
bind(element, binding) {
element.value = binding.value
},
// 指令所在元素被插入页面时
inserted(element, binding) {
element.focus()
},
// 指令所在的模板被重新解析时
update(element, binding) {
element.value = binding.value
}
}
bind和update对应函数bind被调用的两个时刻。
自定义指令总结
定义语法
- 局部指令: new Vue({ directives:{指令名:配置对象} }) 或者 new Vue({ directives(){} })
- 全局指令: Vue.directive(指令名,配置对象) 或者 Vue.directive(指令名,回调函数)
Vue.directive('big',function(element,binding){
console.log('big',this)//this是window
})
配置对象中常用的三个回调
- bind:指令与元素成功绑定时调用
- inserted:指令所在元素被插入页面时调用。
- update:指令所在模板结构被重新解析时调用。
备注
- 指令定义时不加v-,但使用的时候要加v-;
- 指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。