1、如何創建一個Vue實例對象? 當一個Vue實例(如上面的vm)被創建後,它將data對象裡面的所有的屬性加入到Vue的響應式系統中。當這些屬性的值發生改變時,視圖會產生“響應”, 即視圖展示最新的數據。 如何雙向式綁定數據?用v-model來綁定數據,如: 2、if else 如何實現?用v-i ...
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>