Vue官方文檔筆記


1、如何創建一個Vue實例對象?

var vm = new Vue({
          el: "#app",  //標簽id 或 標簽類名
          data:{ //雙向綁定的數據
              message: "王大錘",
              show: true,
              arr: [
                  { name: "王大錘", age: 18 }, { name:"羅小虎", age: 19 }
              ]
          }
      })

當一個Vue實例(如上面的vm)被創建后,它將data對象里面的所有的屬性加入到Vue的響應式系統中。當這些屬性的值發生改變時,視圖會產生“響應”, 即視圖展示最新的數據。

如何雙向式綁定數據?用v-model來綁定數據,如:

<input v-model="message" />

 

2、if  else  如何實現?用v-if、v-else、v-else-if,如:

<div v-if="show">show為true展示</div>
<div v-else>show為false展示</div>

3、for循環如何使用?

  • 不帶索引,格式:v-for = "item  in  arr",如:
    <div v-for="item in arr">{{item.name}}---{{item.age}}</div>
  • 帶索引,格式:v-for = "(item, index)  in  arr",如:
    <div v-for="(item, index) in arr">{{index}}--{{item.name}}</div>
  • for循環除了能對數組進行遍歷,還能對對象進行遍歷,遍歷對象的屬性,格式:v-for = "value  in  object"  /  v-for = "(value, name)  in  object"   /   v-for = "(value, name, index)  in  object"

 

4、Vue實例創建后,data對象里面的所有屬性都會加入到響應式系統中,當這些屬性的值發生改變時,視圖將會產生“響應”,如果不想被響應式系統追蹤變化,如何操作?

  使用Object.freeze()方法可以處理不想被追蹤的數據。

 

5、如何知道當前Vue實例對象作用在哪個標簽上?

  Vue實例.el 就是目標標簽,如vm.el == document.getElementById("#app")。在實例里面,this.$el指向的也是目標標簽。

 

6、如果Vue實例中的data里面的屬性值變化我們想及時知道,如何做?

  在watch方法里面增加對屬性的監聽,這樣當屬性的值進行變化時,watch里面回及時知道。比如想監聽data里面message屬性的值變化。

//第一種方式
vm.$watch('message', function(newValue, oldValue){
    //這個回調函數會在 ’vm.message‘ 改變后調用
})
//第二種方式,在Vue實例里面寫
      new Vue({
          el: "#app",
          data: {
              message: "hello",
              //...
          },
          watch: {
              message: function(newValue, oldValue){
                //這個回調函數會在‘message'改變后調用
              }
          }
      })

 

7、為什么不能在Vue實例的選項屬性或回調中使用箭頭函數?
  比如類似於 created: ()=>{ console.log(this.message) },  或vm.$watch('a', newValue => this.myMethod())。

  因為箭頭函數中並沒有this, 如果你使用了箭頭函數,然后箭頭函數中又使用了this。為了找到這個this,當在當前箭頭函數中找不到這個this時,系統會一直向上級詞法作用域去查找,直至找到為止,所以會經常導致出現Uncaught  TypeError: Cannot  read  property  of  undefined  或  Uncaught  TypeErrorr:  this.myMethod  is  not  a  function  之類的錯誤。

 

