1. 程式人生 > >vue學習筆記(五)條件渲染和列表渲染

vue學習筆記(五)條件渲染和列表渲染

前言

在眾多的程式語言中,我們的基礎語法總是少不了一些專業語法,比如像定義變數,條件語句,for迴圈,陣列,函式等等,vue.js這個優秀的前端框架中也有同樣的語法,我們換一個名詞,將條件語句改成專業詞彙叫做條件渲染,迴圈語句改成專業詞彙叫做列表渲染,這樣比較舒服一點。

本章目標

  • 學會條件渲染的使用

  • 學會可複用的key的使用

  • 學會列表渲染的使用

條件渲染

1.v-if的使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="app01">
    <span v-if="type==='A'">成績為A</span>
</div>
<script src="../js/vue.js"></script>
<script>
    let vm=new Vue({
        el:'#app01',
        data:{
            type:'A'
        },
        methods:{
            
        },
        watch:{
            
        },
        computed:{
            
        }
    })
</script>
</body>
</html>

結果:成績為A

v-if判斷條件是否相等,就像if一樣,如果相等,那麼值就會true,與之對應的還有v-else,v-else-if

2.v-else的使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="app01">
    <span v-if="type==='A'">成績為A</span>
    <span v-else>成績為B</span>
</div>
<script src="../js/vue.js"></script>
<script>
    let vm=new Vue({
        el:'#app01',    
        data:{
            type:'B'
        },
        methods:{
            
        },
        watch:{
            
        },
        computed:{
            
        }
    })
</script>
</body>
</html>

結果:成績為B

小練習

