Vue条件渲染与列表渲染

条件渲染

  1. v-if
    1. 写法:
      1. v-if="表达式"
      2. v-else-if="表达式"
      3. v-else="表达式"
    2. 适用于:切换频率较低的场景。
    3. 特点:不展示的DOM元素直接删除。
    4. 注意:v-if可以与:v-else-if、v-else一起使用,但要求结构不能被打断。
  2. v-show
    1. 写法:v-show='表达式'。
    2. 适用于:切换频率较高的场景。
    3. 特点:不展示的DOM元素会被隐藏。
  3. 备注:使用v-if时,元素可能无法获取到,二使用v-show一定可以获取到。
<div id="root">
    <h1>当前值:{{val}}</h1>
    <button @click="val++">点击增加值</button>
    <!-- v-show条件成立就显示,否则就隐藏 -->
    <label v-show="val===1">我是第一个值</label>
    <label v-show="val===2">我是第二个值</label>
    <label v-show="val===3">我是第三个值</label>
    
    <br/>
    <!-- v-if条件成立就显示,否则就从DOM中删除掉,Vue会一行一行判断 -->
    <label v-if="val===1">******我是第一个值******</label>
    <label v-else-if="val===2">******我是第二个值******</label>
    <label v-else-if="val===3">******我是第三个值******</label>

    <br/>
    <!-- v-else-if条件成立就显示,否则就从DOM中删除掉,语句必须紧挨着一起,如果前面的if成立,Vue就不会看下面的语句了(效率更高) -->
    <label v-if="val===1">-------我是第一个值</label>
    <label v-else-if="val===2">-------我是第二个值</label>
    <label v-else-if="val===3">-------我是第三个值</label>

    <br/>
    <!-- v-if或者v-else-if条件成立就显示,否则就从DOM中删除掉,语句必须紧挨着一起,如果前面的if都不成立,Vue就会执行v-else中的语句 -->
    <label v-if="val===1">#######我是第一个值#######</label>
    <label v-else-if="val===2">#######我是第二个值#######</label>
    <label v-else>#######我哪个值都不是#######</label>
</div>

<script>
    new Vue({
        el: "#root",
        data: {
            val: 0
        }
    })
</script>

v-if与template配合使用

<div id="root">
    <h1>当前值:{{val}}</h1>
    <button @click="val++">点击增加值</button>
    <!-- v-show条件成立就显示,否则就隐藏 -->
    <br/>
    <!-- template不影响页面结构,显然的时候会被自动删除,只能配合v-if使用 -->
    <template v-if="n===1">
        <label>******我是第一个值******</label>
        <label>******我是第二个值******</label>
        <label>******我是第三个值******</label>
    </template>
</div>

<script>
    new Vue({
        el: "#root",
        data: {
            val: 0
        }
    })
</script>

列表渲染

v-for指令:

  1. 用于展示列表数据。
  2. 语法:v-for="(item,index) in xxx" :key="yyy",index有添加或者删除的场景下一般不当作key,key一般用数据的id。
  3. 可遍历:数组,对象,字符串(用的很少),指定次数(用的很少)。

遍历数组

<ul id="root">
    <!-- index是下标,key必须是唯一的 -->
    <li v-for="(p,index) in persons" :key="p.id">{{p.id}}------------{{p.name}}----------下标:{{index}}</li>
    
    <!-- 
        <li v-for="p in persons" :key="p.id">{{p.id}}------------{{p.name}}</li> 
    -->
</ul>


<script>
    new Vue({
        el: "#root",
        data: {
            persons: [
                { id: 1, name: '李义新' },
                { id: 2, name: '李二新' },
                { id: 3, name: '李三新' },
                { id: 4, name: '李四新' }
            ]
        }
    })
</script>

遍历对象

<ul id="root">
    <li v-for="(value,key) in obj" :key="key">{{value}}----------{{key}}</li>
</ul>
<script>
    new Vue({
        el: "#root",
        data: {
            obj: {
                name: "李义新",
                sex: "男",
                age: 11
            }
        }
    })
