(掌握)簡單說下setTimeout(fn, 0)中的0代表的是什么?如果我想在vue實現(xiàn)此功能可以用什么方法代替
js運行是基于單線程的,意味著一段代碼執(zhí)行時儡首,其他代碼將進(jìn)入隊列等待片任,一旦線程有空閑就執(zhí)行后續(xù)代碼。如果代碼中設(shè)定了一個setTimeout
蔬胯,那么瀏覽器便會在合適的時間对供,將代碼插入任務(wù)隊列,如果這個時間設(shè)為 0氛濒,就代表立即插入隊列产场,但并不是立即執(zhí)行,仍然要等待前面代碼執(zhí)行完畢舞竿。
所以setTimeout
并不能保證執(zhí)行的時間京景,是否及時執(zhí)行取決于 JavaScript 線程是擁擠還是空閑。
可以用Vue中的nextTick是Vue的DOM更新隊列的下一次更新完成時觸發(fā)醋粟,也是能夠確保DOM更新完畢,如果環(huán)境不支持的時候其實就是setTimeout(fn, 0)重归。
#(掌握)用Vue實現(xiàn)樣式綁定米愿,可以用class或者內(nèi)聯(lián)樣式,最少寫出2個鼻吮?
<!-- 第一種綁定class -->
<div :class="['classA', 'classB']"></div>
<!-- 第二種綁定class -->
<div :class="{'classA': true, 'classB' : false}"></div>
<!-- 第一種綁定style -->
<div :style="{fontSize: '16px', color: 'red'}"></div>
<!-- 第二種綁定style -->
<div :style="[{fontSize: '16px', color: 'red'}]"></div>
#(掌握)el的用法
ref 有三種用法:
1育苟、ref 加在普通的元素上,用this.$refs(ref值) 獲取到的是dom元素椎木。
2违柏、ref 加在子組件上,用 this.refs.XX。
vm.$el:
獲取Vue實例關(guān)聯(lián)的DOM元素畜伐;
比方說我這里想獲取自定義組件tabControl馍惹,并獲取它的OffsetTop,就需要先獲取該組件玛界。
在組件內(nèi)設(shè)置 屬性 ref='一個名稱(tabControl2)', 然后 this.$refs.tabControl2万矾,就拿到了該組件
切記:ref屬性,而獲取組件的時候要用$refs
獲取 OffsetTop慎框,組件不是DOM元素良狈,是沒有OffsetTop的,無法通過.OffsetTop來獲取的笨枯。就需要通過$el來獲取組件中的DOM元素:
this.tabOffsetTop=this.$refs.tabControl2.$el.offsetTop
#(掌握)一薪丁、簡述Vue的生命周期
常用的有8個(生命周期不僅僅是8個)遇西,都是成對出現(xiàn)。分別是: beforeCreate階段窥突、created階段努溃; beforeMount階段、mounted階段阻问; beforeUpdate階段梧税、updated階段; beforeDestroy階段称近、destroyed階段第队; 分別為:創(chuàng)建前/后,載入前/后刨秆,更新前/后凳谦,銷毀前/后。
#(掌握)二衡未、第一次頁面加載會觸發(fā)哪幾個鉤子尸执?
beforeCreate, created, beforeMount, mounted
#(掌握)三、Vue實現(xiàn)數(shù)據(jù)雙向綁定的原理
vue實現(xiàn)數(shù)據(jù)雙向綁定主要是:采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式缓醋,通過Object.defineProperty()來劫持各個屬性的setter如失,getter,在數(shù)據(jù)變動時發(fā)布消息給訂閱者送粱,觸發(fā)相應(yīng)監(jiān)聽回調(diào)褪贵。當(dāng)把一個普通 Javascript 對象傳給 Vue 實例來作為它的 data 選項時,Vue 將遍歷它的屬性抗俄,用 Object.defineProperty 將它們轉(zhuǎn)為 getter/setter脆丁。用戶看不到 getter/setter,但是在內(nèi)部它們讓 Vue 追蹤依賴动雹,在屬性被訪問和修改時通知變化槽卫。
vue的數(shù)據(jù)雙向綁定 將MVVM作為數(shù)據(jù)綁定的入口,整合Observer胰蝠,Compile和Watcher三者晒夹,通過Observer來監(jiān)聽自己的model的數(shù)據(jù)變化,通過Compile來解析編譯模板指令(vue中是用來解析 {{}})姊氓,最終利用watcher搭起observer和Compile之間的通信橋梁,達(dá)到數(shù)據(jù)變化 —>視圖更新喷好;視圖交互變化(input)—>數(shù)據(jù)model變更雙向綁定效果翔横。
#(掌握)四、簡單實現(xiàn)雙向數(shù)據(jù)綁定
<body>
<div id="app">
<input type="text" id="txt">
<p id="show"></p>
</div>
</body>
<script type="text/javascript">
var obj = {}
Object.defineProperty(obj, 'txt', {
get: function () {
return obj
},
set: function (newValue) {
document.getElementById('txt').value = newValue
document.getElementById('show').innerHTML = newValue
}
})
document.getElementById('txt').addEventListener('keyup', function (e) {
obj.txt = e.target.value
})
</script>
#(掌握)六梗搅、簡單講述vuex
vuex是專門為vue.js提供的一種狀態(tài)管理模式禾唁,它采用的是集中式儲存和管理所有組件的狀態(tài)和數(shù)據(jù)效览,方便使用。
Vex有5種屬性荡短,分別是 state丐枉、getter、mutation掘托、action瘦锹、module:
1、state
Vuex 使用單一狀態(tài)樹,即每個應(yīng)用將僅僅包含一個store 實例闪盔,但單一狀態(tài)樹和模塊化并不沖突弯院。存放的數(shù)據(jù)狀態(tài),不可以直接修改里面的數(shù)據(jù)泪掀。
2听绳、getters
類似vue的計算屬性,主要用來過濾一些數(shù)據(jù)异赫。
3椅挣、mutations
mutations定義的方法動態(tài)修改Vuex 的 store 中的狀態(tài)或數(shù)據(jù)。
4塔拳、actions
actions可以理解為通過將mutations里面處里數(shù)據(jù)的方法變成可異步的處理數(shù)據(jù)的方法鼠证,簡單的說就是異步操作數(shù)據(jù)。view 層通過 store.dispath 來分發(fā) action蝙斜。
const store = new Vuex.Store({ //store實例
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
5名惩、modules
項目特別復(fù)雜的時候,可以讓每一個模塊擁有自己的state孕荠、mutation娩鹉、action、getters,使得結(jié)構(gòu)非常清晰稚伍,方便管理弯予。
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
#(掌握)七、vue如何自定義一個過濾器
1个曙、局部過濾器
Html:
<div id="app">
<input type="text" v-model="msg" />
{{msg| 過濾器名稱 }}
</div>
JS:
var vm=new Vue({
el:"#app",
data:{
msg:''
},
filters: {
過濾器名稱: function (value) {
if (!value) return ''
...
return value
}
}
})
2锈嫩、全局過濾器
Vue.filter('過濾器名稱', function (value) {
if (!value) return ''
...
return value
})
#(掌握)八、對keep-alive 的了解垦搬?
keep-alive
包裹動態(tài)組件時呼寸,會緩存不活動的組件實例,主要用于保留組件狀態(tài)或避免重新渲染。
使用方法:
<keep-alive>
<component>
<!-- 該組件將被緩存猴贰! -->
</component>
</keep-alive>
#(掌握)十一对雪、Vue 組件 data 為什么必須是函數(shù)
每個實例可以維護(hù)一份被返回對象的獨立的拷貝。data是一個函數(shù)的話米绕,這樣每復(fù)用一次組件瑟捣,就會返回一份新的data
馋艺,類似于給每個組件實例創(chuàng)建一個私有的數(shù)據(jù)空間,讓各個組件實例維護(hù)各自的數(shù)據(jù)迈套。而單純的寫成對象形式捐祠,就使得所有組件實例共用了一份data
,就會造成一個變了全都會變的結(jié)果桑李。
#(掌握)十二踱蛀、Vue 中怎么自定義指令
1、全局注冊
// 注冊一個全局自定義指令 `v-focus`
Vue.directive('focus', {
// 當(dāng)被綁定的元素插入到 DOM 中時……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})
2芙扎、局部注冊
directives: {
focus: {
// 指令的定義
inserted: function (el) {
el.focus()
}
}
}
#(掌握)十三星岗、nextTick 是做什么的
$nextTick
是在下次 DOM
更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào),在修改數(shù)據(jù)之后使用 $nextTick
戒洼,則可以在回調(diào)中獲取更新后的DOM俏橘。
#(掌握)十四、$route
和 $router
的區(qū)別
$router
為 VueRouter
實例圈浇,想要導(dǎo)航到不同 URL
寥掐,則使用 $router.push
方法
$route
為當(dāng)前 router
跳轉(zhuǎn)對象里面可以獲取 name
、 path
磷蜀、 query
召耘、 params
等
#(掌握)十五、vue-cli生成的項目文件夾assets和public(static) 的區(qū)別
vue-cli2生成的項目目錄是static
vue-cli3以上生成的項目目錄是public
- 相同點:
assets和public(static) 都是存放靜態(tài)資源的文件褐隆。項目所需要的靜態(tài)文件污它、圖片、樣式文件都可以放在這兩個文件夾下
- 不同點:
在assets中存放的靜態(tài)資源庶弃,在項目打包時會將這些靜態(tài)資源與代碼衫贬、index.html文件一起一同進(jìn)行打包壓縮,上傳到服務(wù)器
在public(static)中存放的靜態(tài)資源歇攻,不會被打包壓縮格式化等流程固惯,而是直接進(jìn)入打包好的目錄,直接上傳到服務(wù)器
#(掌握)十六缴守、DOM渲染在哪個周期中就已經(jīng)完成
DOM 渲染在 mounted 中就已經(jīng)完成了葬毫。
#(掌握)十七、VNode是什么屡穗?虛擬DOM是什么贴捡?
Vue在頁面上渲染的節(jié)點,及其子節(jié)點稱為“虛擬節(jié)點 (Virtual Node)”村砂,簡寫為“VNode”烂斋。“虛擬 DOM”是由 Vue 組件樹建立起來的整個 VNode 樹的稱呼。
#(掌握)十八源祈、什么是RESTful API?怎么使用?
是一個api的標(biāo)準(zhǔn)色迂,無狀態(tài)請求香缺。請求的路由地址是固定的,如果是tp5則先路由配置中把資源路由配置好歇僧。標(biāo)準(zhǔn)有:.post .put .delete
#(掌握)二十图张、如何讓CSS只在當(dāng)前組件中起作用?
將當(dāng)前組件的<style>
修改為 <style scoped>
#(掌握)二十一、 修改第三方庫的樣式
/deep/
>>>
#(掌握)二十二 诈悍、那你能講一講MVVM嗎祸轮?
MVVM是Model-View-ViewModel
縮寫,也就是把MVC
中的Controller
演變成ViewModel
侥钳。Model層代表數(shù)據(jù)模型适袜,View代表UI組件,ViewModel是View和Model層的橋梁舷夺,數(shù)據(jù)會綁定到viewModel層并自動將數(shù)據(jù)渲染到頁面中苦酱,視圖變化的時候會通知viewModel層更新數(shù)據(jù)。
#(掌握)單向數(shù)據(jù)流和雙向數(shù)據(jù)流
單向數(shù)據(jù)流(Unidirectional data flow)方式使用一個上傳數(shù)據(jù)流和一個下傳數(shù)據(jù)流進(jìn)行單向數(shù)據(jù)通信给猾,兩個數(shù)據(jù)流之間相互獨立疫萤。單向數(shù)據(jù)流指只能從一個方向來修改狀態(tài)。vuex(組件data -> action -> state->組件data)
與單向數(shù)據(jù)流對對應(yīng)的是雙向數(shù)據(jù)流(也叫雙向綁定)敢伸。在雙向數(shù)據(jù)流中扯饶,Model(可以理解為狀態(tài)的集合) 中可以修改自己或其他Model的狀態(tài), 用戶的操作(如在輸入框中輸入內(nèi)容)也可以修改狀態(tài)池颈。這使改變一個狀態(tài)有可能會觸發(fā)一連串的狀態(tài)的變化尾序,最后很難預(yù)測最終的狀態(tài)是什么樣的。使得代碼變得很難調(diào)試饶辙。
#(掌握)說一下MVC的理解蹲诀?
mvc是模型(model)-視圖(view)-控制器(controller)`的縮寫,一種軟件設(shè)計典范使用MVC的目的是將M和V的實現(xiàn)代碼分離弃揽,從而使同一個程序可以使用不同的表現(xiàn)形式脯爪。`MVC對應(yīng)Html,CSS矿微,js痕慢。
#(掌握)二十三、那你知道Vue3.x響應(yīng)式數(shù)據(jù)原理嗎涌矢?
Vue3.x改用Proxy
替代Object.defineProperty掖举。因為Proxy可以直接監(jiān)聽對象和數(shù)組的變化,并且有多達(dá)13種攔截方法娜庇。并且作為新標(biāo)準(zhǔn)將受到瀏覽器廠商重點持續(xù)的性能優(yōu)化
Proxy只會代理對象的第一層塔次,那么Vue3又是怎樣處理這個問題的呢方篮?(拓展)
判斷當(dāng)前Reflect.get的返回值是否為Object,如果是則再通過reactive
方法做代理励负, 這樣就實現(xiàn)了深度觀測藕溅。
監(jiān)測數(shù)組的時候可能觸發(fā)多次get/set,那么如何防止觸發(fā)多次呢继榆?(拓展)
我們可以判斷key是否為當(dāng)前被代理對象target自身屬性巾表,也可以判斷舊值與新值是否相等,只有滿足以上兩個條件之一時略吨,才有可能執(zhí)行trigger集币。
#(掌握)二十四、再說一下vue2.x中如何監(jiān)測數(shù)組變化
使用了函數(shù)劫持的方式翠忠,重寫了數(shù)組的方法鞠苟,Vue將data中的數(shù)組進(jìn)行了原型鏈重寫(push,pop,shift,unshift,splice...),指向了自己定義的數(shù)組原型方法负间。這樣當(dāng)調(diào)用數(shù)組api時偶妖,可以通知依賴更新。如果數(shù)組中包含著引用類型政溃,會對數(shù)組中的引用類型再次遞歸遍歷進(jìn)行監(jiān)控趾访。這樣就實現(xiàn)了監(jiān)測數(shù)組變化。
#(掌握)二十五董虱、Computed和Watch
Computed
本質(zhì)是一個具備緩存的watcher扼鞋,依賴的屬性發(fā)生變化就會更新視圖。 適用于計算比較消耗性能的計算場景愤诱。當(dāng)表達(dá)式過于復(fù)雜時云头,在模板中放入過多邏輯會讓模板難以維護(hù),可以將復(fù)雜的邏輯放入計算屬性中處理淫半。
Watch
沒有緩存性溃槐,更多的是觀察的作用,可以監(jiān)聽某些數(shù)據(jù)執(zhí)行回調(diào)科吭。當(dāng)我們需要深度監(jiān)聽對象中的屬性時昏滴,可以打開deep:true
選項,這樣便會對對象中的每一項進(jìn)行監(jiān)聽对人。這樣會帶來性能問題谣殊,優(yōu)化的話可以使用字符串形式
監(jiān)聽。
#(掌握)二十六.再說一下虛擬Dom以及key屬性的作用
由于在瀏覽器中操作DOM是很昂貴的牺弄。頻繁的操作DOM姻几,會產(chǎn)生一定的性能問題。這就是虛擬Dom的產(chǎn)生原因
。
Vue2的Virtual DOM借鑒了開源庫snabbdom
的實現(xiàn)蛇捌。
Virtual DOM本質(zhì)就是用一個原生的JS對象去描述一個DOM節(jié)點抚恒。是對真實DOM的一層抽象。
(也就是源碼中的VNode類络拌,它定義在src/core/vdom/vnode.js中柑爸。)
VirtualDOM映射到真實DOM要經(jīng)歷VNode的create、diff盒音、patch等階段。
「key的作用是盡可能的復(fù)用 DOM 元素馅而∠榉蹋」
新舊 children 中的節(jié)點只有順序是不同的時候,最佳的操作應(yīng)該是通過移動元素的位置來達(dá)到更新的目的瓮恭。
需要在新舊 children 的節(jié)點中保存映射關(guān)系雄坪,以便能夠在舊 children 的節(jié)點中找到可復(fù)用的節(jié)點。key也就是children中節(jié)點的唯一標(biāo)識屯蹦。
#(掌握)二十七.Vue中組件生命周期調(diào)用順序說一下
組件的調(diào)用順序都是先父后子
,渲染完成的順序是先子后父
维哈。
組件的銷毀操作是先父后子
,銷毀完成的順序是先子后父
登澜。
加載渲染過程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount- >子mounted->父mounted
子組件更新過程
父beforeUpdate->子beforeUpdate->子updated->父updated
父組件更新過程
父 beforeUpdate -> 父 updated
銷毀過程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed
#(了解)二十八.SSR了解嗎阔挠?
SSR也就是服務(wù)端渲染,也就是將Vue在客戶端把標(biāo)簽渲染成HTML的工作放在服務(wù)端完成脑蠕,然后再把html直接返回給客戶端
购撼。
SSR有著更好的SEO、并且首屏加載速度更快等優(yōu)點谴仙。不過它也有一些缺點迂求,比如我們的開發(fā)條件會受到限制,服務(wù)器端渲染只支持beforeCreate
和created
兩個鉤子晃跺,當(dāng)我們需要一些外部擴(kuò)展庫時需要特殊處理揩局,服務(wù)端渲染應(yīng)用程序也需要處于Node.js的運行環(huán)境。還有就是服務(wù)器會有更大的負(fù)載需求掀虎。
#(了解)在vuejs中實現(xiàn)防止模板渲染時閃爍的方法
[v-cloak] {
display: none;
}
<div v-cloak>
{{ message }}
</div>
#(了解)十九凌盯、聊聊你對Vue.js的template編譯的理解?
簡而言之涩盾,就是先轉(zhuǎn)化成AST樹十气,再得到的render函數(shù)返回VNode(Vue的虛擬DOM節(jié)點)。
詳情步驟:
首先春霍,通過compile編譯器把template編譯成AST語法樹(abstract syntax tree 抽象語法樹 即 源代碼的抽象語法結(jié)構(gòu)的樹狀表現(xiàn)形式)砸西,compile是createCompiler的返回值,createCompiler是用以創(chuàng)建編譯器的。另外compile還負(fù)責(zé)合并option芹枷。
然后衅疙,AST會經(jīng)過generate(將AST語法樹轉(zhuǎn)化成render funtion字符串的過程)得到render函數(shù),render的返回值是VNode鸳慈,VNode是Vue的虛擬DOM節(jié)點饱溢,里面有(標(biāo)簽名、子節(jié)點走芋、文本等等)
#(了解)談?wù)刅ue.extend和Vue.component
Vue.extend
返回的是一個擴(kuò)展實例構(gòu)造器绩郎,也就是預(yù)設(shè)了部分選項的Vue實例構(gòu)造器。其主要用來服務(wù)于Vue.component
翁逞。
Vue.component()`會注冊一個全局的組件肋杖,其會自動判斷第二個傳進(jìn)來的是Vue繼續(xù)對象(`Vue.extend`)還是普通對象(`{...}`),如果傳進(jìn)來的是普能對象的話會自動調(diào)用`Vue.extend
#(了解)九挖函、vue常用的修飾符状植?
.prevent: 提交事件不再重載頁面竭望;
.stop: 阻止單擊事件冒泡墩莫;
.self: 當(dāng)事件發(fā)生在該元素本身而不是子元素的時候會觸發(fā);
.capture: 事件偵聽堤结,事件發(fā)生的時候會調(diào)用必怜;
#(了解)十肉拓、什么是vue的計算屬性?
在模板中放入太多的邏輯會讓模板過重且難以維護(hù)梳庆,在需要對數(shù)據(jù)進(jìn)行復(fù)雜處理帝簇,且可能多次使用的情況下,盡量采取計算屬性的方式靠益。好處:
① 使得數(shù)據(jù)處理結(jié)構(gòu)清晰丧肴;
② 依賴于數(shù)據(jù),數(shù)據(jù)更新胧后,處理結(jié)果自動更新芋浮;
③ 計算屬性內(nèi)部this指向vm實例;
④ 在template調(diào)用時壳快,直接寫計算屬性名即可纸巷;
⑤ 常用的是getter方法,獲取數(shù)據(jù)眶痰,也可以使用set方法改變數(shù)據(jù)瘤旨;
⑥ 相較于methods,不管依賴的數(shù)據(jù)變不變竖伯,methods都會重新計算存哲,但是依賴數(shù)據(jù)不變的時候computed從緩存中獲取因宇,不會重新計算。
#(了解)五祟偷、Vue的路由實現(xiàn)
1察滑、hash模式
在瀏覽器中符號“#”,#以及#后面的字符稱之為hash修肠,用window.location.hash讀群爻健; 特點:hash雖然在URL中嵌施,但不被包括在HTTP請求中饲化;用來指導(dǎo)瀏覽器動作,對服務(wù)端安全無用吗伤,hash不會重加載頁面滓侍。 hash 模式下,僅 hash 符號之前的內(nèi)容會被包含在請求中牲芋,如 http://www.xxx.com (opens new window),因此對于后端來說捺球,即使沒有做到對路由的全覆蓋缸浦,也不會返回 404 錯誤。
2氮兵、history模式
history采用HTML5的新特性裂逐;且提供了兩個新方法:pushState(),replaceState()可以對瀏覽器歷史記錄棧進(jìn)行修改泣栈,以及popState事件的監(jiān)聽到狀態(tài)變更卜高。 history 模式下,前端的 URL 必須和實際向后端發(fā)起請求的 URL 一致南片,如 http://www.xxx.com/items/id掺涛。后端如果缺少對 /items/id 的路由處理,將返回 404 錯誤疼进。Vue-Router 官網(wǎng)里如此描述:“不過這種模式要玩好薪缆,還需要后臺配置支持……所以呢,你要在服務(wù)端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態(tài)資源伞广,則應(yīng)該返回同一個 index.html 頁面拣帽,這個頁面就是你 app 依賴的頁面〗莱”
#(了解)vue-router 有幾種導(dǎo)航鉤子减拭?
1、全局守衛(wèi): router.beforeEach
2区丑、全局解析守衛(wèi): router.beforeResolve
3拧粪、全局后置鉤子: router.afterEach
4修陡、路由獨享的守衛(wèi): beforeEnter
5、組件內(nèi)的守衛(wèi): beforeRouteEnter既们、beforeRouteUpdate (2.2 新增)濒析、beforeRouteLeave