1.vue的原理?

關(guān)鍵詞: 虛擬DOM樹+訪問(wèn)器屬性
- 解釋一下:響應(yīng)式原理?
當(dāng)你把一個(gè)普通的 JavaScript 對(duì)象傳入 Vue 實(shí)例作為
data選項(xiàng),Vue 將遍歷此對(duì)象所有的 property,并使用 Object.defineProperty把這些 property 全部轉(zhuǎn)為 getter/setter這些 getter/setter 對(duì)用戶來(lái)說(shuō)是不可見(jiàn)的,但是在內(nèi)部它們讓 Vue 能夠追蹤依賴,在 property 被訪問(wèn)和修改時(shí)通知變更,每個(gè)組件實(shí)例都對(duì)應(yīng)一個(gè) watcher 實(shí)例,它會(huì)在組件渲染的過(guò)程中把“接觸”過(guò)的數(shù)據(jù) property 記錄為依賴。之后當(dāng)依賴項(xiàng)的 setter 觸發(fā)時(shí),會(huì)通知 watcher,從而使它關(guān)聯(lián)的組件重新渲染。
- vue為什么不支持IE8及更低版本?
Object.defineProperty` 是 ES5 中一個(gè)無(wú)法 shim 的特性,這也就是 Vue 不支持 IE8 以及更低版本瀏覽器的原因。
2. vue有哪些缺點(diǎn)
- Vue 不能檢測(cè)數(shù)組和對(duì)象的變化
3.為什么vue不能檢測(cè)對(duì)象的變化
對(duì)于對(duì)象, Vue 無(wú)法檢測(cè) property 的添加或移除,由于 Vue 會(huì)在初始化實(shí)例時(shí)對(duì) property 執(zhí)行 getter/setter 轉(zhuǎn)化,所以 property 必須在 data 對(duì)象上存在才能讓 Vue 將它轉(zhuǎn)換為響應(yīng)式的.
- 追問(wèn):那如何解決上述問(wèn)題?
使用this.
$set(this.someObject,'b',2) 添加新的屬性
使用this.$delete(this.someObject,'b') 刪除舊屬性
4.講一下 $set 的實(shí)現(xiàn)原理
1、如果目標(biāo)是數(shù)組,使用 vue 實(shí)現(xiàn)的變異方法 splice 實(shí)現(xiàn)響應(yīng)式
2、如果目標(biāo)是對(duì)象,判斷屬性存在,即為響應(yīng)式,直接賦值
3、如果 target 本身就不是響應(yīng)式,直接賦值
4、如果屬性不是響應(yīng)式,則調(diào)用 defineReactive 方法進(jìn)行響應(yīng)式處理
核心代碼如下
export function set(target: Array | Object, key: any, val: any): any {
// target 為數(shù)組
if (Array.isArray(target) && isValidArrayIndex(key)) {
// 修改數(shù)組的長(zhǎng)度, 避免索引>數(shù)組長(zhǎng)度導(dǎo)致splice()執(zhí)行有誤
target.length = Math.max(target.length, key);
// 利用數(shù)組的splice變異方法觸發(fā)響應(yīng)式
target.splice(key, 1, val);
return val;
}
// target為對(duì)象, key在target或者target.prototype上 且必須不能在 Object.prototype 上,直接賦值
if (key in target && !(key in Object.prototype)) {
target[key] = val;
return val;
}
// 以上都不成立, 即開(kāi)始給target創(chuàng)建一個(gè)全新的屬性
// 獲取Observer實(shí)例
const ob = (target: any).__ob__;
// target 本身就不是響應(yīng)式數(shù)據(jù), 直接賦值
if (!ob) {
target[key] = val;
return val;
}
// 進(jìn)行響應(yīng)式處理
defineReactive(ob.value, key, val);
ob.dep.notify();
return val;
}
5.new Vue()實(shí)例中,data 可以直接是一個(gè)對(duì)象,為什么在 vue 組件中,data 必須是一個(gè)函數(shù)呢?
關(guān)鍵詞:復(fù)用+污染 + 函數(shù)返回 + 數(shù)據(jù)拷貝
因?yàn)榻M件是可以復(fù)用的,JS 里對(duì)象是引用關(guān)系,如果組件 data 是一個(gè)對(duì)象,那么子組件中的 data 屬性值會(huì)互相污染,產(chǎn)生副作用。所以一個(gè)組件的 data 選項(xiàng)必須是一個(gè)函數(shù),因此每個(gè)實(shí)例可以維護(hù)一份被返回對(duì)象的獨(dú)立的拷貝。new Vue 的實(shí)例是不會(huì)被復(fù)用的,因此不存在以上問(wèn)題。
6.computed 和 watch 有什么區(qū)別?

computed 計(jì)算屬性 :
依賴其它屬性值,只有它依賴的屬性值發(fā)生改變,下一次獲取 computed 的值時(shí)才會(huì)重新計(jì)算 computed 的值,如果和上次計(jì)算結(jié)果不一致,重新渲染頁(yè)面。
watch 偵聽(tīng)器 : 更多的是「觀察」的作用,無(wú)緩存性,類似于某些數(shù)據(jù)的監(jiān)聽(tīng)回調(diào),每當(dāng)監(jiān)聽(tīng)的數(shù)據(jù)變化時(shí)都會(huì)執(zhí)行回調(diào)進(jìn)行后續(xù)操作。
追問(wèn):computed 和 watch 應(yīng)用場(chǎng)景?
關(guān)鍵詞 computed+緩存
computed :當(dāng)我們需要進(jìn)行數(shù)值計(jì)算,并且依賴于其它數(shù)據(jù)時(shí),應(yīng)該使用 computed,因?yàn)榭梢岳?computed 的緩存特性,避免每次獲取值時(shí),都要重新計(jì)算。
watch: 當(dāng)我們需要在數(shù)據(jù)變化時(shí)執(zhí)行的操作時(shí)使用(如調(diào)用其它函數(shù))
追問(wèn) :能使用箭頭函數(shù)定義computed和watch嗎?
不應(yīng)該使用箭頭函數(shù)來(lái)定義 watcher 函數(shù),理由是箭頭函數(shù)綁定了父級(jí)作用域的上下文,所以 this 將不會(huì)按照期望指向 Vue 實(shí)例,為undefined
7.MVC和MVVM的原理
-
MVC
image.png
視圖(View):用戶界面。
控制器(Controller):業(yè)務(wù)邏輯
模型(Model):數(shù)據(jù)保存
實(shí)現(xiàn)流程
1.View 傳送指令到 Controller
2.Controller 完成業(yè)務(wù)邏輯后,要求 Model 改變狀態(tài)
3.Model 將新的數(shù)據(jù)發(fā)送到 View,用戶得到反饋
- MVVM
視圖(View):用戶界面。
視圖模型(VM):雙向數(shù)據(jù)綁定
模型(Model):數(shù)據(jù)+業(yè)務(wù)
在MVVM架構(gòu)下,View 和 Model 之間并沒(méi)有直接的聯(lián)系,而是通過(guò)ViewModel進(jìn)行交互. Model 和 ViewModel 之間的交互是雙向的, 因此View 數(shù)據(jù)的變化會(huì)同步到Model中,而Model 數(shù)據(jù)的變化也會(huì)立即反應(yīng)到View 上。

8.vue數(shù)據(jù)綁定是雙向還是單向的
Vue 在不同組件間強(qiáng)制使用單向數(shù)據(jù)流。這使應(yīng)用中的數(shù)據(jù)流更加清晰易懂。
9.v-model雙向綁定的原理?
v-model 本質(zhì)上不過(guò)是語(yǔ)法糖。它負(fù)責(zé)監(jiān)聽(tīng)用戶的輸入事件以更新數(shù)據(jù).
原理如下:
Object.defineproperty()重新定義(set方法)對(duì)象設(shè)置屬性值和(get方法)獲取屬性值的操縱來(lái)實(shí)現(xiàn)的.
1.實(shí)現(xiàn)一個(gè)監(jiān)聽(tīng)器Observer,用來(lái)劫持并監(jiān)聽(tīng)所有屬性,如果有變動(dòng)的,就通知訂閱者。
2.實(shí)現(xiàn)一個(gè)訂閱者Watcher,可以收到屬性的變化通知并執(zhí)行相應(yīng)的函數(shù),從而更新視圖。
3.實(shí)現(xiàn)一個(gè)解析器Compile,可以掃描和解析每個(gè)節(jié)點(diǎn)的相關(guān)指令,并根據(jù)初始化模板數(shù)據(jù)以及初始化相應(yīng)的訂閱器。
9.全局導(dǎo)航鉤子函數(shù)應(yīng)用場(chǎng)景?
vue router.beforeEach(全局前置守衛(wèi))router.beforeEach 是頁(yè)面加載之前(before each)意思是在 每次每一個(gè)路由改變的時(shí)候都得執(zhí)行一遍.
vue router.afterEach(全局后置守衛(wèi)),相反router.afterEach是頁(yè)面加載之后.
應(yīng)用場(chǎng)景:
- 可進(jìn)行一些頁(yè)面跳轉(zhuǎn)前處理,例如判斷需要登錄的頁(yè)面進(jìn)行攔截,做登錄跳轉(zhuǎn)!
2.進(jìn)入頁(yè)面登錄判斷、管理員權(quán)限判斷、瀏覽器判斷
10 .v-if和v-for在同一個(gè)標(biāo)簽中的執(zhí)行順序?
v-for 比 v-if 優(yōu)先級(jí)高,如果每一次都需要遍歷整個(gè)數(shù)組,將會(huì)影響速度注意v-for 遍歷避免同時(shí)使用 v-if
如果需要使用判斷,建議使用計(jì)算屬性
<ul> <li v-for="user in activeUsers" :key="user.id"> {{ user.name }} </li></ul>
computed: { activeUsers: function () { return this.users.filter(function (user) { return user.isActive }) }}
10.路由獨(dú)享的守衛(wèi)(路由內(nèi)鉤子)
路由獨(dú)享的守衛(wèi)(路由內(nèi)鉤子)你可以在路由配置上直接定義 beforeEnter 守衛(wèi):
const router = new VueRouter({ routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// 處理
...
next()
}
} ]
11.vue-loader是什么?它有什么作用?
解析和轉(zhuǎn)換 .vue 文件,提取出其中的邏輯代碼 script、樣式代 碼 style、以及 HTML 模版 template,再分別把它們交給對(duì)應(yīng)的 Loader 去處理。
12.vue中怎么重置data?
this .$options.data可以獲取到組件初始化狀態(tài)下的datathis.$data獲取當(dāng)前狀態(tài)下的data// 將數(shù)據(jù)拷貝到this.$data中即可Object.assign(this.$data, this.$options.data())
13.在vue項(xiàng)目中如果methods的方法用箭頭函數(shù)定義結(jié)果會(huì)怎么樣?
因?yàn)榧^函數(shù)默綁定父級(jí)作用域的上下文,所以不會(huì)綁定vue實(shí)例, 在嚴(yán)格模式下this是undefined,在非嚴(yán)格模式下指向window
14.vue怎么實(shí)現(xiàn)強(qiáng)制刷新組件?
1.調(diào)用強(qiáng)制刷新方法 this.$forceUpdate()
- 給模板上綁定key值,通過(guò)修改key值,實(shí)現(xiàn)組件刷新<SomeComponent :key="theKey"/>//選項(xiàng)里綁定datadata(){ return{ theKey:0 }}//刷新key達(dá)到刷新組件的目的theKey++;
15.如何在子組件中訪問(wèn)父組件的實(shí)例?
通過(guò)this.
parent.event來(lái)調(diào)用父組件的方法
2:在子組件里用$emit向父組件觸發(fā)一個(gè)事件,父組件監(jiān)聽(tīng)這個(gè)事件
3:父組件把方法傳入子組件中,在子組件里直接調(diào)用這個(gè)方法父組件如何調(diào)用子組件的方法?給子組件設(shè)置屬性ref
<子組件 ref="name" />可以在子組件中加上ref,然后通過(guò)this.$refs.ref.method調(diào)用
16.vue組件里寫的原生addEventListeners監(jiān)聽(tīng)事件,要手動(dòng)去銷毀嗎?為什么?
需要, Vue不會(huì)主動(dòng)移除監(jiān)聽(tīng)事件, 多次進(jìn)入組件,事件會(huì)綁定多次,另一方面是函數(shù)沒(méi)釋放會(huì)內(nèi)存溢出.
17.組件中寫name選項(xiàng)有什么作用?
a.項(xiàng)目使用keep-alive時(shí),可搭配組件name進(jìn)行緩存過(guò)濾b.DOM做遞歸組件時(shí)需要調(diào)用自身name
c.vue-devtools調(diào)試工具里顯示的組見(jiàn)名稱是由vue中組件name決定的
18.<template></template>有什么用?
當(dāng)做一個(gè)不可見(jiàn)的包裹元素,減少不必要的DOM元素,整個(gè)結(jié)構(gòu)會(huì)更加清晰。使用場(chǎng)景主要用于分組的條件判斷和列表渲染。結(jié)合v-for、v-if等一起使用,插槽時(shí)使用
19 .vue組件之間的通信都有哪些?
父子組件傳值
- 通過(guò)props屬性傳值
- 通過(guò)
on傳值
- (
children ) / $refs
兄弟組件傳值
1.Vuex
2.Bus
跨級(jí)組件傳值
- provide/inject
-
listeners
20.route和router有什么區(qū)別?
route:代表當(dāng)前路由信息對(duì)象,可以獲取到當(dāng)前路由的信息參數(shù)router:代表路由實(shí)例的對(duì)象,包含了路由的跳轉(zhuǎn)方法,鉤子函數(shù)等
21.怎樣動(dòng)態(tài)加載路由?
通過(guò)router.addRoutes方法可以動(dòng)態(tài)加載路由.
let router=new VueRouter({
routes:[
{path:'/product',component:a,name:'product'}
]
});
router.addRoutes([
{path:'/user',component:c,name:'user'},
{path:'/address',component:address,name:'address'}
]);
22.說(shuō)說(shuō)active-class是哪個(gè)組件的屬性?
active-class是vue-router模塊的router-link組件中的屬性,用來(lái)設(shè)置選中連接的樣式.
23.為什么vue使用異步更新組件?
收集當(dāng)前的改動(dòng)一次性批量更新,為了節(jié)省diff開(kāi)銷.
24.怎么緩存當(dāng)前的組件?緩存后怎么更新?
1.通過(guò)keep-alive組件緩存需要緩存的組件
<keep-alive includes="組件1name,組件2name">
<router-view>
</keep-alive>
2.當(dāng)組件激活后,會(huì)觸發(fā)鉤子函數(shù)actived,在這個(gè)鉤子函數(shù)中,做數(shù)據(jù)更新.
25.vue怎么獲取DOM節(jié)點(diǎn)?
為組件定義ref屬性<input ref="myInput">通過(guò)this.$refs.myInput 就可以獲取dom節(jié)點(diǎn).
26.vuex中actions和mutations有什么區(qū)別?
1.mutations可以直接修改state,但只能包含同步操作,同時(shí),只能通過(guò)提交commit調(diào)用.
2.actions可以包含異步操作,通過(guò)store.dispatch觸發(fā),不能直接修改數(shù)據(jù),需要調(diào)用commit去修改數(shù)據(jù).
27. 怎么監(jiān)聽(tīng)vuex數(shù)據(jù)的變化?
通過(guò)watch監(jiān)聽(tīng)數(shù)據(jù)的變化
watch:{
'$store.state.test':function(value){
console.log('數(shù)據(jù)修改了',value)
}}
28.開(kāi)啟vuex中的嚴(yán)格模式有什么好處?
主要用戶防止不合理的改變狀態(tài)值如:this.$.store.state.list = [],這樣就會(huì)拋出異常
A.在嚴(yán)格模式下,無(wú)論何時(shí)發(fā)生了狀態(tài)變更且不是由 mutation 函數(shù)引起的,將會(huì)拋出錯(cuò)誤。這能保證所有的狀態(tài)變更都能被調(diào)試工具跟蹤到。
B. 不要在發(fā)布環(huán)境下啟用嚴(yán)格模式!嚴(yán)格模式會(huì)深度監(jiān)測(cè)狀態(tài)樹來(lái)檢測(cè)不合規(guī)的狀態(tài)變更——請(qǐng)確保在發(fā)布環(huán)境下關(guān)閉嚴(yán)格模式,以避免性能損失。
如何使用?
const store = new Vuex.Store({
// 讓構(gòu)建工具自動(dòng)幫我們處理
strict: process.env.NODE_ENV !== 'production'
})
30.你了解雙向綁定的計(jì)算屬性的應(yīng)用場(chǎng)景嗎?
<input type="text" v-model="username">
如果我們想要監(jiān)聽(tīng)用戶輸入變化,我們首先會(huì)想到下面的方法
<input type="text" v-model="username" @input="onChange">
其實(shí)我們可以使用雙向綁定的計(jì)算屬性來(lái)實(shí)現(xiàn)
data() {
return { _username:'' };
}, computed:{
username:{
get(){
return this._username
},
set(value){ // 監(jiān)聽(tīng)數(shù)據(jù)變化
console.log('監(jiān)聽(tīng)數(shù)據(jù)變化',value)
this._username = value }
}
}
當(dāng)我們使用了Vuex時(shí),并且開(kāi)啟了嚴(yán)格模式,那么我們就不能直接綁定狀態(tài)值了, 在用戶輸入時(shí),v-model 會(huì)試圖直接修改狀態(tài)name的值,這樣會(huì)拋出異常<input v-model="$store.state.name">這個(gè)時(shí)候我們需要使用雙向綁定的計(jì)算屬性來(lái)解決這個(gè)問(wèn)題
<input v-model="name">
computed: {
name: {
get () {
return this.$store.state.name
},
set (value) {
this.$store.commit('updateName', value)
}
}}
30.vue中的指令v-on如何綁定多個(gè)屬性?
v-on={ 事件名:綁定的自定義回調(diào)函數(shù)}
<input type="text" v-on="{input:onInput,focus:onFocus}"/>
31.vue中使用delete刪除對(duì)象的屬性,頁(yè)面會(huì)更新嗎?
delete this.list[1]頁(yè)面不會(huì)更新, Vue不能檢測(cè)到 property 被刪除那么如何在刪除元素或者對(duì)象屬性時(shí),可以觸發(fā)更新視圖?this.$delete(this.list,1)
32.watch怎么深度監(jiān)聽(tīng)對(duì)象變化?
data() {
return {
data:{},
user:{
info:{ name:123 }
}
};
}
比如我們要對(duì)user.info 屬性進(jìn)行監(jiān)聽(tīng),如果info屬性有任何更改觸發(fā)通知
watch:{ 'user.info':{
handler(value){
console.log("數(shù)據(jù)變化",value)
}
}
}
此時(shí)我們調(diào)用
this.user.info.name = "8888888"handle方法不會(huì)被觸發(fā).這個(gè)user.info是一個(gè)對(duì)象
Vue只響應(yīng)對(duì)象的地址變化進(jìn)行響應(yīng).
如果我們需要讓Vue對(duì)整個(gè)info里面的屬性變化,進(jìn)行監(jiān)聽(tīng),
就需要開(kāi)啟深度監(jiān)聽(tīng)屬性deep:true
watch:{
'user.info':{
handler(value){
console.log("數(shù)據(jù)變化",value)
},
deep:true
}
}
33 .vue組件會(huì)在什么時(shí)候下被銷毀?
1.頁(yè)面關(guān)閉、
2.路由跳轉(zhuǎn)、
3.v-if為false
4.改變key值
33.怎么使css樣式只在當(dāng)前組件中生效
給style標(biāo)簽添加scoped屬性, 通過(guò)該屬性,可以使得組件之間的樣式不互相污染<style scoped> </style>
原理vue中的scoped屬性的效果主要通過(guò)PostCSS轉(zhuǎn)譯實(shí)現(xiàn), PostCSS給一個(gè)組件中的所有dom添加了一個(gè)獨(dú)一無(wú)二的動(dòng)態(tài)屬性,然后,給CSS選擇器額外添加一個(gè)對(duì)應(yīng)的屬性選擇器來(lái)選擇該組件中dom.
<div adfs-888-123213 ></div>
vue
vuex
vue-reouter
axios
https://developer.mozilla.org/zh-CN/docs/Web/HTTP
微信小程序
支付寶小程序
can I use
實(shí)戰(zhàn)經(jīng)驗(yàn)
安全
ES6教程
javascript
