1.vue的原理?
關(guān)鍵詞: 虛擬DOM樹
+訪問器屬性
- 解釋一下:響應(yīng)式原理?
當(dāng)你把一個普通的 JavaScript 對象傳入 Vue 實例作為
data
選項阔涉,Vue 將遍歷此對象所有的 property金赦,并使用 Object.defineProperty把這些 property 全部轉(zhuǎn)為 getter/setter這些 getter/setter 對用戶來說是不可見的烙如,但是在內(nèi)部它們讓 Vue 能夠追蹤依賴,在 property 被訪問和修改時通知變更,每個組件實例都對應(yīng)一個 watcher 實例,它會在組件渲染的過程中把“接觸”過的數(shù)據(jù) property 記錄為依賴。之后當(dāng)依賴項的 setter 觸發(fā)時唧瘾,會通知 watcher,從而使它關(guān)聯(lián)的組件重新渲染别凤。
- vue為什么不支持IE8及更低版本?
Object.defineProperty` 是 ES5 中一個無法 shim 的特性饰序,這也就是 Vue 不支持 IE8 以及更低版本瀏覽器的原因。
2. vue有哪些缺點
- Vue 不能檢測數(shù)組和對象的變化
3.為什么vue不能檢測對象的變化
對于對象, Vue 無法檢測 property 的添加或移除,由于 Vue 會在初始化實例時對 property 執(zhí)行 getter/setter 轉(zhuǎn)化规哪,所以 property 必須在 data 對象上存在才能讓 Vue 將它轉(zhuǎn)換為響應(yīng)式的.
- 追問:那如何解決上述問題?
使用this.
$set
(this.someObject,'b',2) 添加新的屬性
使用this.$delete
(this.someObject,'b') 刪除舊屬性
4.講一下 $set 的實現(xiàn)原理
1求豫、如果目標(biāo)是數(shù)組,使用 vue 實現(xiàn)的變異方法 splice 實現(xiàn)響應(yīng)式
2、如果目標(biāo)是對象,判斷屬性存在,即為響應(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ù)組的長度, 避免索引>數(shù)組長度導(dǎo)致splice()執(zhí)行有誤
target.length = Math.max(target.length, key);
// 利用數(shù)組的splice變異方法觸發(fā)響應(yīng)式
target.splice(key, 1, val);
return val;
}
// target為對象, key在target或者target.prototype上 且必須不能在 Object.prototype 上,直接賦值
if (key in target && !(key in Object.prototype)) {
target[key] = val;
return val;
}
// 以上都不成立, 即開始給target創(chuàng)建一個全新的屬性
// 獲取Observer實例
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()實例中,data 可以直接是一個對象,為什么在 vue 組件中,data 必須是一個函數(shù)呢?
關(guān)鍵詞:復(fù)用
+污染
+ 函數(shù)返回
+ 數(shù)據(jù)拷貝
因為組件是可以復(fù)用的,JS 里對象是引用關(guān)系,如果組件 data 是一個對象,那么子組件中的 data 屬性值會互相污染,產(chǎn)生副作用猾蒂。所以一個組件的 data 選項必須是一個函數(shù),因此每個實例可以維護(hù)一份被返回對象的獨立的拷貝均唉。new Vue 的實例是不會被復(fù)用的,因此不存在以上問題。
6.computed 和 watch 有什么區(qū)別?
computed 計算屬性 :
依賴其它屬性值,只有它依賴的屬性值發(fā)生改變,下一次獲取 computed 的值時才會重新計算 computed 的值,如果和上次計算結(jié)果不一致,重新渲染頁面肚菠。
watch 偵聽器 : 更多的是「觀察」的作用,無緩存性,類似于某些數(shù)據(jù)的監(jiān)聽回調(diào),每當(dāng)監(jiān)聽的數(shù)據(jù)變化時都會執(zhí)行回調(diào)進(jìn)行后續(xù)操作。
追問:computed 和 watch 應(yīng)用場景?
關(guān)鍵詞 computed
+緩存
computed :當(dāng)我們需要進(jìn)行數(shù)值計算,并且依賴于其它數(shù)據(jù)時,應(yīng)該使用 computed,因為可以利用 computed 的緩存特性,避免每次獲取值時,都要重新計算。
watch: 當(dāng)我們需要在數(shù)據(jù)變化時執(zhí)行的操作時使用(如調(diào)用其它函數(shù))
追問 :能使用箭頭函數(shù)定義computed和watch嗎?
不應(yīng)該使用箭頭函數(shù)來定義 watcher 函數(shù),理由是箭頭函數(shù)綁定了父級作用域的上下文咪橙,所以 this 將不會按照期望指向 Vue 實例,為undefined
7.MVC和MVVM的原理
-
MVC
image.png
視圖(View):用戶界面。
控制器(Controller):業(yè)務(wù)邏輯
模型(Model):數(shù)據(jù)保存
實現(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 之間并沒有直接的聯(lián)系,而是通過ViewModel進(jìn)行交互. Model 和 ViewModel 之間的交互是雙向的戳表, 因此View 數(shù)據(jù)的變化會同步到Model中桶至,而Model 數(shù)據(jù)的變化也會立即反應(yīng)到View 上。
8.vue數(shù)據(jù)綁定是雙向還是單向的
Vue 在不同組件間強制使用單向數(shù)據(jù)流匾旭。這使應(yīng)用中的數(shù)據(jù)流更加清晰易懂镣屹。
9.v-model雙向綁定的原理?
v-model 本質(zhì)上不過是語法糖。它負(fù)責(zé)監(jiān)聽用戶的輸入事件以更新數(shù)據(jù).
原理如下:
Object.defineproperty()重新定義(set方法)對象設(shè)置屬性值和(get方法)獲取屬性值的操縱來實現(xiàn)的.
1.實現(xiàn)一個監(jiān)聽器Observer价涝,用來劫持并監(jiān)聽所有屬性女蜈,如果有變動的,就通知訂閱者色瘩。
2.實現(xiàn)一個訂閱者Watcher伪窖,可以收到屬性的變化通知并執(zhí)行相應(yīng)的函數(shù),從而更新視圖居兆。
3.實現(xiàn)一個解析器Compile惰许,可以掃描和解析每個節(jié)點的相關(guān)指令,并根據(jù)初始化模板數(shù)據(jù)以及初始化相應(yīng)的訂閱器史辙。
9.全局導(dǎo)航鉤子函數(shù)應(yīng)用場景?
vue router.beforeEach(全局前置守衛(wèi))router.beforeEach 是頁面加載之前(before each)意思是在 每次每一個路由改變的時候都得執(zhí)行一遍.
vue router.afterEach(全局后置守衛(wèi))汹买,相反router.afterEach是頁面加載之后.
應(yīng)用場景:
- 可進(jìn)行一些頁面跳轉(zhuǎn)前處理,例如判斷需要登錄的頁面進(jìn)行攔截聊倔,做登錄跳轉(zhuǎn)晦毙!
2.進(jìn)入頁面登錄判斷、管理員權(quán)限判斷耙蔑、瀏覽器判斷
10 .v-if和v-for在同一個標(biāo)簽中的執(zhí)行順序?
v-for 比 v-if 優(yōu)先級高见妒,如果每一次都需要遍歷整個數(shù)組,將會影響速度注意v-for 遍歷避免同時使用 v-if
如果需要使用判斷,建議使用計算屬性
<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.路由獨享的守衛(wèi)(路由內(nèi)鉤子)
路由獨享的守衛(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,再分別把它們交給對應(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項目中如果methods的方法用箭頭函數(shù)定義結(jié)果會怎么樣幌蚊?
因為箭頭函數(shù)默綁定父級作用域的上下文,所以不會綁定vue實例, 在嚴(yán)格模式下this是undefined溃卡,在非嚴(yán)格模式下指向window
14.vue怎么實現(xiàn)強制刷新組件溢豆?
1.調(diào)用強制刷新方法 this.$forceUpdate()
- 給模板上綁定key值,通過修改key值,實現(xiàn)組件刷新<SomeComponent :key="theKey"/>//選項里綁定datadata(){ return{ theKey:0 }}//刷新key達(dá)到刷新組件的目的theKey++;
15.如何在子組件中訪問父組件的實例?
通過this.
parent.event來調(diào)用父組件的方法
2:在子組件里用$emit向父組件觸發(fā)一個事件瘸羡,父組件監(jiān)聽這個事件
3:父組件把方法傳入子組件中漩仙,在子組件里直接調(diào)用這個方法父組件如何調(diào)用子組件的方法?給子組件設(shè)置屬性ref
<子組件 ref="name" />可以在子組件中加上ref,然后通過this.$refs.ref.method調(diào)用
16.vue組件里寫的原生addEventListeners監(jiān)聽事件犹赖,要手動去銷毀嗎讯赏?為什么?
需要, Vue不會主動移除監(jiān)聽事件, 多次進(jìn)入組件,事件會綁定多次冷尉,另一方面是函數(shù)沒釋放會內(nèi)存溢出.
17.組件中寫name選項有什么作用漱挎?
a.項目使用keep-alive時,可搭配組件name進(jìn)行緩存過濾b.DOM做遞歸組件時需要調(diào)用自身name
c.vue-devtools調(diào)試工具里顯示的組見名稱是由vue中組件name決定的
18.<template></template>
有什么用雀哨?
當(dāng)做一個不可見的包裹元素磕谅,減少不必要的DOM元素,整個結(jié)構(gòu)會更加清晰雾棺。使用場景主要用于分組的條件判斷和列表渲染膊夹。結(jié)合v-for、v-if等一起使用捌浩,插槽時使用
19 .vue組件之間的通信都有哪些放刨?
父子組件傳值
- 通過props屬性傳值
- 通過
on傳值
- (
children ) / $refs
兄弟組件傳值
1.Vuex
2.Bus
跨級組件傳值
- provide/inject
-
listeners
20.route和router有什么區(qū)別?
route:代表當(dāng)前路由信息對象尸饺,可以獲取到當(dāng)前路由的信息參數(shù)router:代表路由實例的對象进统,包含了路由的跳轉(zhuǎn)方法,鉤子函數(shù)等
21.怎樣動態(tài)加載路由?
通過router.addRoutes方法可以動態(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.說說active-class是哪個組件的屬性浪听?
active-class是vue-router模塊的router-link組件中的屬性螟碎,用來設(shè)置選中連接的樣式.
23.為什么vue使用異步更新組件?
收集當(dāng)前的改動一次性批量更新,為了節(jié)省diff開銷.
24.怎么緩存當(dāng)前的組件?緩存后怎么更新迹栓?
1.通過keep-alive組件緩存需要緩存的組件
<keep-alive includes="組件1name,組件2name">
<router-view>
</keep-alive>
2.當(dāng)組件激活后,會觸發(fā)鉤子函數(shù)actived,在這個鉤子函數(shù)中,做數(shù)據(jù)更新.
25.vue怎么獲取DOM節(jié)點掉分?
為組件定義ref屬性<input ref="myInput">通過this.$refs.myInput 就可以獲取dom節(jié)點.
26.vuex中actions和mutations有什么區(qū)別?
1.mutations可以直接修改state克伊,但只能包含同步操作酥郭,同時,只能通過提交commit調(diào)用.
2.actions可以包含異步操作,通過store.dispatch觸發(fā),不能直接修改數(shù)據(jù),需要調(diào)用commit去修改數(shù)據(jù).
27. 怎么監(jiān)聽vuex數(shù)據(jù)的變化愿吹?
通過watch監(jiān)聽數(shù)據(jù)的變化
watch:{
'$store.state.test':function(value){
console.log('數(shù)據(jù)修改了',value)
}}
28.開啟vuex中的嚴(yán)格模式有什么好處?
主要用戶防止不合理的改變狀態(tài)值如:this.$.store.state.list = [],這樣就會拋出異常
A.在嚴(yán)格模式下不从,無論何時發(fā)生了狀態(tài)變更且不是由 mutation 函數(shù)引起的,將會拋出錯誤洗搂。這能保證所有的狀態(tài)變更都能被調(diào)試工具跟蹤到消返。
B. 不要在發(fā)布環(huán)境下啟用嚴(yán)格模式!嚴(yán)格模式會深度監(jiān)測狀態(tài)樹來檢測不合規(guī)的狀態(tài)變更——請確保在發(fā)布環(huán)境下關(guān)閉嚴(yán)格模式耘拇,以避免性能損失撵颊。
如何使用?
const store = new Vuex.Store({
// 讓構(gòu)建工具自動幫我們處理
strict: process.env.NODE_ENV !== 'production'
})
30.你了解雙向綁定的計算屬性的應(yīng)用場景嗎?
<input type="text" v-model="username">
如果我們想要監(jiān)聽用戶輸入變化,我們首先會想到下面的方法
<input type="text" v-model="username" @input="onChange">
其實我們可以使用雙向綁定的計算屬性來實現(xiàn)
data() {
return { _username:'' };
}, computed:{
username:{
get(){
return this._username
},
set(value){ // 監(jiān)聽數(shù)據(jù)變化
console.log('監(jiān)聽數(shù)據(jù)變化',value)
this._username = value }
}
}
當(dāng)我們使用了Vuex時,并且開啟了嚴(yán)格模式,那么我們就不能直接綁定狀態(tài)值了, 在用戶輸入時,v-model 會試圖直接修改狀態(tài)name的值,這樣會拋出異常<input v-model="$store.state.name">這個時候我們需要使用雙向綁定的計算屬性來解決這個問題
<input v-model="name">
computed: {
name: {
get () {
return this.$store.state.name
},
set (value) {
this.$store.commit('updateName', value)
}
}}
30.vue中的指令v-on如何綁定多個屬性?
v-on={ 事件名:綁定的自定義回調(diào)函數(shù)}
<input type="text" v-on="{input:onInput,focus:onFocus}"/>
31.vue中使用delete刪除對象的屬性,頁面會更新嗎?
delete this.list[1]
頁面不會更新, Vue不能檢測到 property 被刪除那么如何在刪除元素或者對象屬性時,可以觸發(fā)更新視圖?this.$delete(this.list,1)
32.watch怎么深度監(jiān)聽對象變化?
data() {
return {
data:{},
user:{
info:{ name:123 }
}
};
}
比如我們要對user.info 屬性進(jìn)行監(jiān)聽,如果info屬性有任何更改觸發(fā)通知
watch:{ 'user.info':{
handler(value){
console.log("數(shù)據(jù)變化",value)
}
}
}
此時我們調(diào)用
this.user.info.name = "8888888"handle方法不會被觸發(fā).這個user.info是一個對象
Vue只響應(yīng)對象的地址變化進(jìn)行響應(yīng).
如果我們需要讓Vue對整個info里面的屬性變化,進(jìn)行監(jiān)聽,
就需要開啟深度監(jiān)聽屬性deep:true
watch:{
'user.info':{
handler(value){
console.log("數(shù)據(jù)變化",value)
},
deep:true
}
}
33 .vue組件會在什么時候下被銷毀?
1.頁面關(guān)閉惫叛、
2.路由跳轉(zhuǎn)倡勇、
3.v-if為false
4.改變key值
33.怎么使css樣式只在當(dāng)前組件中生效
給style標(biāo)簽添加scoped屬性, 通過該屬性,可以使得組件之間的樣式不互相污染<style scoped> </style>
原理vue中的scoped屬性的效果主要通過PostCSS轉(zhuǎn)譯實現(xiàn), PostCSS給一個組件中的所有dom添加了一個獨一無二的動態(tài)屬性嘉涌,然后妻熊,給CSS選擇器額外添加一個對應(yīng)的屬性選擇器來選擇該組件中dom.
<div adfs-888-123213 ></div>
vue
vuex
vue-reouter
axios
https://developer.mozilla.org/zh-CN/docs/Web/HTTP
微信小程序
支付寶小程序
can I use
實戰(zhàn)經(jīng)驗
安全
ES6教程
javascript