什麼是 mvvm?
MVVM 是 Model-View-ViewModel 的縮寫。mvvm 是一種設計思想。Model 層代表數據模型,也可以在 Model 中定義數據修改和操作的業務邏輯;View 代表 UI 組件,它負責將數據模型轉化成 UI 展現出來,ViewModel 是一個同步 View 和 Model 的對象。
簡述Vue的響應式原理
當一個Vue實例創建時,vue會遍歷data選項的屬性,用 Object.defineProperty 將它們轉爲 getter/setter並且在內部追蹤相關依賴,在屬性被訪問和修改時通知變化。
每個組件實例都有相應的 watcher 程序實例,它會在組件渲染的過程中把屬性記錄爲依賴,之後當依賴項的 setter 被調用時,會通知 watcher 重新計算,從而致使它關聯的組件得以更新。
vue生命週期的理解
總共分爲 8 個階段創建前/後,載入前/後,更新前/後,銷燬前/後。
創建前/後: 在 beforeCreate 階段,vue 實例的掛載元素 el 還沒有。
載入前/後:在 beforeMount 階段,vue 實例的$el 和 data 都初始化了,但還是掛載之前爲虛擬的 dom 節點,data.message 還未替換。在 mounted 階段,vue 實例掛載完成,data.message 成功渲染。
更新前/後:當 data 變化時,會觸發 beforeUpdate 和 updated 方法。
銷燬前/後:在執行 destroy 方法後,對 data 的改變不會再觸發周期函數,說明此時 vue 實例已經解除了事件監聽以及和 dom 的綁定,但是 dom 結構依然存在。
爲什麼vue中data必須是一個函數?
當重用組件時,由於數據對象都指向同一個data對象,當在一個組件中修改data時,其他重用的組件中的data會同時被修改;而使用返回對象的函數,由於每次返回的都是一個新對象(Object的實例),引用地址不同,則不會出現這個問題。
vue-router有哪幾種導航鉤子?
三種。
一種是全局導航鉤子:router.beforeEach(to,from,next),作用:跳轉前進行判斷攔截。
第二種:組件內的鉤子;
第三種:單獨路由獨享組件
<!-- 組件內的鉤子 -->
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染該組件的對應路由被 confirm 前調用
// 不!能!獲取組件實例 `this`
// 因爲當守衛執行前,組件實例還沒被創建
},
beforeRouteUpdate (to, from, next) {
// 在當前路由改變,但是該組件被複用時調用
// 舉例來說,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
// 由於會渲染同樣的 Foo 組件,因此組件實例會被複用。而這個鉤子就會在這個情況下被調用。
// 可以訪問組件實例 `this`
},
beforeRouteLeave (to, from, next) {
// 導航離開該組件的對應路由時調用
// 可以訪問組件實例 `this`
}
}
<!--路由獨享的守衛-->
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
計算屬性和watch的區別 ?
計算屬性是用來一些數據需要隨着其它數據變動而變動時用的.
基於它們的響應式依賴進行緩存的。只在相關響應式依賴發生改變時它們纔會重新求值。依賴還沒有發生改變 , 計算屬性會立即返回之前的計算結果,而不會再次執行函數.
watch是用來監聽數據變動的. 當需要在數據變化時執行異步或開銷較大的操作時,這個方式是最有用的。
vue 組件通信 ?
父傳遞子
父:自定義屬性名 + 數據(要傳遞)=> :value=“數據”
子:props ["父組件上的自定義屬性名“] =>進行數據接收)
子傳遞父
在父組件中註冊子組件並在子組件標籤上綁定自定義事件的監聽。
子:this.$emit(‘自定義事件名稱’, 數據) 子組件標籤上綁定@自定義事件名稱=‘回調函數’
父:methods: {自定義事件() {//邏輯處理} }
的作用是什麼?
保持這些組件的狀態,以避免反覆重渲染導致的性能問題, 緩存動態組件的行爲
$nextTick ?
將回調延遲到下次 DOM 更新循環之後執行,在修改數據之後立即執行.
常用的事件修飾符
.stop .prevent .once .self: 只當事件是從事件綁定的元素本身觸發時才觸發回調
Vue子組件調用父組件的方法
- this.$parent
- $emit
axios的特點有哪些?
- axios是一個基於promise的HTTP庫,支持promise的所有API;
- 它可以攔截請求和響應;
- 它可以轉換請求數據和響應數據,並對響應回來的內容自動轉換爲json類型的數據;
- 它安全性更高,客戶端支持防禦XSRF;
vue中的 ref 是什麼?
ref 被用來給元素或子組件註冊引用信息。引用信息將會註冊在父組件的 $refs 對象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子組件上,引用就指向組件實例。
vue.js的兩個核心是什麼?
數據驅動、組件系統
vue如何兼容ie的問題。
babel-polyfill插件
頁面刷新vuex被清空解決辦法?
vuex-persistedstate
import Vue from 'vue'
import Vuex from 'vuex'
import * as Cookies from 'js-cookie'
import createPersistedState from 'vuex-persistedstate'
import createLogger from 'vuex/dist/logger'
import actions from './actions'
import * as getters from './getters'
import state from './state'
import mutations from './mutations'
import player from './modules/player/index'
Vue.use(Vuex)
// webpack 中 生產模式或開發
const debug = process.env.NODE_ENV !== 'production'
const store = new Vuex.Store({
state,
getters,
mutations,
actions,
modules: {
player
},
// 嚴格模式
strict: debug,
plugins: [
// vuex-persistedstate,使vuex狀態持久化(緩存到本地)
createPersistedState({
storage: {
// cookie / localStorage
getItem: key => Cookies.get(key),
setItem: (key, value) => Cookies.set(key, value, {
expires: 3,
secure: true
}),
removeItem: key => Cookies.remove(key)
}
}),
debug ? createLogger() : false
]
})
export default store
如何優化SPA應用的首屏加載速度慢的問題?
- 公用js庫外部CDN引入
- 路由懶加載
- 骨架屏或Loading圖. 優化用戶體驗
DOM 渲染在哪個週期中就已經完成?
mounted, 注意 mounted 不會承諾所有的子組件也都一起被掛載。如果你希望等到整個視圖都渲染完畢,可以用 vm.$nextTick 替換掉 mounted
mounted: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
})
}
vue中的diff算法是怎樣實現的 ?
diff算法是一種優化手段,將前後兩個模塊(vNode: virtual DOM)進行差異化對比,修補(更新真實的DOM)差異的過程叫做patch(打補丁)
diff的過程就是調用名爲patch的函數,比較新舊節點,一邊比較一邊給真實的DOM打補丁。
virtual DOM是將真實的 DOM 的數據抽取出來,以對象的形式模擬樹形結構,diff算法比較的也是virtual DOM
<div>
<p>Hello World</p>
</div>
// 轉換成虛擬節點 類似於下面這種
const Vnode = {
tag:'div',
children:[
{tag:'p',text:'Hello World'}
]
}
談談你對vue的雙向數據綁定原理的理解
vue.js 是採用數據劫持結合發佈者-訂閱者模式的方式,通過Object.defineProperty()來劫持各個屬性的setter,getter,在數據變動時發佈消息給訂閱者,觸發相應的監聽回調。
第一步:需要observe的數據對象進行遞歸遍歷,包括子屬性對象的屬性,都加上 setter和getter。這樣的話,給這個對象的某個值賦值,就會觸發setter,那麼就能監聽到了數據變化
第二步:compile解析模板指令,將模板中的變量替換成數據,然後初始化渲染頁面視圖,並將每個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變動,收到通知,更新視圖
第三步:Watcher訂閱者是Observer和Compile之間通信的橋樑,主要做的事情是:
1、在自身實例化時往屬性訂閱器(dep)裏面添加自己
2、自身必須有一個update()方法
3、待屬性變動dep.notice()通知時,能調用自身的update()方法,並觸發Compile中綁定的回調,則功成身退。
第四步:MVVM作爲數據綁定的入口,整合Observer、Compile和Watcher三者,通過Observer來監聽自己的model數據變化,通過Compile來解析編譯模板指令,最終利用Watcher搭起Observer和Compile之間的通信橋樑,達到數據變化 -> 視圖更新;視圖交互變化(input) -> 數據model變更的雙向綁定效果。
MVVM如何實現模板綁定,依賴是如何收集的?
transition: 過渡的實現原理
vue組件間的交互有七種你知道幾種?
請詳細說出vue生命週期的執行過程
vue-router: 官方路由的實現原理
vue-cli3.0如何實現的?
說說hash路由和history路由,你能自己編寫一個前端路由嗎?
你能手寫vuex狀態管理嗎?
待續…