8、一個Vue實例,從創建到銷毀,經歷了哪些過程?也是說它的生命周期是怎樣的?

  主要有8個步驟

  8.1  beforeCreate:  創建Vue實例,初始化實例的事件、injections(注射:一般是檢查是否有父級信號注入,在這里可以接收對父級組件或父級屬性的引用,與父級提供的provide屬性相配合)、reactivity(反應性:初始化監聽屬性變化的方法,如watch)。

  8.2  created: 在實例進入created后,會判斷它是否包含“el"option(選項)。如果沒有的話,它會調用vm.$mount(el)這個方法,然后執行下一步;如果有的話,直接執行下一步。緊接着會判斷是否含有”template"這個選項,如果有的話,它會把template解析成一個render函數。

  8.3  beforeMount:  在beforeMount階段中,完成render(渲染),  vm.$el創建完成,並將渲染出來的內容掛載到DOM節點上。

  8.4  mounted:  在mounted階段,進行數據請求 --> data數據更新  -->  然后視圖重新渲染  -->  再數據變化  -->  再重新渲染等等循環往復操作。這個對數據進行變化的過程,其實還包含了beforeUpdate和updated兩個周期函數。

  8.5  beforeDestroy:  當Vue實例需要被銷毀時,執行beforeDestroy函數,再這里拆卸屬性偵聽器(watch)、子組件、事件監聽器(method)等等。

  8.6  destroyed:  最后一步,銷毀Vue實例,完成了它豐功偉績的一生!

這是官方給出的一張生命周期圖:

9、v-once是什么指令,有什么用?

  一次性插值,再html標簽中添加v-once屬性,表示標簽里綁定的文本插值只會展示第一次加載的數據。后面如果那個數據更改了,這個標簽里面的內容不會再進行更新。

 

10、如果相比文本插值轉成html標簽(把綁定的數據轉成html標簽),如何操作?

  使用v-html屬性,如:<div  v-html="customHtml"></div>

  注意動態渲染的任意HTML可能會非常危險,因為它很容易導致XSS攻擊。請只對可信內容使用HTML插值,絕不要對用戶提供的內容使用插值。

  

11、對於在html標簽中的插值使用雙括號{{message}}來綁定數據,如果想把數據綁定在HTML標簽中的屬性上,如類名(.)、樣式(style)、自定義屬性等如何操作?

  一般格式為 v-bind:屬性名 = "變量名",如:

<div v-bind:class="myClass" v-bind:style="myStyle" v-bind:key="myKey"></div>

  綁定事件的格式為  v-on:事件類型 = "事件名",如:

<input  v-on:click="showMsg"   v-on:focus="getFocus"   v-on:blur="getBlur" />

 

12、對於表單標簽的一些存在即為true的屬性,如何讓它們默認為false(比如復選框checkbox的checked屬性,所有表單標簽的disabled屬性) ?

  比如: 

<input type="checkbox" checked/> 
<input type="checkbox" checked="true" /> 
<input type="checkbox" checked="false"/>

  這三種寫法的效果是一樣的,即這些復選框一渲染出來就是默認選中狀態,類似的disabled屬性也是這個表現。

  那么如何讓它們默認為false呢?用v-bind, 比如:

<input type="checkbox" v-bind:checked="false"/> 
<input v-bind:disabled="false"/>

 

13、Vue模板語法除了綁定變量,還能綁定表達式,如:

<div>{{number + 1}} , {{ok ? '展示':'隱藏'}} ,{{message.split('').reverse().join('')}}</div>

 

14、v-bind和v-on的縮寫方式:

  v-bind:  可以縮寫成 :  

<div v-bind:href="url" v-bind:class="myClass"></div>

可以縮寫成

<div :href="url" :class="myClass"></div>

  v-on: 可以縮寫成

<input  v-on:focus="getFocus" v-on:click="clickMe"/>

可以縮寫成

<input @focus="getFocus" @click="clickMe"/>

 

15、模板內的表達式可以進行簡單運算,如果在模板內進行復雜邏輯有什么后果?有什么替代方案?

  在模板中放入太多的邏輯會讓模板過重且難以維護。因此,對於任何復雜邏輯,應該使用計算屬性。如:

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 計算屬性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 實例
      return this.message.split('').reverse().join('')
    }
  }
})

  我們可以像綁定普通屬性一樣在模板中綁定計算屬性,普通屬性和計算屬性已經建立了依賴關系。當普通屬性變化時,計算屬性也會跟着更新。

  當然我們能夠看出,使用計算屬性實現的效果,使用方法也能達到同樣的效果,比如:

