首先细数一下已经了解过的v-指令
v-bind : 单向绑定解析表达式, 可简写为 :xxx
v-model : 双向数据绑定
v-for : 遍历数组/对象/字符串
v-on : 绑定事件监听, 可简写为@
v-if : 条件渲染(动态控制节点是否存存在)
v-else : 条件渲染(动态控制节点是否存存在)
v-show : 条件渲染 (动态控制节点是否展示)
以及本文中要学习的指令 v-text v-html v-cloak v-once v-pre 还有怎样自定义指令
本文内容:
- v-model
- v-text
- v-html
- v-cloak
- v-once
- v-pre
- 自定义指令
1. v-model
前面的章节以及学习了v-model是怎样简单的进行双向绑定的,但是其中的一些细节还需要了解。
v-model用于绑定表单提交一类的,但是表单有很多种类型,不同类型的v-model绑定有所不同,所以根据一个案列可以来学习一下细节。
实现的代码在这里,代码后面有详细的解释
<body>
<!-- 准备好一个容器-->
<div id="root">
<form @submit.prevent="demo">
账号:<input type="text" v-model.trim="userInfo.account"> <br/><br/>
密码:<input type="password" v-model="userInfo.password"> <br/><br/>
年龄:<input type="number" v-model.number="userInfo.age"> <br/><br/>
性别:
男<input type="radio" name="sex" v-model="userInfo.sex" value="male">
女<input type="radio" name="sex" v-model="userInfo.sex" value="female"> <br/><br/>
爱好:
学习<input type="checkbox" v-model="userInfo.hobby" value="study">
打游戏<input type="checkbox" v-model="userInfo.hobby" value="game">
吃饭<input type="checkbox" v-model="userInfo.hobby" value="eat">
<br/><br/>
所在城市
<select v-model="userInfo.city">
<option value="">请选择城市</option>
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="shenzhen">深圳</option>
<option value="wuhan">武汉</option>
</select>
<br/><br/>
其他信息:
<textarea v-model.lazy="userInfo.other"></textarea> <br/><br/>
<input type="checkbox" v-model="userInfo.agree">阅读并接受<a href="http://www.atguigu.com">《用户协议》</a>
<button>提交</button>
</form>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false
new Vue({
el:'#root',
data:{
userInfo:{
account:'',
password:'',
age:18,
sex:'female',
hobby:[],
city:'beijing',
other:'',
agree:''
}
},
methods: {
demo(){
console.log(JSON.stringify(this.userInfo))
}
}
})
</script>
上面这个案列我们一行一行的来分析:
首先整体,在data中放入了一个userInfo,为什么要把数据放在一起呢?是因为界面可能需要依次的输出填入的数据,如果要一个个的输出很麻烦,所以放在一起进行输出。console.log(JSON.stringify(this.userInfo))。
帐号是一个普通的input框,其中的v-model修饰符trim用于输入首尾空格过滤。
密码也没有什么需要注意的地方。
年龄有一个number的v-model修饰符,为了保证输入的数字在对象中是数值形式,否则会被保存为字符串形式。type="number"是为了保证输入的必须是数字,不能有其他字符。
性别只能二选一,所以name要相同,需要在后面配置value,因为v-model收集的是value。
爱好用的是checkbox,主要这里也是需要配置value的,否则收集的就是布尔值。
所在城市用的是select下拉框,也是需要配置value的。
其他信息这里有一个lazy的v-model修饰符,是因为在text中输入信息,会实时更新,这样会降低效率,lazy的话会在失去焦点的时候再更新数据。
总结:
- 如果
<input type="text"/>
,则v-model收集的是value值,用户输入的就是value值。 - 如果
<input type="radio"/>
,则v-model收集的是value值,且要给标签配置value值。 - 如果
<input type="checkbox"/>
1.没有配置input的value属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
2.配置input的value属性:
(1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
(2)v-model的初始值是数组,那么收集的的就是value组成的数组
v-model的三个修饰符:
lazy:失去焦点再收集数据
number:输入字符串转为有效的数字
trim:输入首尾空格过滤
2. v-text
1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
3. v-html
1.作用:向指定节点中渲染包含html结构的内容。
2.与插值语法的区别:
(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
(2).v-html可以识别html结构。
3.严重注意:v-html有安全性问题!!!!
(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
(2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
4. v-cloak
1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
5. v-once
1.v-once所在节点在初次动态渲染后,就视为静态内容了。
2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
6. v-pre
1.跳过其所在节点的编译过程。
2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
7. 自定义指令
一、定义语法:
(1).局部指令:
new Vue({
el:'#root',
data:{
name:'尚硅谷',
n:1
},
directives:{
//需求1:定义一个v-big指令,和v-text功能类似,但会把绑定的数值放大10倍。
//需求2:定义一个v-fbind指令,和v-bind功能类似,但可以让其所绑定的input元素默认获取焦点。
//big函数何时会被调用?1.指令与元素成功绑定时(一上来)。2.指令所在的模板被重新解析时。
/* 'big-number'(element,binding){
// console.log('big')
element.innerText = binding.value * 10
}, */
big(element,binding){
console.log('big',this) //注意此处的this是window
// console.log('big')
element.innerText = binding.value * 10
},
fbind:{
//指令与元素成功绑定时(一上来)
bind(element,binding){
element.value = binding.value
},
//指令所在元素被插入页面时
inserted(element,binding){
element.focus()
},
//指令所在的模板被重新解析时
update(element,binding){
element.value = binding.value
}
}
}
})
(2).全局指令:
Vue.directive(指令名,配置对象) 或 Vue.directive(指令名,回调函数)
二、配置对象中常用的3个回调:
(1).bind:指令与元素成功绑定时调用。
(2).inserted:指令所在元素被插入页面时调用。
(3).update:指令所在模板结构被重新解析时调用。
三、备注:
1.指令定义时不加v-,但使用时要加v-;
2.指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名。