自学vue第二天(理论)

95 阅读4分钟

自学Vue第二天

1.条件渲染

v-if与v-show

条件渲染:
1.v-if 
v-if 有个搭档叫template标签 不影响布局
写法:
(1).v-if="表达式”
(2).v-else-if="表达式"
(3) .v-else="表达式”
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意: v-if可以和:v-else-if、v-else起使用, 但要求结构不能被“打断”。
2. V-show
写法: v-show=" 表达式”
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
3.备注:使用v-if的时,元素可能无法获取到,而使用v-show 定可以获取到。

2.列表渲染

v-for

key 中的 index 和属性的索引

1.虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当状态中的数据发生变化时,Vue会根据[新数据]生成(新的虚拟DOM],
随后Vue进行[新虚拟DOM]与[旧虚拟DOM]的差异比较,比较规则如下:

2.对比规则:
(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
①.若虛拟DOM中内容没变,直接使用之前的真实DOM !
②.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
(2).旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到到页面。

3.用index作为key可能会引发的问题:
1.若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新==> 界面效果没问题,但效率低。
2.如果结构中还包含输入类的DOM:
会产生错误DOM更新==>界面有问题。

4.开发中如何选择key?:
1.最好使用每条数据的唯一标 识作为key,比如id、 手机号、身份证号、学号等唯一值。
2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,
使用index作为key是没有问题的。

3.模糊查询案例

使用filter遍历

  <div id="root">
      <h2>人员列表</h2>
      <input type="text" value="请输入" v-model="keyWold" />
      <ul>
        <li v-for="(p,index) of fillperson " :key="p.id">
            <p>{{p.name}}--{{p.sex}}--{{p.age}}</p>
        </li>
<button @click="sortType = 2">升序</button>
<button @click="sortType = 1 ">降序</button>
<button @click="sortType = 0">原顺序</button>
      </ul>
    </div>
    <script>
        new Vue({
            el: '#root',
            data: {
                sortType : 0 , //默认为原来顺序 1降序 2升序
                keyWold: '', //页面的输入框的值
                persons:[{
                    id:'001',name:'张三',sex:'男',age:10
                },{
                    id:'002',name:'张四',sex:'男',age:17
                },{
                    id:'003',name:'李四',sex:'女',age:11
                },{
                    id:'004',name:'李五',sex:'女',age:15
                },]
            },
            computed: {
                fillperson(){
                    const arr = this.persons.filter((p)=>{
                        return p.name.indexOf(this.keyWold) !== -1
                    })
                    if(this.sortType){
                        //sort 排序 
                        arr.sort((p1,p2)=>{
                            // 如果是一就返回降序 如果不是就降序
                            return this.sortType === 1 ? p2.age - p1.age : p1.age -p2.age
                        })
                    }
                    // 计算属性一定要有返回值
                    return arr
                }
            }
            
        })
    </script>

4.数据劫持与列表渲染

<!-- 劫持 拥有get 和set就被劫持了 
Vue监视数据的原理:
1. vue会监视data中所有层次的数据。
2.如何监测对象中的数据?
    通过setter实现监视,且要在new Vue时就传入要监测的数据。
    (1).对象中后追加的属性,Vue默认不做响应式处理
    (2) .如需给后添加的属性做响应式,请使用如下API:
   Vue. set(target,propertyName/index,value) 或
   Vm.$set(target,propertyName/index,value)
3.如何监测数组中的数据?
     通过包裹数组更新元素的方法实现,本质就是做了两件事:
     (1).调用原生对应的方法对数组进行更新。
     (2).重新解析模板,进而更新页面。
4.Vue修改数组中的某个元素一定要用如 下方法: 
    1.使用这些API:push()、pop()、 shift()、 unshift()、 splice()、 sort()、 reverse( )
    2.Vue.set()或vm.$set( )
特别注意: Vue.set() 和vm.$set() 不能给vm或vm的根数据对象添加属性  -->

案例

<div id="root">
			<h1>学生信息</h1>
			<button @click="student.age++">年龄+1岁</button> <br/>
			<button @click="addSex">添加性别属性,默认值:男</button> <br/>
			<button @click="student.sex = '未知' ">修改性别</button> <br/>
			<button @click="addFriend">在列表首位添加一个朋友</button> <br/>
			<button @click="updateFirstFriendName">修改第一个朋友的名字为:张三</button> <br/>
			<button @click="addHobby">添加一个爱好</button> <br/>
			<button @click="updateHobby">修改第一个爱好为:开车</button> <br/>
			<button @click="removeSmoke">过滤掉爱好中的抽烟</button> <br/>
			<h3>姓名:{{student.name}}</h3>
			<h3>年龄:{{student.age}}</h3>
			<h3 v-if="student.sex">性别:{{student.sex}}</h3>
			<h3>爱好:</h3>
			<ul>
				<li v-for="(h,index) in student.hobby" :key="index">
					{{h}}
				</li>
			</ul>
			<h3>朋友们:</h3>
			<ul>
				<li v-for="(f,index) in student.friends" :key="index">
					{{f.name}}--{{f.age}}
				</li>
			</ul>
		</div>
	</body>

	<script type="text/javascript">
		Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

		const vm = new Vue({
			el:'#root',
			data:{
				student:{
					name:'tom',
					age:18,
					hobby:['抽烟','喝酒','烫头'],
					friends:[
						{name:'jerry',age:35},
						{name:'tony',age:36}
					]
				}
			},
			methods: {
				// 添加属性
				addSex(){
					Vue.set(this.student,'sex','男')
				},
				//在首位添加一个朋友
				addFriend(){
					this.student.friends.unshift({name:'李四',age:35})
				},
				// 修改
				updateFirstFriendName(){
					this.student.friends[0].name = '张三'
				},
				// 添加爱好
				addHobby(){
					this.student.hobby.push('大哥')
				},
				// 修改第一个爱好为开车
				updateHobby(){
					// this.student.hobby.splice(0,1,'开车')
					// Vue.set(this.student.hobby,0,'开车')
					this.$set(this.student.hobby,0,'开车');
				},
				//因为filter不是七个允许的语法中其中一个 所以只能用这种覆盖
				removeSmoke(){
					this.student.hobby = this.student.hobby.filter((p)=>{
						return p != '抽烟'
					})
				}
			}
		})
	</script>

5.收集表单数据

收集表单数据:
若: <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:输入首尾空格过滤

6.过滤器

过滤器:
定义:对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)。
语法:
1.注册过滤器: Vue.filter(name , callback)或new Vue{filters:{}}
2.使用过滤器: {{ xxx|过滤器名}} 或v-bind:属性 = "xxx|过滤 器名"
备注:
1.过滤器也可以接收额外参数、多个过滤器也可以串联
2.并没有改变原本的数据,是产生新的对应的数据

7.内置指令

v-bind	: 单向绑定解析表达式, 可简写为 :xxx
v-model	: 双向数据绑定
v-for: 遍历数组/对象/字符串
v-on: 绑定事件监听, 可简写为@
v-if: 条件渲染(动态控制节点是否存存在)
v-else:条件渲染(动态控制节点是否存存在)
v-show:条件渲染 (动态控制节点是否展示)
v-text指令:
1.作用:向其所在的节点中渲染文本内容。
2.与插值语法的区别:v-text会替换掉节点中的内容,{{xx}}则不会。
v-html指令:
1.作用:向指定节点中渲染包含html结构的内容。
2.与插值语法的区别:
		(1).v-html会替换掉节点中所有的内容,{{xx}}则不会。
		(2).v-html可以识别html结构。
3.严重注意:v-html有安全性问题!!!!
		(1).在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
		(2).一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
v-cloak指令(没有值):
1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
2.使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题。
v-once指令:
1.v-once所在节点在初次动态渲染后,就视为静态内容了。
2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
v-pre指令:
1.跳过其所在节点的编译过程。
2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。