<p>Reversed message: "{{ reversedMessage() }}"</p>
var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  methods: {
      reversedMessage: function () {
        return this.message.split('').reverse().join('')
      }
    }
})    

  那么問題來了,既然使用計算屬性和方法的效果是一樣的,那么用哪個更好性能更高?

  這個要具體問題具體分析,看用在哪些場景下。計算屬性是基於它們的響應式依賴進行緩存的,只有相關響應式依賴發生改變時他們才會重新求值。這就意味着只要message還沒發生改變,多次訪問reversedMessage計算屬性會立即返回之前的計算結果,而不必再次執行函數。相比之下,每當觸發重新渲染時,調用方法將總會再次執行函數。

  因此,根據實際情況是否需要緩存,來判斷是使用計算屬性,還是使用方法,讓性能更高。

  另外,計算屬性vs偵聽屬性的區別比較,在某種場景下:當有些數據需要隨着其他數據的變動而變動時,通常更好的做法是使用計算屬性,而不是命令式的watch回調。如:

  

<div id="demo">{{ fullName }}</div>
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

  上面的代碼式命令式重復的。且看使用計算屬性如何實現這個效果:

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

  可以看出,在這種場景下,使用計算屬性比偵聽屬性要好的多。

 

16、給標簽綁定類名和內聯樣式,有幾種寫法?

  主要有兩種:對象語法和數組語法,看下面的例子:

<div :class="{classOne: classObj.isOK, 'classTwo': classObj.isNO}">class的對象語法</div>
<div :class="{'classOne': classObj.isNo, 'classTwo': classObj.isOK}">class的對象語法</div>
<div class="classZero" :class="classObj2">class的對象語法</div>
<div :class="classObj3">class的數組語法</div>
<div :class="[classObj3[0], classObj3[1]]">class的數組語法</div>
<div :style="{fontSize: styleObj.fontSize, border: styleObj['border-bottom']}">style的對象語法</div>
<div :style="styleObj">style的對象語法</div>
<div :style="[styleObj, styleObj2]">style的數組語法</div>
data:{
    classObj: { isOK: true, isNO: false }, //class對象語法
    classObj2: { classOne: true, classTwo: true }, //class的對象語法2
    classObj3: ['classOne', 'classTwo'],   //class的數組語法
    styleObj: { fontSize: '50px', 'border-bottom': '8px dashed purple', color: 'red' }, //內聯樣式的對象語法
    styleObj2: { borderLeft: '3px solid red', 'border-right':'5px solid green' }, //內聯樣式的對象語法
},

最后這8個div渲染為:

<div class="classOne">class的對象語法</div>
<div class="classTwo">class的對象語法</div>
<div class="classZero classOne classTwo">class的對象語法</div>
<div class="classOne classTwo">class的數組語法</div>
<div class="classOne classTwo">class的數組語法</div>
<div style="font-size: 50px; border: 8px dashed purple; ">style的對象語法</div>
<div style="font-size: 50px; border-bottom: 8px dashed purple; color: red">style的對象語法</div>
<div style="font-size: 50px; border-bottom: 8px dashed purple; color: red; border-left: 3px solid red; border-right: 5px solid green;">style的數組語法</div>

 

17、數組有很多方法,哪些方法能夠被Vue偵聽,哪些方法不能被偵聽?

  數組的push、pop、shift、unshift、sort、rever、splice等方法的調用會改變原數組,因此能夠被Vue偵聽;

  而filter、concat、slice等方法調用不會被改變原數組,而總是返回一個新數組,因此這幾個方法的調用不會被Vue偵聽。所以對於filter、concat、slice如果也想被偵聽,可以用新數組替換舊數組。

  另外對於數組的通過索引修改某一項的值,或者修改數組的長度,也不會被Vue偵聽,比如:

var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // 不是響應性的, 不會被Vue偵聽
vm.items.length = 2 // 不是響應性的,不會被偵聽

  如果想被Vue偵聽,則可以使用vm.$set,或Vue.set(vm.$set實例方法是全局方法Vue.set的一個別名),如下:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
