条件渲染

  • v-if

    • 写法:
      • v-if="表达式"
      • v-else-if="表达式"
      • v-else="表达式"
    • 适用于:切换频率较低的场景
    • 特点:不展示的DOM元素直接被移除
    • 注意:v-if可以和:v-else-if、v-else一起使用,但要求结构不能被"打断"
  • v-show

    • 写法:v-show="表达式"
    • 适用于:切换频率较高的场景
    • 特点:不展示DOM元素未被移除,仅仅是使用样式隐藏掉
  • 备注:使用v-if的时候,元素可能无法获取到,而使用v-show一定要获取到
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>条件渲染</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
        <!-- 准备好一个容器 -->
		<div id="app">
			<h2>当前的n值是:{{n}}</h2>
            <button @click="n++">点我n+1</button>
            <!-- 使用v-show做条件渲染 -->
            <h2 v-show:"false">欢迎来到{{name}}</h2>
            <h2 v-show:"1 === 1">欢迎来到{{name}}</h2>

            <!-- 使用v-if做条件渲染 -->
            <h2 v-if:"false">欢迎来到{{name}}</h2>
            <h2 v-if:"1 === 1">欢迎来到{{name}}</h2>

            <!-- v-else和v-else-if -->
            <div v-if="n===1">大理</div>
            <div v-else-if="n===2">厦门</div>
            <!-- <div>@</div> 不允许被打断 -->
            <div v-else-if="n===3">台湾</div>
            <div v-else>台湾</div>

            <!-- v-if与template的配合使用  template只是一个模板结构不会解析到画面中-->
            <!-- v-show不可以和template的配合使用 -->
            <template v-if="n===1">
                <h2>你好</h2>
                <h2>同福客栈</h2>
                <h2>武林外传</h2>
            </template>
		</div>
	</body>
 
    <script type = "text/javascript">
        Vue.config.productionTip = false
 
        // 创建Vue实例
	    const vm = new Vue({
		    el: '#app',
		    data:{
				name:'武林外传'
            },
	</script>
</html>

列表渲染

  • v-for指令

    • 用于展示列表数据
    • 语法:v-for="(item, index) in  xxx" :key="yyy"
    • 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>条件渲染</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
        <!-- 准备好一个容器 -->
		<div id="app">
            <!-- 遍历数组 -->
            <ul>
                <li>xxx-xxx</li>
                <li>xxx-xxx</li>
                <li>xxx-xxx</li>
                
                <h2>人员列表</h2>
                <li>姓名-年龄</li>
                <!-- :key="表达式"使每一个li节点都动态绑定一个唯一标识 -->
                <!-- key="1"生成的li标识都是1 -->
                <li v-for="p in persons" :key="p.id">
                    <!-- 插值语法 p还可以来自属性 -->
                    {{p.name}}-{{p.age}}
                </li>
                <li v-for="(a,b,c) in persons" :key="p.id">
                    <!-- 输出的分辨是item(遍历的每一项)---索引值(数组里的第几个0开始)---undefined -->
                    {{a}---{{b}}---{{c}}
                    <!-- {id:'001',name:'张三',age:18}---0---  -->
                </li>
                <li v-for="(p,index) in persons" :key="index">
                    {{p.name}}-{{p.age}}
                </li>
                <li v-for="(p,index) of persons" :key="index">
                    {{p.name}}-{{p.age}}
                </li>
            </ul>

            <!-- 遍历对象 -->
            <h2>汽车信息</h2>
            <ul>
                <li v-for="(value, k) in car" :key="k">
                    {{value}}-{{k}}
                </li>
                <!-- 
                    奥迪A8-name
                    70万-price
                    黑色-color
                -->
            </ul>

            <!-- 遍历字符串 -->
            <h2>测试遍历字符串</h2>
            <ul>
                <li v-for="(char, index) in str" :key="index">
                    {{char}}-{{index}}
                </li>
                <!-- 
                    h-0
                    e-1
                    y-2
                -->
            </ul>

            <!-- 遍历指定次数 -->
            <h2>测试遍历指定次数(用得少)</h2>
            <ul>
                <li v-for="(number, index) in 3" :key="index">
                    {{number}}-{{index}}
                </li>
                <!-- 
                    1-0
                    2-1
                    3-2
                -->
            </ul>
		</div>
	</body>
 
    <script type = "text/javascript">
        Vue.config.productionTip = false
 
        // 创建Vue实例
	    const vm = new Vue({
		    el: '#app',
		    data:{
				persons:[
                    {id:'001',name:'张三',age:18},
                    {id:'002',name:'李四',age:19},
                    {id:'003',name:'王五',age:20}
                ],
                car:{
                    name:'奥迪A8',
                    price:'70万',
                    color:'黑'
                },
                str:'hey'
            },
	</script>
</html>

key作用与原理

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>条件渲染</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
        <!-- 准备好一个容器 -->
		<div id="app">
            <!-- 遍历数组 -->
            <h2>人员列表(遍历数组)</h2>
            <button @click.once='add'>添加一个人</button>
            <ul>
                <li v-for="(p,index) of persons" :key="index">
                    {{p.name}}-{{p.age}}
                </li>
            </ul>
		</div>
	</body>
 
    <script type = "text/javascript">
        Vue.config.productionTip = false
 
        // 创建Vue实例
	    const vm = new Vue({
		    el: '#app',
		    data:{
				persons:[
                    {id:'001',name:'张三',age:18},
                    {id:'002',name:'李四',age:19},
                    {id:'003',name:'王五',age:20}
                ]
            },
            method:{
                add(){
                    const p = {id:'004',name:'赵六',age:40}
                    // 数组的最前面加一个数组p
                    this.persons.unshift(p)
                }
            }
	</script>
</html>

遍历列表时key的作用(index作为key)

遍历列表时key的作用(数据唯一标识id作为key)

总结

面试题: react、 vue中的key有什么作用? (key的内部原理)

  • 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是没有问题的。

列表过滤

用监视属性watch实现

ps:#region #endregion可以折叠代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>条件渲染</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
        <!-- 准备好一个容器 -->
		<div id="app">
            <h2>人员列表</h2>
            <!-- 收集用户输入 -->
            <input type="text" placeholder="请输入名字" v-model="keyWord"/>
            <ul>
                <li v-for="(p,index) of filPerons" :key="index">
                    {{p.name}}-{{p.age}}
                </li>
            </ul>
		</div>
	</body>
 
    <script type = "text/javascript">
        Vue.config.productionTip = false
 
        // 创建Vue实例
	    const vm = new Vue({
		    el: '#app',
		    data:{
                keyWord:'',
				persons:[
                    {id:'001',name:'马冬梅',age:18,sex:'女'},
                    {id:'002',name:'周冬雨',age:19,sex:'女'},
                    {id:'003',name:'周杰伦',age:20,sex:'男'},
                    {id:'004',name:'温兆伦',age:21,sex:'男'}
                ],
                filPerons:[]
            },
            watch:{
                // 输入框value值改变时触发
                keyWord:{
                    immediate:true,//初始化时让handler调用一下 即:handler('')
                    handler(val){
                        console.log('keyWord被改了', val)
                        // 过滤数据-不会影响原数据,而是返回一个全新的数组数据
                        // 只有将新数组重新赋值给persons才可以变化 但是过滤的数据真的不见了
                        // 赋值给filPerons并遍历filPerons
                        this.filPerons= this.persons.filter((p)=>{
                            // indexOf是否包含某字符串 不包含返回-1 包含则返回所在位置(0开始)
                            // indexOf('')indexOf一个空字符串会返回0而不是-1
                            retuen p.name.indexOf(val) !== -1
                        })
                    }
                }    
            }
        })
	</script>
</html>

用计算属性computer实现

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>条件渲染</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
        <!-- 准备好一个容器 -->
		<div id="app">
            <h2>人员列表</h2>
            <!-- 收集用户输入 -->
            <input type="text" placeholder="请输入名字" v-model="keyWord"/>
            <ul>
                <li v-for="(p,index) of filPerons" :key="index">
                    {{p.name}}-{{p.age}}
                </li>
            </ul>
		</div>
	</body>
 
    <script type = "text/javascript">
        Vue.config.productionTip = false
 
        // 创建Vue实例
	    const vm = new Vue({
		    el: '#app',
		    data:{
                keyWord:'',
				persons:[
                    {id:'001',name:'马冬梅',age:18,sex:'女'},
                    {id:'002',name:'周冬雨',age:19,sex:'女'},
                    {id:'003',name:'周杰伦',age:20,sex:'男'},
                    {id:'004',name:'温兆伦',age:21,sex:'男'}
                ]
            },
            computed:{
                filPerons(){
                    // 计算属性的return即filPerons的结果
                    return this.persons.filter((p)=>{
                        // filter的返回值 过滤的结果数组
                        retuen p.name.indexOf(this.keyWord) !== -1
                    })
                }
            }
        })
	</script>
</html>

列表排序

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>条件渲染</title>
		<script type="text/javascript" src="../js/vue.js"></script>
	</head>
	<body>
        <!-- 准备好一个容器 -->
		<div id="app">
            <h2>人员列表</h2>
            <input type="text" placeholder="请输入名字" v-model="keyWord"/>
            <button @click="sortType =2">年龄升序</button>
            <button @click="sortType =1>年龄降序</button>
            <button @click="sortType =0">原顺序</button>
            <ul>
                <li v-for="(p,index) of filPerons" :key="p.id">
                    {{p.name}}-{{p.age}}
                </li>
            </ul>
		</div>
	</body>
 
    <script type = "text/javascript">
        Vue.config.productionTip = false
 
        // 创建Vue实例
	    const vm = new Vue({
		    el: '#app',
		    data:{
                keyWord:'',
                sortType:0,//0原顺序 1降序 2升序
                //原数据
				persons:[
                    {id:'001',name:'马冬梅',age:30,sex:'女'},
                    {id:'002',name:'周冬雨',age:18,sex:'女'},
                    {id:'003',name:'周杰伦',age:29,sex:'男'},
                    {id:'004',name:'温兆伦',age:21,sex:'男'}
                ]
            },
            // 只要计算属性中任何一个属性发生变化 计算属性都会重新计算
            computed:{
                filPerons(){
                    // 过滤结果数组
                    const arr = this.persons.filter((p)=>{
                        // filter的返回值 过滤的结果数组
                        retuen p.name.indexOf(this.keyWord) !== -1
                    })
                    // 判断一下是否需要排序
                    // 只要不是0转成bool型就是1
                    if(this.sortType){
                        // 排序会收到两个数据项sort(前项,后项)会改变原数组
                        // 升序:前项-后项;降序:后项-前项
                        arr.sort((p1,p2)=>{
                            return this.sortType === 1? p2.age-p1.age:p1.age-p2.age
                        })
                    }
                    // filPerons的结果
                    return arr
                }
            }
        })
	</script>
</html>

更多推荐

【VUE】遍历列表