</script>
  1. 虚拟DOM中key的作用:
    1. key是虚拟DOM对象的标识,当数据发生改变时,Vue会根据【新数据】生成【新的虚拟DOM】,然后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较。
  2. 比较规则:
    1. 旧虚拟DOM中找到了与新虚拟DOM相同的key
      1. 若虚拟DOM中内容没变, 直按使用之前的真实DOM。
      2. 若虚拟DOM中内容变了,则生成新的真实DOM,然后替换掉页面中之前的真实DOM。
    2. 旧虚拟DOM中未找到与新虚拟DOM相同的key
      1. 创建新的真实DOM,随后渲染到到页面。
    3. 用index作为key可能会引发的问题
      1. 若对数据进行:逆序添加,逆序删除等破坏顺序的操作,会产生没有必要的真是DOM更新->界面效果没有问题,但效率低。
      2. 如果结构中还包含输入类的DOM:会产生错误的DOM更新->界面有问题。
    4. 如何选择key
      1. 最好使用每条数据的唯一标识作为key,比如id,手机号。
      2. 如果不存在对数据的逆序操作,逆序删除等破幻顺序的操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。

列表渲染 

模糊查询功能的实现

模糊查询时优先使用computed。

使用监听器的方式查询

<div id="root">
<h1>人员列表</h1>
<input type="text" placeholder="请输入名字" v-model="keyword">
<ul>
    <li v-for="(p,index) in filterPersons" :key="index">
        {{p.name}}-{{p.age}}-{{p.sex}}
    </li>
</ul>
</div>

<script type="text/javascript">
new Vue({
    el: "#root",
    data: {
        keyword: "",
        persons: [
            { id: "001", name: "马冬梅", age: 19, sex: "女" },
            { id: "002", name: "周冬丽", age: 20, sex: "女" },
            { id: "003", name: "周杰伦", age: 21, sex: "男" },
            { id: "004", name: "温兆伦", age: 22, sex: "男" }
        ],
        filterPersons: []
    },
    watch: {
        keyword: {
            immediate: true,
            handler(newValue) {
                this.filterPersons = this.persons.filter((p) => {
                    return p.name.indexOf(this.keyword) !== -1;
                })
            }
        }
    }
})
</script>

使用计算属性的方式查询

<div id="root">
    <h1>人员列表</h1>
    <input type="text" placeholder="请输入名字" v-model="keyword">
    <ul>
        <li v-for="(p,index) in filterPersons" :key="index">
            {{p.name}}-{{p.age}}-{{p.sex}}
        </li>
    </ul>
</div>

<script type="text/javascript">
    new Vue({
        el: "#root",
        data: {
            keyword: "",
            persons: [
                { id: "001", name: "马冬梅", age: 19, sex: "女" },
                { id: "002", name: "周冬丽", age: 20, sex: "女" },
                { id: "003", name: "周杰伦", age: 21, sex: "男" },
                { id: "004", name: "温兆伦", age: 22, sex: "男" }
            ]
        },
        computed: {
            filterPersons() {
                return this.persons.filter((p) => {
                    return p.name.indexOf(this.keyword) !== -1;
                })
            }
        }
    })
</script>

列表排序

<div id="root">
    <h1>人员列表</h1>
    <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) in filterPersons" :key="index">
            {{p.name}}-{{p.age}}-{{p.sex}}
        </li>
    </ul>
</div>

<script type="text/javascript">
    new Vue({
        el: "#root",
        data: {
            keyword: "",
            sortType: 0,   //0代表原,1代表降序,2代表升序
            persons: [
                { id: "001", name: "马冬梅", age: 23, sex: "女" },
                { id: "002", name: "周冬丽", age: 34, sex: "女" },
                { id: "003", name: "周杰伦", age: 11, sex: "男" },
                { id: "004", name: "温兆伦", age: 45, sex: "男" }
            ]
        },
        computed: {
            filterPersons() {
                const arr = this.persons.filter((p) => {
                    return p.name.indexOf(this.keyword) !== -1;
                });
                if (this.sortType) {
                    arr.sort((p1, p2) => {
                        return this.sortType === 1 ? p2.age - p1.age : p1.age - p2.age;
                    })
                }
                return arr;
            }
        }
    })
</script>

关于数组的更改

例如:vm.myArr[0]="xin";这样vue监测不到数据的改变,不会时模板重新解析。

只有调用push(),pop(),shift(),unshift(),splice(),sort(),reverse()这七个方法操作数组时Vue才会监测到数组的改变并重新解析模板。

Vue.ser(vm.myArr,0,"xin");    //设置第一个元素为‘xin’。

vm$.ser(vm.myArr,0,"xin");    //设置第一个元素为‘xin’。

上面两种方式也可以更改数组元素后被Vue监测到并解析模板。

也可以用新的数组替换掉旧的数组,替换后模板也会重新解析。

Vue监视数据的原理(总结)

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

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值