vue: 条件渲染v-if和循环v-for

知识点: v-if、v-for、在vue中重写的数组的方法、识别不同的dom节点

v-if

条件渲染有三个: v-if v-else-if v-else,使用方法跟js相似

他们是把多余的dom节点去除(不是none)

        <div id="app">
    <p v-if='items > 10'>有库存{{ items }}个</p>
    <p v-else-if='0<items && items<=10'>即将售馨</p>
    <p v-else>没有货啦,下次光临</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
 new Vue({
     el: "#app",
     data: {
         items: 0,
      }
})
</script>
      

v2-075bc0fa31aaff717fdbbbd360de641e_b.jpg

template标签

既想使用一个标签包裹需要需要的标签,又不想显示包裹标签,可以使用template标签

v-if == true显示

v-if == false隐藏

        <div id="app">
    <template v-if="show">
        <p>我是第一个P标签</p>
        <p>我是第二个P标签</p>
    </template>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data: {
            show: true,
        }
})
</script>
      

v2-f37e6e418ef09037f00c0c134cabc996_b.jpg


v-show

v-show == true 把dom节点显示

v-show == false 把dom节点隐藏(display:none)

        <div id="app">
    <button @click = "show = !show">点击显示隐藏</button>
    <p v-show = "show">我是用v-shou显示</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data: {
            show: true,
        }
    })
</script>
      

v2-2a81be61d450154088ece01e13bce16b_b.jpg


v-for

v-for的基础使用方法

        <div id="app">
    <ul>
        <li v-for = 'item in movies'>{{ item }}</li>
    </ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
     new Vue({
         el: "#app",
         data: {
             movies: ['扫毒2天地对决', '跳舞吧!大象', '英雄之战', '复仇者联盟4:终局之战']
         }
    })
</script>
      

v2-0fc44194f39a7905b937eb3a248d01ac_b.jpg

在数组中使用对象增加评分

        <div id="app">
    <ul>
        <li v-for = 'item in movies'>电影名称:{{ item.movie }}|评分:{{ item.rate }}</li>
    </ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
 new Vue({
            el: "#app",
            data: {
                movies: [{
                    movie: '扫毒2天地对决',
                    rate: '8.1',
                },{
                    movie: '跳舞吧!大象',
                    rate: '7.6',
                },{
                    movie: '英雄之战',
                    rate: '6.4',
                },{
                    movie: '复仇者联盟4:终局之战',
                    rate: '9.1',
                },]
            }
        })
</script>
      

v2-bff2abd497d0df5622ee4105561ea4b5_b.jpg

索引: 在item中可以分成item和index(自定义)来写

        <li v-for = '(item, index) in movies'>{{ index }}|电影名称:{{ item.movie }}|评分:{{ item.rate }}</li>
      

v2-2fc5a8d0aa75fd0572371e7d995897eb_b.jpg

循环对象

第一个形参: 对象值

第二个形参:对象名

第三个形参: 对象索引

        <div id="app">
    <p v-for = '(value, prop, index) in person'>{{ index }}|{{ prop }}|{{ value }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data: {
            person: {
                name: 'fanghuayong',
                age: '18',
                sex: '男'
            }
        }
    })
</script>
      

v2-3b12f5694d1f2fc833ba5348080491d4_b.jpg


v-for还可以循环数字和字符

        <ul>
    <li v-for="num in 10">{{ num }}</li>
</ul>
<p v-for="str in 'fanghuayong'">{{ str }}</p>
      

v2-17b59c16f9d36d1e5a22d354c513cbe6_b.jpg
v-for在开发中的使用:
通常结合template标签使用,因为template标签不会有dom节点
不能直接改变数组中的数据
有一些重写的方法,如push
:key值告诉模板每隔渲染的不一样


写个需求1:

在使用鼠标点击列表中的电影,电影的名字变成西虹市首富,评分6.5

点击之前

v2-945e336c1f8871fbac7b08c811cd0f4c_b.jpg

