Vue 指令 / 頁面展示

頁面展示

基本指令
  • v-text
    用于在頁面中展示數據,可以簡寫為{{ }}的形式

    <p v-text="msg"></p>
    <p>{{msg}}</p>
    <!--這兩種寫法是等價的-->
    
  • v-html
    同樣是用于展示數據,與v-text區別相當于innerHtml和textContent

    <div v-html="msg"></div>
    
  • v-pre
    用來在展示頁面是跳過渲染某一段代碼,該方法主要可以用來跳過沒有指令的代碼來提高加載速度

    <p v-pre>{{msg}}</p>
    
  • v-once
    添加了該指令的元素/組件只會渲染一次,之后vue重新渲染時會直接跳過該元素/組件,即使我們改變元素/組件引用的數據,元素也不會重新渲染,我們可以在內容固定的元素/指令上使用該指令來節省性能

    <tem v-once></tem>
    <p v-once>{{msg}}</p> 
    
  • v-bind
    可以綁定一個或多個動態,或者一個組件的prop,在vue中可以使用v-bing來將元素本身的屬性變為動態特性, 成為動態特性后可以接受變量值,使元素更加靈活,可以簡寫為 " : " 的形式

    <div :style="" :class=""></div>
    <img :src="變量值">
    
  • v-on
    綁定事件監聽器,事件類型由參數指定,表達式可以是一個方法的名字或者是一個內聯語句,當用在普通元素上時只支持原生DOM事件,用在組件上時可以支持自定義事件,可以簡寫為"@"形式

    <div @click="click"></div>
    <div @click="bool=!bool"></div>
    <button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
    
  • v-cloak
    該指令是vue用來配合css樣式在vue沒有在頁面渲染完成之前,使用該指令的元素不顯示,使用戶界面不會展示在渲染未完成之前的{{msg}}之類的修飾符,該指令會在頁面渲染完成之后自動被去除

    <style>
      [v-cloak]{
        display:none;
      }
    </style>
    <div v-cloak></div>
    
  • ref
    ref用來給元素或者子組件設定引用信息,引用信息將會注冊在父組件的$refs對象上,如果在普通的DOM上使用,引用指向的就是DOM元素對象,如果在組件上使用,引用指向的就是子組件對象

    <p ref="p">{{picked}}</p>
    
    new Vue({
     ...
     created(){
        console.log(this.$refs.p,"created"); // p undefined
        this.$refs.p.style.color="red"; //Cannot read property 'style' of undefined"
      },
      mounted(){
        console.log(this.$refs,"mounted"); //p:p
        this.$refs.p.style.color="red";
      }
    })
    

    通過ref注冊的元素/組件可以在父組件的this.$refs中獲取,但是需要注意的是,我們注冊的元素/組件初始渲染時不能被獲取到的,只有在創建完成時才能被獲取,因為ref本身是作為渲染結果被創建的,同時refs也不是響應式的

綁定HTML class樣式
<div id="box">
    <!--傳入一個對象,對應值來控制當前元素的樣式-->
    <p :class="{col:bool,weight:bool}" class="size" @click="change">hello</p>
    <!--傳入一個實例中的計算屬性,通過計算屬性的返回值控制當前元素的樣式-->
    <p :class="classList">hello</p>
    <!--傳入一個實例中的對象,對象中定義的值會控制當前元素的樣式-->
    <p :class="classObj">hello</p>
    <!--傳入一個數組,可以用來接收多個樣式對象-->
    <!--可以通過使用三元表達式來控制當前元素樣式-->
    <p :class="[bool?classList:'']">hello</p>
    <!--也可以通過在數組中傳入對象來傳入多個樣式-->
    <p :class="[classList,{col:bool}]">hello</p>
</div>
<script>
    new Vue({
        data: {
            bool: true,
            classList: {
                colGreen: true,
                style: true
            },
            col: true,
            error: {
                type: "fatal"
            }
        },
        computed: {
            classObj: function () {
                return {
                    col: this.col && !this.error,
                    weight: this.error && this.error.type === "fatal"
                }
            }
        },
        methods: {
            change() {
                this.bool = false;
            }
        }
    }).$mount("#box")
</script>

:class樣式能夠和原生的class屬性共存,在元素被渲染后,:class樣式和class的樣式都會被保留

在使用組件的時候,在組件上內部添加的樣式將會和在組件上添加的樣式一同被渲染

<body>
<div id="box">
    <tem class="size"></tem>
</div>
<script>
    const Tem={
        template:`
            <div class="box">
                <p class="col">hello</p>
            </div>
        `
    }
    new Vue({
        el:"#box",
        components:{
            "tem":Tem
        }
    })
    //模板最后的渲染結果是
    //<div class="size box">
    //<p class="col">hello</p>
    //</div>
</script>
</body>
綁定內聯 style樣式
  • 對象語法
    :style的對象語法十分直觀,css屬性名可以用駝峰命名法或者短橫分割命名

    <div :style="{color:activeColor,fontSize:fontSize+'px'}">
    
    data:{
      activeColor:'red',
      fontSize:30
    }
    

    直接綁定到一個樣式對象通常更好,讓模板更清晰

    <div :style="styleObj"></div>
    
    data:{
      styleObj:{
        color:'red',
        fontSize:'13px'
      }
    }
    

    同樣可以集合返回對象的計算屬性使用

  • 數組語法

    :style的數組語法可以將多個樣式對象應用到一個元素上

    <div :style="[baseStyles,overr]"><div>
      
    data:{
      baseStyles:{
        color:"red"
      },
      overr:{
        fontSize:"40px"
      }
    }
    
  • 自動添加前綴

    當:style使用需要特定前綴的css屬性時,如transform,vue會自動偵測并添加相應的前綴

條件渲染

v-if,v-else,v-else-if

v-if的判斷條件可以是數據表達式,也可以是一個變量的值,或者是一條邏輯判斷語句

<div v-if="type==='A'">
A
</div>
<div v-else-if="0<1">
B
</div>
<div v-lese="bool">
C
</div>

也可以通過v-if來控制組件是否能夠顯示

<div id="box">
    <tem v-if="bool"></tem>
</div>
v-show

v--show用法與v-if的大致相同,除了v-show沒有v-else,不同的是帶有v-show屬性的元素始終會被渲染并保留在DOM中,v-show是通過切換元素的css樣式disoplay的值來控制元素是否顯示,而v-if則是通過創建和銷毀來控制元素是否可見,所以相比而言v-if的切換開銷更高一些,但是v-if是惰性的,如果初始的條件為false的話,那么它會保持什么也不做,直到條件發生變化,而v-show不論條件是什么都會進行渲染,一般來說,v-show會有更高的初始渲染開銷
一般來說,如果需要非常頻繁的進行切換,那么我們會使用v-show,如果運行條件不是經常改變,那么我們會使用v-if

列表渲染

v-for

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

也可以使用of代替in作為分割符

<li v-for="item of items"></li>

在v-for塊中,我們擁有對父級作用域完全的訪問權限,還支持可選的第二參數為當前項的索引值

<div id="box">
    <p v-for="(item,index) in items">{{item}}{{index}}</p>
</div>

new Vue({
  data:{
    items:["tom","xm"]
  }
}).$mount("#box")

我們也可以使用v-for通過一個對象來迭代

<div id="box">
    <p v-for="value in items">{{value}}</p>
</div>

new Vue({
  data:{
    items:{
      name:"tom",
      age:18
    }
  }
}).$mount("#box")

vue對于對象的迭代默認會展示對象的鍵值對的值,可以通過提供第二個參數來獲取對象的鍵名

<p v-for="(value,ket) in items">{{value}}{{key}}</p>

也可以傳入第三個參數來獲取索引值

<p v-for="(value,key,index) in items">{{value}}{{key}}{{index}}</p>

這里的遍歷順序遵照JS中Object.keys()的順序

:key

當vue.js在渲染是時發現已有元素再次被使用時會復用已有元素而不是重新渲染,這會加快vue渲染的速度,同時還有一個好處,例如下面這個例子

<body>
<div id="box">
    <user></user>
</div>
<template id="userInfo">
    <div>
        <div v-if="loginType ==='username'">
            <label>Username</label>
            <input type="text" placeholder="請輸入用戶名" >
        </div>
        <div v-else>
            <label>Email</label>
            <input type="text" placeholder="請輸入郵箱">
        </div>
        <button @click="change">switch</button>
    </div>
</template>

<script>
    new Vue({
        components:{
            "user":{
                template:"#userInfo",
                data(){
                    return{
                        loginType: "username"
                    }
                },
                methods: {
                    change() {
                        this.loginType = "Email"
                    }
                }
            }
        }
    }).$mount("#box")
</script>
</body>

在這個例子中,我們點擊button進行切換時,veu會復用重復的元素,template中相同的元素如llabel,input等元素只會渲染一次,在第二次出現時會被復用,如lable只會替換它的文字,input只會替換元素的placeholder,而不會再次重復渲染標簽,所以在點擊切換時我們會發現輸入框中我們輸入的內容會依然存在

這種復用會提高vue的運行效率,但是有時在實際開發中我們可能需要避免這種情況,此時需要我們用到:key,我們可以通過為每一個input設置不同的:key來通知vue需要將該元素重新渲染

<input type="text" placeholder="請輸入郵箱" :key="Email">

建議在使用v-for循環時如果要使用:key要給每一個不同的元素不同的key值,推薦使用如下方法

<p v-for="item in items" :key="item.id">{{item}}</p>
顯示過濾/排序結果

有時候我們想要顯示一個數組的過濾或排序副本,而不改變或重置原始數據,在這種情況下,可以創建返回過濾排序數組的計算屬性

<p v-for="item in items">{{item}}</p>

new Vue({
        data:{
          num:[1,2,3,4,5,6,7,8]
        },
        computed:{
            items:function () {
                return this.num.filter(function (item) {
                    return item % 2 === 0+it
                    
                })
            }
        }
 }).$mount("#box")        

在計算屬性不適用的情況下,可以使用methods來配合filter

<p v-for="item in even(nums)">{{item}}</p> 
 
 new Vue({
        data:{
          nums:[1,2,3,4,5,6,7,8]
        },
        methods:{
            even(n){
               return n.filter(function (n) {
                   return n%2===0
               })
            }
        }
}).$mount("#box")       
v-for和v-if

類似于v-if,我們也可以利用帶有v-for的<template>渲染多個元素

<ul>
    <template v-for="item in items">
    <li>{{item.title}}</li>
    </template>
</ul>   

當v-if和v-for處于同一節點,v-for的優先級比v-if更高,這也意味著v-if將會對每一次的v-for循環進行判斷

<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo }}
</li>

如果是有條件的跳過循環的執行,那么可以將v-if置于元素的外層上

組件的v-for

在自定義組件中,我們可以像普通元素一樣使用v-for

<my-component is="my-component" v-for="item in 10" :key="item.id" :item="item"></my-component>

但是注意在組件中不能使用item,也就是不能拿到父級的數據,需要我們通過props獲取父級的數據(item)

在vue2.2.0+的版本里,當組件在使用v-for時,key是必須的

表單輸入綁定

v-model會忽略所有表單元素的value,checked,selected特性的初始值,因為它會選擇Vue實例來作為具體的值,我們應該通過javascript在組件的data選項中聲明初始值,對于單選按鈕以及列表選項,v-model綁定的是input的value的值,對于勾選按鈕綁定的是邏輯值

文本
<input v-model='massage' placeholder='edit me'>
<p>{{massage}}</p>
多行文本
<p style="white-sapce:pre-line">{{massage}}</p>
<br/>
<textarea v-model="massage" placeholder="add multiple lines"></textarea>
復選框
  • 單個復選框

    <input v-model="massage" id="checkbox" type="checkbox">
    <label for="checkbox">
    
  • 多個復選框

    <form action="#">
            <input type="checkbox" id="jack"  v-model="checkedNames">
            <label for="jack">jack</label>
            <input type="checkbox" id="john" value="john" v-model="checkedNames">
            <label for="john">john</label>
            <input type="checkbox" id="moke" value="mike" v-model="checkedNames">
            <label for="moke">mike</label>
    </form>
    <span>checked names:{{checkedNames}}</span>
    
    new Vue({
            data:{
                checkedNames:[]
    <!--如果我們將checkedNames設置為數組,那么在復選框選中后會傳回復選框的value值,
        如果設置為字符串,那么在復選框被選中后會傳回當前復選框的選中狀態為true/false,并且所有復選框會被同時選中/不選中 -->
            }
    })
    
單選按鈕
<input type="radio" value="one" v-model="picked" id="one" >
<label for="one">one</label>
<input type="radio" value="two" v-model="picked" id="two" >
<label for="two">two</label>
<p>{{picked}}</p>

 new Vue({
    data:{
        picked:''
    }
}).$mount("#box")
選擇列表
  • 單選列表

    <select v-model="selected">
      <option value="" disabled>請選擇</option>
      <option>A</option>
      <option>B</option>
      <option>C</option>
    </select>
    <span>{{selected}}</span>
    
    new Vue({
      data:{
          selected:''
    }
    }).$mount("#box")
    
  • 動態選項

    <select v-model="selected">
      <option v-for="option in options" :value="option.value">
          {{option.text}}
      </option>
    </select>
    <span>{{selected}}</span>
    
     new Vue({
      data:{
          selected:'A',
          options:[
              {text:'one',value:'A'},
              {text:'two',value:'B'},
              {text:'three',value:'C'}
          ]
      }
    }).$mount("#box")
    
動態value

我們可以利用v-bind:將value綁定到Vue實例的一個動態屬性上,之后v-model將會綁定到動態value上,動態value可以是對象,字符串,數組等類型

  • 復選框

    <input type="checkbox" v-model="toggle" :true-value="a" :false-value="b">
    <p>{{toggle}}</p>
    
     new Vue({
      data:{
          a:{
              text:'您已經選中'
          },
          b:"您沒有選中",
          toggle:''
      }
    }).$mount("#box")
    
  • 單選按鈕

    <input type="radio" v-model="pick" :value="a">
    <p>{{pick}}</p>
    
    new Vue({
      data:{
          a:'你已經選中A',
          pick:''
      }
    }).$mount("#box")
    
  • 動態列表

    參考上一例動態列表例子

修飾符
  • lazy

    <input type="text" v-model.lazy="pick">
    <!--在默認情況下,v-model會在input事件中同步輸入框的值與數據,在使用lazy修飾符后,會變為在change事件中同步-->
    <!--change事件觸發條件:輸入框內容發生改變并且失去焦點-->
    <!--input事件觸發條件:輸入框內容發生變化-->
    
  • number

    <input type="number" v-model.number="pick">
    <!--將用戶的輸入值轉化為number類型,在通常的時候即使我們使用的是type="number"類型的輸入框,得到的值也是string-->
    
  • trim

    <!--自動去掉用戶輸入文本的首尾空格-->
    <input type="text" v-model.trim="pick">
    
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容