VUE面試題
- v-show 與 v-if 區別
- 動態繫結class的方法
- 計算屬性和 watch 的區別
- 怎樣理解單向資料流
- keep-alive
- 自定義元件的語法糖 v-model 是怎樣實現的
- 生命週期
- 元件通訊
- 路由跳轉
- vue-router 有哪幾種導航鉤子
- Vue.js 2.x 雙向繫結原理
- 什麼是 MVVM,與 MVC 有什麼區別
- vuex
- this.$nextTick()
- vue的原理
- 理解Vue中的Render渲染函式
- slot插槽
v-show 與 v-if 區別
- v-hsow和v-if的區別: v-show是css切換,v-if是完整的銷燬和重新建立。
- 使用 頻繁切換時用v-show,執行時較少改變時用v-if
- v-if=‘false’ v-if是條件渲染,當false的時候不會渲染
繫結 class 的陣列用法
- 物件方法
v-bind:class="{'orange': isRipe, 'green': isNotRipe}"
- 陣列方法
v-bind:class="[class1, class2]"
- 行內
v-bind:style="{color: color, fontSize: fontSize+'px' }"
計算屬性和 watch 的區別
計算屬性是自動監聽依賴值的變化,從而動態返回內容,監聽是一個過程,在監聽的值變化時,可以觸發一個回撥,並做一些事情。 所以區別來源於用法,只是需要動態值,那就用計算屬性;需要知道值的改變後執行業務邏輯,才用 watch,用反或混用雖然可行,但都是不正確的用法。
說出一下區別會加分
computed 是一個物件時,它有哪些選項? computed 和 methods 有什麼區別? computed 是否能依賴其它元件的資料? watch 是一個物件時,它有哪些選項?
- 有get和set兩個選項
- methods是一個方法,它可以接受引數,而computed不能,computed是可以快取的,methods不會。
- computed可以依賴其他computed,甚至是其他元件的data
- watch 配置
handler deep 是否深度 immeditate 是否立即執行
總結
當有一些資料需要隨著另外一些資料變化時,建議使用computed。 當有一個通用的響應資料變化的時候,要執行一些業務邏輯或非同步操作的時候建議使用watcher
事件修飾符
- 繫結一個原生的click事件, 加native,
- 其他事件修飾符
stop prevent self - 組合鍵 click.ctrl.exact 只有ctrl被按下的時候才觸發
元件中 data 為什麼是函式
為什麼元件中的 data 必須是一個函式,然後 return 一個物件,而 new Vue 例項裡,data 可以直接是一個物件?
因為元件是用來複用的,JS 裡物件是引用關係,這樣作用域沒有隔離,而 new Vue 的例項,是不會被複用的,因此不存在引用物件的問題。
keep-alive
自定義元件的語法糖 v-model 是怎樣實現的
根據官方文件介紹,v-model本質上就是語法糖,即利用v-model繫結資料後,其實就是既繫結了資料,又新增了一個input事件監聽,如下:
怎樣理解單向資料流
這個概念出現在元件通訊。父元件是通過 prop 把資料傳遞到子元件的,但是這個 prop 只能由父元件修改,子元件不能修改,否則會報錯。子元件想修改時,只能通過 $emit 派發一個自定義事件,父元件接收到後,由父元件修改。 一般來說,對於子元件想要更改父元件狀態的場景,可以有兩種方案: 在子元件的 data 中拷貝一份 prop,data 是可以修改的,但 prop 不能:
export default {
props: {
value: String
},
data () {
return {
currentValue: this.value
}
}
}
複製程式碼
如果是對 prop 值的轉換,可以使用計算屬性:
export default {
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase();
}
}
}
複製程式碼
生命週期
-
建立前後 beforeCreate/created
在beforeCreate 階段,vue例項的掛載元素el和資料物件data都為undefined,還未初始化。在created階段,vue例項的資料物件有了,el還沒有。
-
載入前後 beforeMount/mounted
在beforeMount階段,vue例項的$el和data都初始化了,但還是掛載之前未虛擬的DOM節點,data尚未替換。 在mounted階段,vue例項掛載完成,data成功渲染。
-
更新前後 beforeUpdate/updated
當data變化時,會觸發beforeUpdate和updated方法。這兩個不常用,不推薦使用。
-
銷燬前後beforeDestory/destoryed
beforeDestory是在vue例項銷燬前觸發,一般在這裡要通過removeEventListener解除手動繫結的事件。例項銷燬後,觸發的destroyed。
元件間的通訊
- 父子
props
/event
$parent
/$children
ref
provide
/inject
- 兄弟 bus vuex
- 跨級 bus vuex provide inject
路由的跳轉方式
一般有兩種
<router-link to='home'> router-link
標籤會渲染為<a>
標籤,咋填template中的跳轉都是這種;- 另一種是程式設計是導航 也就是通過js跳轉 比如
router.push('/home')
Vue.js 2.x 雙向繫結原理
這個問題幾乎是面試必問的,回答也是有深有淺。基本上要知道核心的 API 是通過 Object.defineProperty()
來劫持各個屬性的setter / getter
,在資料變動時釋出訊息給訂閱者,觸發相應的監聽回撥,這也是為什麼 Vue.js 2.x 不支援 IE8 的原因(IE 8 不支援此 API,且無法通過 polyfill 實現)。
cn.vuejs.org/v2/guide/re…
什麼是 MVVM,與 MVC 有什麼區別
www.ruanyifeng.com/blog/2015/0…
nextTick()
在下次 DOM 更新迴圈結束之後執行延遲迴調。在修改資料之後,立即使用這個回撥函式,獲取更新後的 DOM。
// 修改資料
vm.msg = 'Hello'
// DOM 還未更新
Vue.nextTick(function () {
// DOM 更新
})
複製程式碼
vue的原理
Vue的模式是m-v-vm模式,即(model-view-modelView
),通過modelView作為中間層(即vm的例項),進行雙向資料的繫結與變化。
- 通過建立虛擬dom樹
document.createDocumentFragment()
,方法建立虛擬dom樹。 - 一旦被監測的資料改變,會通過
Object.defineProperty
定義的資料攔截,擷取到資料的變化。 - 擷取到的資料變化,從而通過訂閱——釋出者模式,觸發
Watcher
(觀察者),從而改變虛擬dom的中的具體資料。 - 最後,通過更新虛擬dom的元素值,從而改變最後渲染dom樹的值,完成雙向繫結 雙向繫結的實現
object.defineProperty 方法會直接在一個物件上定義一個新屬性,或者修改一個物件的現有屬性, 並返回這個物件。
語法:Object.defineProperty(obj, prop, descriptor)
var obj = {};
Object.defineProperty(obj,'hello',{
get:function(){
//我們在這裡攔截到了資料
console.log("get方法被呼叫");
},
set:function(newValue){
//改變資料的值,攔截下來額
console.log("set方法被呼叫");
}
});
obj.hello//輸出為“get方法被呼叫”,輸出了值。
obj.hello = 'new Hello';//輸出為set方法被呼叫,修改了新值
複製程式碼
我們可以做到資料的雙向繫結:
var obj = {};
Object.defineProperty(obj,'hello',{
get:function(){
//我們在這裡攔截到了資料
console.log("get方法被呼叫");
},
set:function(newValue){
//改變資料的值,攔截下來額
console.log("set方法被呼叫");
document.getElementById('test').value = newValue;
document.getElementById('test1').innerHTML = newValue;
}
});
//obj.hello;
//obj.hello = '123';
document.getElementById('test').addEventListener('input',function(e){
obj.hello = e.target.value;//觸發它的set方法
})
複製程式碼
理解Vue中的Render渲染函式
VUE一般使用template來建立HTML,然後在有的時候,我們需要使用javascript來建立html,這時候我們需要使用render函式。
render函式return一個createElement元件中的子元素儲存在元件實列中 $slots.default
中。
return createElement('h1', this.title)
; createElement
返回的是包含的資訊會告訴VUE頁面上需要渲染什麼樣的節點及其子節點。我們稱這樣的節點為虛擬DOM,可以簡寫為VNode。
createElement 引數
{String | Object | Function}
複製程式碼
一個HTML標籤字串,元件選項物件,或者一個返回值型別為String/Object的函式。該引數是 必須的
子節點
子節點,可選,String 或 Array
Vue.component('anchored-heading', {
render: function (createElement) {
return createElement(
'h' + this.level, // 標籤名稱
this.$slots.default // 由子節點構成的陣列
)
},
props: {
level: {
type: Number,
required: true
}
}
})
複製程式碼
slot插槽
vue.docschina.org/v2/guide/co…
單個插槽
當子元件模板只有一個沒有屬性的插槽時,父元件傳入的整個內容片段將插入到插槽所在的 DOM 位置,並替換掉插槽標籤本身。
最初在 標籤中的任何內容都被視為備用內容。備用內容在子元件的作用域內編譯,並且只有在宿主元素為空,且沒有要插入的內容時才顯示備用內容。
命名插槽
solt元素可以用一個特殊的特性name來進一步配置如何分發內容。多個插槽可以有不同的名字。 這樣可以將父元件模板中 slot 位置,和子元件 slot 元素產生關聯,便於插槽內容對應傳遞
作用域插槽scoped slots
可以訪問元件內部資料的可複用插槽(reusable slot)
在父級中,具有特殊特性 slot-scope
的<template>
元素必須存在,表示它是作用域插槽的模板。slot-scope 的值將被用作一個臨時變數名,此變數接收從子元件傳遞過來的 prop 物件。