我們做一個小練習,鞏固一下v-if和v-else的使用,需求如下:點選一個按鈕時,按鈕上的文字變為顯示,再次點選時按鈕上的文字變為隱藏,當按鈕上的文字顯示隱藏時,顯示紅色,按鈕上的文字變為顯示時顯示藍色

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            .box{
                width: 100px;
                height: 100px;
            }
            .red{
                background: red;
            }
            .blue{
                background: blue;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <button @click="handleClick">{{text}}</button>
            <div v-if="show" class="box red"></div>
            <div v-else class="blue box"></div>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            let vm=new Vue({
                el:'#app',
                data:{
                    show:true,
                    text:'隱藏'
                },
                methods:{
                    handleClick(){
                        this.show=!this.show;
                        this.text=this.show?'隱藏':'顯示'
                    }
                }
            })
            
        </script>
    </body>
</html>

結果

 

3.v-else-if的使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="app01">
    <input type="text" v-model="type"/>
    <div v-if="type==='A'">成績為A</div>
    <div v-else-if="type==='B'">成績為B</div>
    <div v-else-if="type==='C'">成績為C</div>
    <div v-else>不及格</div>
</div>
<script src="../js/vue.js"></script>
<script>
    let vm=new Vue({
        el:'#app01',    
        data:{
            type:''
        },
        methods:{
            
        },
        watch:{
            
        },
        computed:{
            
        }
    })
</script>
</body>
</html>

結果:

4.v-show

說起這個v-show,其實和v-if有與曲同工的妙處,但是又有不同的地方,我們來看下示例你就秒懂了

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            .box{
                width: 100px;
                height: 100px;
            }
            .red{
                background: red;
            }
            .blue{
                background: blue;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div v-show="show" class="box red"></div>
            <button @click="handleClick()">{{text}}</button>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            let vm=new Vue({
                el:'#app',
                data:{
                    show:true,
                    text:'隱藏',
                },
                methods:{
                    handleClick(){
                        this.show=!this.show;
                        this.text=this.show?'隱藏':'顯示'
                    }
                },
                computed:{
                    
                }
            })
        </script>
    </body>
</html>

當按鈕變為顯示的時候,背景顏色消失,這裡就不截圖了,有興趣的小夥伴可以自己去嘗試,既然v-if可以幫我們實現元素的顯示和隱藏,那我們還需要v-show幹什麼呢?不妨看下接下來的例項。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            .box{
                width: 100px;
                height: 100px;
            }
            .red{
                background: red;
            }
            .blue{
                background: blue;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div v-show="show" class="box red"></div>
            <div class="box blue" v-if="show"></div>
            <button @click="handleClick()">{{text}}</button>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            let vm=new Vue({
                el:'#app',
                data:{
                    show:true,
                    text:'隱藏',
                },
                methods:{
                    handleClick(){
                        this.show=!this.show;
                        this.text=this.show?'隱藏':'顯示'
                    }
                },
                computed:{
                    
                }
            })
        </script>
    </body>
</html>

 當我們點選按鈕的時候

 

現在結果已經出來了,使用v-show的dom元素,dom元素只是簡單的切換display屬性,而v-if會將dom元素移除,當我們再次點選時,v-if又會重新渲染元素,可想而知如果頻繁的切換的話,那麼有多麼的耗費效能,因此我總結了如下幾點

  • 頻繁的切換顯示/隱藏要使用v-show

  • 只判斷一次時,使用v-if

5.減少dom的生成

我們都知道js操作dom元素是非常消耗效能的,但是我們需要儘量的避免這個問題,vue中為我們提供了一個template標籤,這個標籤叫做模板(至於什麼叫做模板,後期的部落格會講到),我們先看一個示例

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            .box{
                width: 100px;
                height: 100px;
            }
            .red{
                background: red;
            }
            .blue{
                background: blue;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div v-if="show">
                <div class="box red"></div>
                <div class="box blue"></div>
            </div>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            let vm=new Vue({
                el:'#app',
                data:{
                    show:true,
                },
                methods:{
                    
                },
                computed:{
                    
                }
            })
        </script>
    </body>
</html>

 我們想讓圖上的那個div消失,不想為了管理同一組元素而多生成一個節點,這樣是非常消耗效能的,我們將div標籤變成template標籤

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            .box{
                width: 100px;
                height: 100px;
            }
            .red{
                background: red;
            }
            .blue{
                background: blue;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <div v-if="show">
                <div class="box red"></div>
                <div class="box blue"></div>
            </div>
            <template v-if="show">
                <div class="box red"></div>
                <div class="box blue"></div>
            </template>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            let vm=new Vue({
                el:'#app',
                data:{
                    show:true,
                },
                methods:{
                    
                },
                computed:{
                    
                }
            })
        </script>
    </body>
</html>
View Code

 現在我有心中萌生了一個想法,v-if可以使用template,那麼v-show是否可以使用呢?

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            .box{
                width: 100px;
                height: 100px;
            }
            .red{
                background: red;
            }
            .blue{
                background: blue;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <template v-if="show">
                <div class="box red"></div>
                <div class="box blue"></div>
            </template>
            <template v-show="show">
                <div class="box red"></div>
                <div class="box blue"></div>
            </template>
            <button @click="handleClick()">{{text}}</button>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            let vm=new Vue({
                el:'#app',
                data:{
                    show:true,
                    text:'隱藏',
                },
                methods:{
                    handleClick(){
                        this.show=!this.show;
                        this.text=this.show?'隱藏':'顯示'
                    }
                },
                computed:{
                    
                }
            })
        </script>
    </body>
</html>
View Code

 

 答案是v-if可以使用template,而v-show不能使用template

vue中用key管理可複用的元素

Vue 會盡可能高效地渲染元素,通常會複用已有元素而不是從頭開始渲染。這麼做除了使 Vue 變得非常快之外,還有其它一些好處。例如,如果你允許使用者在不同的登入方式之間切換。

示例一:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="app01">
    <template v-if="type==='username'">
        <label>使用者名稱</label>
        <input type="text" placeholder="請輸入您的賬號" />
    </template>
    <template v-else>
        <label>郵箱</label>
        <input type="text" placeholder="請輸入您的郵箱" />
    </template>
    <p>
        <a href=""@click.prevent="type='username'">使用者名稱登入</a>|
        <a href=""@click.prevent="type='email'">郵箱登入</a>
    </p>
</div>
<script src="../js/vue.js"></script>
<script>
    let vm=new Vue({
        el:'#app01',    
        data:{
            isShow:true,
            type:'username'
        },
        methods:{
            
        },
        watch:{
            
        },
        computed:{
            
        }
    })
</script>
</body>
</html>

結果:

 

 

當我們在使用者名稱登入和郵箱切換的時候,我們發現我們輸入的內容始終保持,為什麼呢?總的來說,因為兩個模板使用了相同的元素,input不會被替換掉——僅僅是替換了它的 placeholder屬性,這樣也不總是符合實際需求,所以 Vue 為你提供了一種方式來表達這兩個元素是完全獨立的,不要複用它們,只需新增一個具有唯一值的key屬性即可。

示例二:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<div id="app01">
    <template v-if="type==='username'">
        <label>使用者名稱:</label>
        <input type="text" placeholder="請輸入您的使用者名稱"  key='usename'/>
    </template>
    <template v-else>
        <label>郵箱:</label>
        <input type="text" placeholder="請輸入您的郵箱"  key='email'/>
    </template>
    <p>
        <a href=""@click.prevent="type='username'">使用者名稱登入</a>|
        <a href=""@click.prevent="type='email'">郵箱登入</a>
    </p>
</div>
<script src="../js/vue.js"></script>
<script>
    let vm=new Vue({
        el:'#app01',    
        data:{
            isShow:true,
            type:'username'
        },
        methods:{
            
        },
        watch:{
            
        },
        computed:{
            
        }
    })
</script>
</body>
</html>

結果:

 

現在我們點選切換的時候,輸入框都會重新渲染,當然我們的<label>標籤依舊的高效的複用,因為它沒有新增key。

列表渲染

我們用v-for指令根據一組陣列的選項列表進行渲染,v-for指令需要以item in items的形式的特殊語法,items是原資料陣列並且item是元素迭代的別名

1.v-for的基本使用

語法:(item,index) in|of items

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>v-for的基本使用</title>
    </head>
    <body>
        <div id="app">
            <ul>
                <li v-for="(item) in arr">{{item}}</li>
            </ul>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            let vm=new Vue({
                el:'#app',
                data:{
                    arr:['apple','banana','pear']
                },
                methods:{
                    
                },
                computed:{
                    
                }
            })
        </script>
    </body>
</html>

結果:

當然v-for中也可以帶第二個引數index

2.v-for中帶索引

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>v-for的基本使用</title>
    </head>
    <body>
        <div id="app">
            <ul>
                <li v-for="(item,index) in arr">{{item}}--{{index}}</li>
            </ul>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            let vm=new Vue({
                el:'#app',
                data:{
                    arr:['apple','banana','pear']
                },
                methods:{
                    
                },
                computed:{
                    
                }
            })
        </script>
    </body>
</html>
View Code

3.v-for迭代字串

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>v-for的基本使用</title>
    </head>
    <body>
        <div id="app">
            <ul>
                <li v-for="(item,index) in arr">{{item}}--{{index}}</li>
            </ul>
            <ul>
                <li v-for="item in 'helloworld'">{{item}}</li>
            </ul>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            let vm=new Vue({
                el:'#app',
                data:{
                    arr:['apple','banana','pear']
                },
                methods:{
                    
                },
                computed:{
                    
                }
            })
        </script>
    </body>
</html>
View Code

4.v-for迭代物件

語法:(value,key,index) of | in items

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>v-for迭代物件</title>
    </head>
    <body>
        <div id="app">
            <ul>
                <li v-for="(value,key,index) of obj">{{value}}-{{key}}-{{index}}</li>
            </ul>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            let vm=new Vue({
                el:'#app',
                data:{
                    obj:{
                        name:'kk',
                        age:18,
                        sex:'male'
                    }
                },
                methods:{
                    
                },
                computed:{
                    
                }
            })
        </script>
    </body>
</html>

結果:

5.v-for迭代整數

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>v-for迭代物件</title>
    </head>
    <body>
        <div id="app">
            <ul>
                <li v-for="(value,key,index) of obj">{{value}}-{{key}}-{{index}}</li>
            </ul>
            <ul>
                <li v-for="item in 10">{{item}}</li>
            </ul>
        </div>
        <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            let vm=new Vue({
                el:'#app',
                data:{
                    obj:{
                        name:'kk',
                        age:18,
                        sex:'male'
                    }
                },
                methods:{
                    
                },
                computed:{
                    
                }
            })
        </script>
    </body>
</html>

結果:

注意:但我們迭代整數的時候,item從1開始而不是從0開始

總結

在本章內容中,我們一共學習了三個知識點,分別是條件渲染的使用(v-if,v-else,v-else-if),管理可複用的key,列表渲染(v-for的基本使用等等),本章的內容也多但是在實際應用上非常廣泛,畢竟這些是非常基礎的語法,基礎不牢,地動山搖,學習任何東西都需要自己一步一個腳印走出來。

&n