代码:

        <div id="app">
    <ul>
        <li v-for = '(item, index) in movies' @click = 'changeMovie(index)'>{{ index }}|电影名称:{{ item.movie }}|评分:{{ item.rate }}</li>
    </ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: "#app",
        data: {
            movies: [{
                    movie: '扫毒2天地对决',
                    rate: '8.1',
                },{
                    movie: '跳舞吧!大象',
                    rate: '7.6',
                },{
                    movie: '英雄之战',
                    rate: '6.4',
                },{
                    movie: '复仇者联盟4:终局之战',
                    rate: '9.1',
                },],
                person: {
                    name: 'fanghuayong',
                    age: '18',
                    sex: '男'
                }
            },
        methods: {
            changeMovie: function(i){
            // 先定位到点击的是哪个li
                console.log(i)
                this.movies[i] = {
                     movie: "西虹市首富",
                     rate: '6.5',
                }
                 console.log(this.movies)
                }
            }
     })
</script>
      

点击后:

v2-6d845e90bda7197e2b1b340df3c8cc9e_b.jpg

为什么数据发生改变了,内容没有刷新?

在vue中,数组直接改变,不会被检测到,所以也面不会刷新。(因为数组是引用值,新数据和旧数据的内存地址都一样,所以不会发生改变)

那么如何改变数组中的元素?

使用副本 coucat(),改变为新的内存地址,把列表替换到新数组上。(使vue检测到数据发生改动,重新渲染)

        // js的vue中的metods字段
 methods: {
 changeMovie: function(i){
     let arr = this.movies.concat()
     arr[i] = {
         movie: "西虹市首富",
         rate: '6.5',
     }
     this.movies = arr
 }
}

      

v2-697a91f2b4f18238b1a69cbc06cb2f47_b.jpg

dom节点已刷新


需求2: botton按键每点击一下,新增一部电影

        <!-- html新增代码 -->
<button @click = "add">新增电影</button>

<!-- js的vue中的metods字段 -->
methods: {
    changeMovie: function(i){
        let arr = this.movies.concat()
        arr[i] = {
            movie: "西虹市首富",
            rate: '6.5',
        }
        this.movies = arr
    },
    add: function() {
         this.movies.push({
             movie: "东虹市首富",
             rate: '6.6',
         })
    }
}
      

v2-44877c58d5c48647b751abe758852c05_b.jpg

为什么我们使用push方法新增,并没有改变内存地址,但是刷新dom了呢?(push是数组原型链上的方法)

因为在vue中重写了push()方法,使在使用push()后vue监测到数据发生变化,所以重新渲染了。

备注:vue中重写了push/pop/reverse等方法,大概有六七个,等有时间再看。


让dom节点识别成不同的dom节点

需求: 使input框倒置

        <div id="app">
    <template v-for = "item in arr">
        <p>{{ item }}</p>
        <input type="text">
    </template>
    <button @click = 'reverse'>倒置</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
 new Vue({
     el: "#app",
     data: {
         arr: [1, 2, 3],
     },
     methods: {
         reverse: function() {
             this.arr.reverse();
         }
      }
 })
</script>
      

倒置前:

v2-7ebd40ce7183f57de3bf87536e2ab71d_b.jpg

倒置后:

v2-579f794e31e15e5a1746b70911b17956_b.jpg

问题: reverse也是重写的方法,为什么p标签倒置了,input框没有被倒置呢?

渲染机制: 渲染的时候这几个input框没有什么区别,识别的时候也没有什么不同,为了节省资源,没有重排重绘。

解决: 使用v-bind:绑定key,给不同的input框绑定不同的值,这里刚好可以使用循环的item。这样就可以识别成不一样的input。

        <input type="text" :key = "item">
      

倒置前:

v2-27abc0e9555e7ac82d2a517f88507ac8_b.jpg

倒置后

v2-081166070d882a9a4cbbab94bbbb758b_b.jpg

成功。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值