一、条件渲染
条件渲染有两种方式:
- v-if :v-if = '表达式' 表达式为真才展示 特点:不展示的DOM元素直接移除
- v-show v-show='表达式' 特点: 不展示的DOM仅仅是样式隐藏
二、列表渲染
1、v-for指令:
用来遍历并展示列表数据:可遍历数组、对象、字符串
<body>
<div id="root">
<h2>遍历数组</h2>
<ul>
<li v-for="(p,index) in persons" :key='index'>
{
{p.name}}--{
{p.age}}
</li>
</ul>
<h2>遍历对象</h2>
<ul>
<!-- 先收到的参数是值,再是属性名 -->
<li v-for="(value,key) in car" :key='key'>
{
{key}}--{
{value}}
</li>
</ul>
</div>
</body>
<script>
new Vue({
el:'#root',
data:{
persons:[
{id:'001',name:'张三',age:18},
{id:'002',name:'李四',age:19},
{id:'003',name:'王五',age:20}
],
car:{
name:'奥迪',
price:'70W',
color:'黑色'
},
}
})
</script>
备注:
v-for 提供 key attribute是 Vue 识别节点的一个通用机制,在后期维护状态时是必要的
2、v-for中的key 的作用
- 为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,所有我们需要给每一项提供一个key attribute
-
key 是虚拟DOM对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM,随后Vue 进行新虚拟DOM 与 旧虚拟DOM的差异比较
我们可以用index或者id作为它的标识符
用id作为key:
当新增一个数据时,由于它的id是唯一的,所以在新旧虚拟DOM对比中,旧虚拟DOM中找到了与新虚拟DOM相同的Key,发现内容没变,那么就直接使用之前的真实DOM
用index作为key:
用索引值作为key,假如我们用unshift方法在原来列表的前面逆序添加一项,那么索引值就全部发生了变化,那么新旧虚拟DOM对比算法中,发现所有相同key的新旧DOM内容发生了变化,所有的成员都不可复用了,则重新生成新的DOM,随后替换掉页面中之前的真实DOM。
实际开发中如何选择key:
最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号等唯一值
如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作,仅用于渲染列表用于展示。使用index 作为key或者不写也是没有问题的
3、Vue监测数据变化改变
原理:Vue监测数据变化完全依赖属性的setter 和 getter,即使是对象中的对象(第n层),Vue都会配置setter和getter ,来监测他们的变化.
- 监测对象中的数据:通过setter实现数据监视,且要在new Vue时就传入要监测的数据
(1)对象中后追加的属性,Vue默认不做响应式处理
(2)如果需要给后添加的属性做响应式。使用如下API
Vue.set(target,propertyName/index,value)
or vm.$set(target,propertyName/index,value)
- 监测数组中的数据:通过包裹数组更新元素的方法实现,本质上就是做了两件事;
(1) 调用原生对应的方法对数组进行更新(就是那7个会改变原数组的方法: push pop shift unshift reverse sort splice)
(2)重新解析模板,进而更新页面
备注: 替换数组,例如 filter(),slice(),concat()这些不会改变原数组的方法,当使用这些方法时,用新数组替换旧数组
example1.items = example1.items.filter(function (item) {
return 过滤表达式
})
三、表单数据
1、几类表单数据(根据input的type分)
- <input type="text"/> v-model收集的就是value值,用户输入的就是value值
-
<input type="radio"/> v-model 收集的就是value值,且要给标签配置value值
<div> //这个按钮是二选一的,所有指定name属性为sex,就可实现 男<input type="radio" name='sex' v-model='sex' value='male'> 女<input type="radio" name='sex' v-model='sex' value='female'> </div>
- <input type="checkbox"/> 选择框,分为单选框和多选框:分以下两种情况
没有配置input 的value 属性,那么收集的就是checked(勾选 or 未勾选,就是布尔值)
配置input的value属性:
v-model 的初始值是非数组,那么收集的就是checked (勾选or未勾选,是布尔值)
v-model 的初始值是数组,那么收集的就是value组成的数组
<body>
<div>
学习 <input type="checkbox" v-model='hobby' value='study'>
打游戏 <input type="checkbox" v-model='hobby' value='game'>
吃饭 <input type="checkbox" v-model='hobby' value='eat'>
</div>
</body>
<script>
new Vue({
el:'#root',
data:{
// 这里的输入类型是checkbox,并且实现多选,所有给hobby的初始值设为数组类型
hobby:[],
// 如果这里的hobby初始值为空,那么就只能实现选中单个
},
})
</script>
2、v-model的修饰符:
- lazy 失去焦点再收集数据,(输入完再收集)
- number 输入字符串转成有效的数字
- trim 过滤掉输入的首尾空格
四、过滤器
就是对要显示的数据进行特定格式化后再显示
- 注册过滤器 全局过滤器 和 局部过滤器
- 使用过滤器 { {xxx | 过滤器名}} 或 v-bind:属性 = ‘xxx | 过滤器名’
<div>
//可以使用多个管道符,同时使用多个过滤器
<h3>现在是:{
{time | timeFormater(YYYY_MM_DD) | mySlice}}</h3>
</div>
<script>
// 注册一个全局过滤器,在 new Vue外部注册
Vue.filter('mySlice',function(value){
//slice截取指定个数的字符
return value.slice(0,4)
})
new Vue({
el:'',
data:{
time:'128399872716
}
filter:{
timeFormater(value,str='YYYY-MM-DD HH:mm:ss'){
return dayjs(value).format(str)
},
}
})
</script>
五、内置指令
- v-text 向其所在节点渲染文本内容 与{ {}}语法的区别是v-text会替换掉节点中的内容
- v-html 向指定节点中渲染包含html结构的内容 会替换掉节点中的所有内容,而且可以识别html结构
- v-cloak 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性;使用css配合v-cloak可以解决网速慢时页面还没有Vue介入而引入{
{xxx}}的问题
<style> [v-cloak]{ display: none; } </style>
- v-once 所在节点在初次动态渲染后,就视为静态内容了,以后数据的改变不会引起v-once所在结构的更新
- v-pre 用于跳过其所在节点的编译过程,可利用它跳过那些没有使用指令语法、插值语法的节点,加快编译
六、自定义指令
可分为:
- 局部指令,写在new Vue里面,与data平级
<script> new Vue({ el:'#root', directives:{ //指令名:配置对象 } //也可以写成函数形式 // directives(){} }) </script>
- 全局指令,写在new Vue外面
备注:
自定义指令的名称(不需要加 “v-”,约定全小写);使用指令时必须要加 v-。
当需要拿到directives与指令成功绑定过程中的关键节点,需要写成完整的对象形式。
配置对象中三个钩子函数:
- bind 当指令绑定到元素上时,就会执行该函数,执行一次;此时元素还未插入到 DOM 中去(一般执行样式操作)
- inserted 被绑定元素插入父节点时会调用该函数,执行一次。(一般执行js相关操作)
- update 指令所在模板结构被重新解析时调用
// 自定义一个v-fbind指令,和v-bind功能类似,但是可以让绑定的input自动获取焦点 <div> <input type:'text' v-fbind:value='n'> </div> <script> //全局指令 Vue.directives('fbind',{ //指令与元素成功绑定 bind(element,binding) {element.value = binding.value}, //指令所在元素被插入页面生成真实DOM才可以获取焦点 inserted(element,binding) {element.focus() } //更新 update(element,binding) {element.value = binding.value} }) new Vue({ el:'#root', //n 的初始值 data:{n:99}, directives:{ //定义了一个局部指令 fbind:{ bind(element,binding) {element.value = binding.value}, inserted(element,binding) {element.focus() } update(element,binding) {element.value = binding.value} } } }) </script>
备注:该案例中,在bind钩子函数执行时,元素还未插入到 dom 中去,此时调用 focus() 方法无效(focus 是 原生js 的方法),所以必须在元素插入dom 之后才能调用该方法