vm.$set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

//修改數組索引長度的方法
vm.items.splice(newLength)

  另外對於已經創建的實例,Vue不允許動態添加根級別的響應式屬性。但是可以使用Vue.set(object,  propertyName,  value)方法向嵌套對象添加響應式屬性。

 

18、調用事件時,如何傳遞原始DOM的事件對象event ?

  如果是非內聯方法,方法中默認第一個參數就是event;對於內聯事件方法,可以傳$event表示原始DOM的事件對象,如:

<input @focus="getFocus" @click="clickMe('你點我了', $event)"/>
method: {
    getFocus: function(event){
        console.log(event);
    },
    clickMe: function(msg, event){
        console.log(msg, ',', event);
    }
}

 

19、事件修飾符合按鍵修飾符

  1、在Vue中如何調用preventDefault()和stopPropagation()等事件方法?

  盡管我們可以在方法中輕松實現這些,但更好的方式是:方法只是純粹的數據邏輯,而不是去處理DOM事件細節。因此,Vue為v-on提供了事件修飾符。

<!-- 阻止單擊事件繼續傳播 -->
<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重載頁面 -->
<form v-on:submit.prevent="onSubmit"></form>

<!-- 修飾符可以串聯 -->
<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修飾符 -->
<form v-on:submit.prevent></form>

<!-- 添加事件監聽器時使用事件捕獲模式 -->
<!-- 即內部元素觸發的事件先在此處理,然后才交由內部元素進行處理 -->
<div v-on:click.capture="doThis">...</div>

<!-- 只當在 event.target 是當前元素自身時觸發處理函數 -->
<!-- 即事件不是從內部元素觸發的 -->
<div v-on:click.self="doThat">...</div>

  注意:使用修飾符時,順序很重要:相應的代碼會以同樣的順序產生。比如v-on:click.prevent.self會阻止所有的點擊,而v-on:click.self.prevent只會阻止對元素自身的點擊。

  2、按鍵修飾符

  如何對鍵盤某別特別按鍵進行監聽,如著名的event.keyCode= 13表示對鍵盤enter按鍵的監聽。

  Vue對常用的按鍵設置了別名,如:enter、tab、delete(捕獲“刪除”和“退格”鍵)、esc、space、up、down、left、right等,用法:  

<!-- 只有在 `key` 是 `Enter` 時調用 `vm.submit()` -->
<input v-on:keyup.enter="submit">

 你還可以通過全局config.keyCodes對象自定義按鍵修飾符別名:

// 可以使用 `v-on:keyup.f1`
Vue.config.keyCodes.f1 = 112

 

20、組件,如何創建一個組件?組件復用要注意哪些地方?父級如何傳遞數據給子組件?子組件如何傳遞數據給父級?

     1、組件的創建,先看一個示例

// 定義一個名為 button-counter 的新組件
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
組件是可復用的Vue實例,且帶有一個名字,上面這個列子中是<button-counter>。我們可以在一個通過new Value創建的Vue跟實例二中,把這個組件作為自定義元素來使用: 
<div id="app">
  <button-counter></button-counter>
</div>
new Vue({ el: '#app' })

  因為組件也是Vue實例,所以它們和new Vue接收相同的選項,例如data、computed、watch、methods以及其他生命周期鈎子等。僅有的例外是像el根實例獨自擁有的屬性。

  2、組件的復用注意點

    一個組件的data屬性必須是一個函數,這個和根實例的data是一個對象稍有不同。這樣做的原因是為了當組件在復用時,可以讓每個組件實例的數據互不影響。

  3、父級如何向子組件傳遞數據?

    父級通過v-bind:key傳遞子組件需要的數據,子組件在props屬性里面接收父級傳遞過來的數據。

  4、子組件修改數據后,如何傳回給父級(或者說通知父級修改數據)

    父級和子組件約定好在父級調用子組件時注冊一個事件v-on:方法名,子組件修改數據后,通過$emit('方法名', { //... })傳遞新數據給父級。

  3、4完整示例:

<div>
    <tan-one-com v-bind:super-obj="myInfo"
                 v-on:change-name="updateName" v-on:change-age="updateAge"></tan-one-com>
    <tan-one-com v-bind:super-obj="myInfo"
                 v-on:change-name="updateName" v-on:change-age="updateAge"></tan-one-com>
</div>
//注冊全局組件, 注冊之后,每個Vue實例都可以使用
Vue.component('tan-one-com',{
    //父級bind用駝峰,子組件用全小寫;
    //父級bind用全小寫,子組件用全小寫;
    //父級bind用中杠線連接,子組件可用駝峰式
    props: ['superObj'],  //接收來自父級傳遞過來的數據
    data: function(){  //自定義屬性,必須用函數。這是為了保證該組件在復用時,各組件實例數據互不影響
        return {
            count: 1
        };
    },
    methods: {
        inputName: function(event){
            console.log(event.target.value);
            //通知父級,傳遞最新值給父級
            this.$emit('change-name', { value: event.target.value });
        },
        inputAge: function(age){
            //傳遞最新值給父級
            this.$emit('change-age', { value: age });
        }
    },
    template: '<div>' +
                '<div><button v-on:click="count+=1">點我加一:{{count}}</button></div>' +
                '<div><input type="text" placeholder="請輸入名字" v-model="superObj.name" v-on:input="inputName"/></div>' +
                '<div><input type="text" placeholder="請輸入年齡" v-model="superObj.age" v-on:input="inputAge($event.target.value)"/></div>' +
              '</div>'
})

var vm = new Vue({
    el: "#app",
    data:{
        myInfo: { name: '', age: 18 },
    },
    methods: {
        updateName: function(event){
            this.myInfo.name = event.value;
        },
        updateAge: function(event){
            this.myInfo.age = event.value;
            console.log("event: ", event);
        }
    }
});

 

21、如何讓父級在子組件中插入一些自定義標簽?
  子組件開放一個接口,名為slot標簽,然后如果父級想在子組件中插入自定義標簽 ,最后將會插入到slot標簽中。 
<div>
    <tan-two-com>
        <h3>男兒何不帶吳鈎,收取關山五十州;</h3>
        <h1>請君暫上凌煙閣,若個書生萬戶侯。</h1>
    </tan-two-com>
</div>
//注冊全局組件,父級如何在子組件中插入自定義標簽
        Vue.component('tan-two-com', {
            template: '<div style="border: 5px dashed green;">' +
                        '<p>我是子組件,給父級開放一個入口,方便插入父級自定義標簽,用slot標簽來接收父級自定義標簽</p>'+
                        '<slot></slot>'+
                        '<div>..........end.......</div>'+
            '</div>'
        })

 

22、定義組件名的方式主要有兩種,官方建議使用短橫線分隔命名法(子組件通知父級的事件名也建議用kebab-case法命名)

  1、kebab-case:短橫線分隔命名法。用短橫線給組件命名時,在引用時也必須使用kebab-case, 例如
Vue.component('my-component-name', { /* ... */ })
<div><my-component-name></my-component-name></div>
  2、PascalCase: 首字母大寫命名法。使用首字母大寫給組件命名時,在引用時可以兩種命名法都可以使用,也就是說<my-component-name>和<MyComponentName>都是可以接受的。注意:直接在DOM(即非字符串的模板)中使用時只有kebab-case是有效的

 
官方推薦的一些命名規則:
  • 組件名命名用kebab-case命名
  • 父子級單向數據流:父級引用子組件時用kebab-case(短橫線分隔法),子組件prop用駝峰式命名接收
  • 子組件通知父級事件命名用kebab-case,即父級引用子組件時是v-on:xxx-xxx,子組件通知父級時是$emit('xxx-xxx', )
 

測試示例:https://github.com/xiaotanit/Tan_HtmlDemo/tree/master/VueDemo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM