1、vue優(yōu)點
- 輕量級
- 速度快
- 簡單易學
- 低耦合
- 可重用性
- 獨立開發(fā)
- 文檔齊全城菊,且文檔為中文文檔
2、vue父組件向子組件傳遞數(shù)據(jù)
- props
3、子組件向父組件傳遞事件
- $emit
4盗忱、v-show和v-if指令的共同點和不同點
- 相同點:都可以控制dom元素的顯示和隱藏
- 不同點:v-show只是改變display屬性,dom元素并未消失羊赵,切換時不需要重新渲染頁面
- v-if直接將dom元素從頁面刪除趟佃,再次切換需要重新渲染頁面
5扇谣、如何讓CSS只在當前組件中起作用
- scoped
6、<keep-alive></keep-alive>的作用是什么
- 主要是用于需要頻繁切換的組件時進行緩存,不需要重新渲染頁面
7、如何獲取dom
- 給dom元素加ref=‘refname’,然后通過this.$refs.refname進行獲取dom元素
8昆汹、說出幾種vue當中的指令和它的用法
- v-model
- v-on
- v-html
- v-text
- v-once
- v-if
- v-show
9、vue-loader是什么鸯绿?它的用途是什么?
- vue文件的一個加載器簸淀,將template/js/style轉(zhuǎn)換為js模塊
- 用途:js可以寫es6瓶蝴、style樣式
10、為什么用key
- 給每個dom元素加上key作為唯一標識 租幕,diff算法可以正確的識別這個節(jié)點舷手,使頁面渲染更加迅速。
11令蛉、axios及安裝聚霜?
- vue項目中使用ajax時需要axios插件
- 下載方式cnpm install axios --save
12、v-model的使用
- v-model用于表單的雙向綁定珠叔,可以實時修改數(shù)據(jù)
13蝎宇、請說出vue.cli項目中src目錄每個文件夾和文件的用法
- components存放組件
- app.vue主頁面入口
- index.js主文件入口
- ass存放靜態(tài)資源文件
14、分別簡述computed和watch的使用場景
- 用官網(wǎng)的一句話來說祷安,所有需要用到計算的都應該使用計算屬性姥芥。多條數(shù)據(jù)影響一條數(shù)據(jù)時使用計算屬性,使用場景購物車汇鞭。
- 如果是一條數(shù)據(jù)更改凉唐,影響多條數(shù)據(jù)時,使用watch霍骄,使用場景搜索框台囱。
15、v-on可以監(jiān)聽多個方法嗎读整?
- 可以簿训,比如 v-on=“onclick,onbure”
16、$nextTick的使用
- 在data()中的修改后米间,頁面中無法獲取data修改后的數(shù)據(jù)强品,使用$nextTick時,當data中的數(shù)據(jù)修改后屈糊,可以實時的渲染頁面
17的榛、vue組件中data為什么必須是一個函數(shù)?
- 因為javaScript的特性所導致逻锐,在component中夫晌,data必須以函數(shù)的形式存在雕薪,不可以是對象。
- 組件中的data寫成一個函數(shù)晓淀,數(shù)據(jù)以函數(shù)返回值的形式定義蹦哼,這樣每次復用組件的時候,都會返回一份新的data要糊,相當于每個組件實例都有自己私有的數(shù)據(jù)空間,他們值負責各自維護數(shù)據(jù)妆丘,不會造成混亂锄俄。而單純的寫成對象形式,就是所有組件實例共用了一個data勺拣,這樣改一個全部都會修改奶赠。
18、漸進式框架的理解
- 主張最少
- 可以根據(jù)不同的需求選擇不同的層級
19药有、vue在雙向數(shù)據(jù)綁定是如何實現(xiàn)的毅戈?
- vue雙向數(shù)據(jù)綁定是通過數(shù)據(jù)劫持、組合愤惰、發(fā)布訂閱模式的方式來實現(xiàn)的苇经,也就是說數(shù)據(jù)和視圖同步,數(shù)據(jù)發(fā)生變化宦言,視圖跟著變化扇单,視圖變化,數(shù)據(jù)也隨之發(fā)生改變
- 核心:關于vue雙向數(shù)據(jù)綁定奠旺,其核心是Object.defineProperty()方法
20蜘澜、單頁面應用和多頁面應用區(qū)別及缺點
- 單頁面應用(SPA),通俗的說就是指只有一個主頁面的應用响疚,瀏覽器一開始就加載所有的js鄙信、html、css忿晕。所有的頁面內(nèi)容都包含在這個主頁面中装诡。但在寫的時候,還是分開寫杏糙,然后再加護的時候有路由程序動態(tài)載入慎王,單頁面的頁面跳轉(zhuǎn),僅刷新局部資源宏侍。多用于pc端赖淤。
- 多頁面(MPA),就是一個應用中有多個頁面谅河,頁面跳轉(zhuǎn)時是整頁刷新
- 單頁面的優(yōu)點:用戶體驗好咱旱,快确丢,內(nèi)容的改變不需要重新加載整個頁面,基于這一點spa對服務器壓力較型孪蕖鲜侥;前后端分離,頁面效果會比較酷炫
- 單頁面缺點:不利于seo诸典;導航不可用描函,如果一定要導航需要自行實現(xiàn)前進、后退狐粱。初次加載時耗時多舀寓;頁面復雜度提高很多。
21肌蜻、Vue 項目中為什么要在列表組件中寫 key互墓,其作用是什么?
- key是給每一個vnode的唯一id,可以依靠key,更準確, 更快的拿到oldVnode中對應的vnode節(jié)點蒋搜。
- 更準確:因為帶key就不是就地復用了篡撵,在sameNode函數(shù) a.key === b.key對比中可以避免就地復用的情況。所以會更加準確豆挽。
- 更快:利用key的唯一性生成map對象來獲取對應節(jié)點育谬,比遍歷方式更快。
22祷杈、父組件和子組件生命周期鉤子執(zhí)行順序是什么斑司?
- 加載渲染過程:父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
- 子組件更新過程:父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
- 父組件更新過程:父 beforeUpdate -> 父 updated
- 銷毀過程:父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed
23、談一談你對 nextTick 的理解但汞?
- 當你修改了data的值然后馬上獲取這個dom元素的值宿刮,是不能獲取到更新后的值,你需要使用$nextTick這個回調(diào)私蕾,讓修改后的data值渲染更新到dom元素之后在獲取僵缺,才能成功。
24踩叭、vue組件中data為什么必須是一個函數(shù)磕潮?
- 因為JavaScript的特性所導致,在component中容贝,data必須以函數(shù)的形式存在自脯,不可以是對象。
- 組建中的data寫成一個函數(shù)斤富,數(shù)據(jù)以函數(shù)返回值的形式定義膏潮,這樣每次復用組件的時候,都會返回一份新的data满力,相當于每個組件實例都有自己私有的數(shù)據(jù)空間焕参,它們只負責各自維護的數(shù)據(jù)轻纪,不會造成混亂。而單純的寫成對象形式叠纷,就是所有的組件實例共用了一個data刻帚,這樣改一個全都改了。
25涩嚣、vue和jQuery的區(qū)別
- jQuery是使用選擇器(("lable").val();,它還是依賴DOM元素的值。
- Vue則是通過Vue對象將數(shù)據(jù)和View完全分離開來了互妓。對數(shù)據(jù)進行操作不再需要引用相應的DOM對象溪窒,可以說數(shù)據(jù)和View是分離的,他們通過Vue對象這個vm實現(xiàn)相互的綁定冯勉。這就是傳說中的MVVM澈蚌。
26、delete和Vue.delete刪除數(shù)組的區(qū)別
- delete只是被刪除的元素變成了 empty/undefined 其他的元素的鍵值還是不變灼狰。Vue.delete 直接刪除了數(shù)組 改變了數(shù)組的鍵值宛瞄。
27、SPA首屏加載慢如何解決
- 安裝動態(tài)懶加載所需插件交胚;使用CDN資源份汗。
28、vue項目是打包了一個js文件蝴簇,一個css文件杯活,還是有多個文件?
- 根據(jù)vue-cli腳手架規(guī)范熬词,一個js文件旁钧,一個CSS文件。
29互拾、vue更新數(shù)組時觸發(fā)視圖更新的方法
- push()歪今;
- pop();
- shift()颜矿;
- unshift()寄猩;
- splice();
- sort()或衡;
- reverse()
30焦影、什么是 vue 生命周期车遂?有什么作用?
- 每個 Vue 實例在被創(chuàng)建時都要經(jīng)過一系列的初始化過程——例如斯辰,需要設置數(shù)據(jù)監(jiān)聽舶担、編譯模板、將實例掛載到 DOM 并在數(shù)據(jù)變化時更新 DOM 等彬呻。同時在這個過程中也會運行一些叫做 生命周期鉤子 的函數(shù)衣陶,這給了用戶在不同階段添加自己的代碼的機會。
31闸氮、第一次頁面加載會觸發(fā)哪幾個鉤子剪况?
- beforeCreate, created蒲跨, beforeMount译断, mounted
32、vue獲取數(shù)據(jù)在一般在哪個周期函數(shù)
- created
- beforeMount
- mounted
33或悲、created和mounted的區(qū)別
- created:在模板渲染成html前調(diào)用孙咪,即通常初始化某些屬性值,然后再渲染成視圖巡语。
- mounted:在模板渲染成html后調(diào)用翎蹈,通常是初始化頁面完成后,再對html的dom節(jié)點進行一些需要的操作男公。
34荤堪、vue生命周期的理解
- 總共分為8個階段創(chuàng)建前/后,載入前/后枢赔,更新前/后澄阳,銷毀前/后。
- 創(chuàng)建前/后: 在beforeCreated階段踏拜,vue實例的掛載元素el還沒有。
- 載入前/后:在beforeMount階段镀琉,vue實例的$el和data都初始化了峦嗤,但還是掛載之前為虛擬的dom節(jié)點,data.message還未替換屋摔。在mounted階段烁设,vue實例掛載完成,data.message成功渲染。
- 更新前/后:當data變化時装黑,會觸發(fā)beforeUpdate和updated方法副瀑。
- 銷毀前/后:在執(zhí)行destroy方法后,對data的改變不會再觸發(fā)周期函數(shù)恋谭,說明此時vue實例已經(jīng)解除了事件監(jiān)聽以及和dom的綁定糠睡,但是dom結(jié)構(gòu)依然存在。
35疚颊、vuex是什么狈孔?
- vue框架中狀態(tài)管理。
36材义、vuex有哪幾種屬性均抽?
- 有五種,State其掂、 Getter油挥、Mutation 、Action款熬、 Module
- state: 基本數(shù)據(jù)(數(shù)據(jù)源存放地)
- getters: 從基本數(shù)據(jù)派生出來的數(shù)據(jù)
- mutations : 提交更改數(shù)據(jù)的方法喘漏,同步!
- actions : 像一個裝飾器华烟,包裹mutations,使之可以異步持灰。
- modules : 模塊化Vuex
37盔夜、vue全家桶
- vue-cli、vuex堤魁、vueRouter喂链、Axios
38、vue-cli 工程常用的 npm 命令有哪些?
- npm install 下載 node_modules 資源包的命令
- npm run dev 啟動 vue-cli 開發(fā)環(huán)境的 npm 命令
- npm run build vue-cli 生成 生產(chǎn)環(huán)境部署資源 的 npm 命令
- npm run build–report 用于查看 vue-cli 生產(chǎn)環(huán)境部署資源文件大小的 npm 命令
39妥泉、請說出 vue-cli 工程中每個文件夾和文件的用處?
- build 文件夾是保存一些 webpack 的初始化配置椭微。
- config 文件夾保存一些項目初始化的配置
- node_modules 是 npm 加載的項目依賴的模塊
- src 目錄是我們要開發(fā)的目錄:
- assets 用來放置圖片
- components 用來放組件文件
- app.vue 是項目入口文件
- main.js 項目的核心文件
40、v-if 和 v-show 有什么區(qū)別
- 共同點:都是動態(tài)顯示 DOM 元素
- 區(qū)別點:v-if 是動態(tài)的向 DOM 樹內(nèi)添加或者刪除 DOM 元素盲链;v-show 是通過設置 DOM 元素的 display 樣式屬性控制顯隱蝇率;v-if 切換有一個局部編譯/卸載的過程,切換過程中合適地銷毀和重建內(nèi)部的事件監(jiān)聽和子組件刽沾;v-show 只是簡單的基于 css 切換
- 性能消耗:v-if 有更高的切換消耗本慕;v-show 有更高的初始渲染消耗
- 使用場景:v-if 適合運營條件不大可能改變;v-show 適合頻繁切換
41侧漓、v-for 與 v-if 的優(yōu)先級?
- v-for 和 v-if 同時使用锅尘,有一個先后運行的優(yōu)先級,v-for 比 v-if 優(yōu)先級更高布蔗,這就說明在
- v-for 每次的循環(huán)賦值中每一次調(diào)用 v-if 的判斷藤违,所以不推薦 v-if 和 v-for 在同一個標簽中同時使用浪腐。
42、 vue 常用的修飾符?
事件修飾符
- .stop 阻止事件繼續(xù)傳播
- .prevent 阻止標簽默認行為
- .capture 使用事件捕獲模式顿乒,即元素自身觸發(fā)的事件先在此處處理议街,然后才交由內(nèi)部元素進行處理
- .self 只當在 event.target 是當前元素自身時觸發(fā)處理函數(shù)
- .once 事件只會觸發(fā)一次
- .passive 告訴瀏覽器你不想阻止事件的默認行為
v-model 的修飾符
- .lazy 通過這個修飾符,轉(zhuǎn)變?yōu)樵?change 事件再同步
- .number 自動將用戶輸入值轉(zhuǎn)化為數(shù)值類型
- .trim 自動過濾用戶輸入的收尾空格
鍵盤事件修飾符
- .enter
- .tab
- .delete (捕獲“刪除”和“退格”鍵)
- .esc
- .space
- .up
- .down
- .left
- .right
系統(tǒng)修飾符
- .ctrl
- .alt
- .shift
- .meta
鼠標按鈕修飾符
- .left
- .right
- .middle
43淆游、vue 事件中如何使用 event 對象?
獲取事件對象傍睹,方法參數(shù)傳遞 符號
<button @click="Event($event)">事件對象</button>
44犹菱、組件傳值方式有哪些
- 父傳子:子組件通過props[‘xx’] 來接收父組件傳遞的屬性 xx 的值
- 子傳父:子組件通過 this.$emit(‘fnName’,value) 來傳遞,父組件通過接收 fnName 事件方法來接收回調(diào)
- 其他方式:通過創(chuàng)建一個bus拾稳,進行傳值
- 使用Vuex
45、vue 中子組件調(diào)用父組件的方法?
- 直接在子組件中通過 this.$parent.event 來調(diào)用父組件的方法腊脱。
- 在子組件里用$emit()向父組件觸發(fā)一個事件访得,父組件監(jiān)聽這個事件就行了。
- 父組件把方法傳入子組件中陕凹,在子組件里直接調(diào)用這個方法悍抑。
46、 如何讓 CSS 只在當前組件中起作用杜耙?
在組件中的 style 前面加上 scoped
47搜骡、如何獲取 dom?
ref="domName" 用法:this.$refs.domName
48、vue路由跳轉(zhuǎn)
(一)聲明式導航router-link
不帶參數(shù):
// 注意:router-link中鏈接如果是'/'開始就是從根路由開始佑女,如果開始不帶'/'记靡,則從當前路由開始。
<router-link :to="{name:'home'}">
<router-link :to="{path:'/home'}"> //name,path都行, 建議用name
帶參數(shù):
<router-link :to="{name:'home', params: {id:1}}">
<router-link :to="{name:'home', query: {id:1}}">
<router-link :to="/home/:id">
//傳遞對象
<router-link :to="{name:'detail', query: {item:JSON.stringify(obj)}}"></router-link>
(二)this.$router.push()
不帶參數(shù):
this.$router.push('/home')
this.$router.push({name:'home'})
this.$router.push({path:'/home'})
query傳參:
1.路由配置:
name: 'home',
path: '/home'
2.跳轉(zhuǎn):
this.$router.push({name:'home',query: {id:'1'}})
this.$router.push({path:'/home',query: {id:'1'}})
3.獲取參數(shù)
html取參: $route.query.id
script取參: this.$route.query.id
params傳參:
1.路由配置:
name: 'home',
path: '/home/:id'(或者path: '/home:id')
2.跳轉(zhuǎn):
this.$router.push({name:'home',params: {id:'1'}})
注意:
// 只能用 name匹配路由不能用path
// params傳參數(shù)(類似post) 路由配置 path: "/home/:id" 或者 path: "/home:id"否則刷新參數(shù)消失
3.獲取參數(shù)
html取參:$route.params.id
script取參:this.$route.params.id
直接通過path傳參:
1.路由配置:
name: 'home',
path: '/home/:id'
2.跳轉(zhuǎn):
this.$router.push({path:'/home/123'})
或者:
this.$router.push('/home/123')
3.獲取參數(shù):
this.$route.params.id
params和query的區(qū)別:
- query類似 get团驱,跳轉(zhuǎn)之后頁面 url后面會拼接參數(shù)摸吠,類似?id=1。
- 非重要性的可以這樣傳嚎花,密碼之類還是用params寸痢,刷新頁面id還在。
- params類似 post紊选,跳轉(zhuǎn)之后頁面 url后面不會拼接參數(shù)啼止。
(三)this.$router.replace()
用法同上
(四)this.$router.go(n)
向前或者向后跳轉(zhuǎn)n個頁面,n可為正整數(shù)或負整數(shù)
區(qū)別:
this.router.replace
跳轉(zhuǎn)到指定url路徑,但是history棧中不會有記錄趣些,點擊返回會跳轉(zhuǎn)到上上個頁面 (就是直接替換了當前頁面)
this.$router.go(n)
向前或者向后跳轉(zhuǎn)n個頁面仿荆,n可為正整數(shù)或負整數(shù)
49、Vue.js 雙向綁定的原理
Vue.js 2.0 采用數(shù)據(jù)劫持(Proxy 模式)結(jié)合發(fā)布者-訂閱者模式(PubSub 模式)的方式,通過 Object.defineProperty()來劫持各個屬性的 setter拢操,getter锦亦,在數(shù)據(jù)變動時發(fā)布消息給訂閱者,觸發(fā)相應的監(jiān)聽回調(diào)令境。
每個組件實例都有相應的watcher程序?qū)嵗茉埃鼤诮M件渲染的過程中把屬性記錄為依賴,之后當依賴項的setter被調(diào)用時舔庶,會通知watcher重新計算抛蚁,從而致使它關聯(lián)的組件得以更新。
Vue.js 3.0, 放棄了Object.defineProperty 惕橙,使用更快的ES6原生 Proxy (訪問對象攔截器, 也稱代理器)
50瞧甩、Computed和Watch的區(qū)別
computed 計算屬性 : 依賴其它屬性值,并且 computed 的值有緩存,只有它依賴的 屬性值發(fā)生改變,下一次獲取 computed 的值時才會重新計算 computed 的值。
watch 偵聽器 : 更多的是觀察的作用,無緩存性,類似于某些數(shù)據(jù)的監(jiān)聽回調(diào),每 當監(jiān)聽的數(shù)據(jù)變化時都會執(zhí)行回調(diào)進行后續(xù)操作弥鹦。
運用場景:
- 當我們需要進行數(shù)值計算,并且依賴于其它數(shù)據(jù)時,應該使用 computed,因為可以利用 computed的緩存特性,避免每次獲取值時,都要重新計算肚逸。
- 當我們需要在數(shù)據(jù)變化時執(zhí)行異步或開銷較大的操作時,應該使用 watch,使用 watch 選項允許我們執(zhí)行異步操作 ( 訪問一個 API ),限制我們執(zhí)行該操作的頻率, 并在我們得到最終結(jié)果前,設置中間狀態(tài)。這些都是計算屬性無法做到的彬坏。
- 多個因素影響一個顯示朦促,用Computed;一個因素的變化影響多個其他因素栓始、顯示务冕,用Watch;
Computed 和 Methods 的區(qū)別:
- computed: 計算屬性是基于它們的依賴進行緩存的,只有在它的相關依賴發(fā)生改變時才會重新求值對于 method ,只要發(fā)生重新渲染幻赚,
- method 調(diào)用總會執(zhí)行該函數(shù)
51禀忆、過濾器 (Filter)
在Vue中使用filters來過濾(格式化)數(shù)據(jù),filters不會修改數(shù)據(jù)坯屿,而是過濾(格式化)數(shù)據(jù),改變用戶看到的輸出(計算屬性 computed 巍扛,方法 methods 都是通過修改數(shù)據(jù)來處理數(shù)據(jù)格式的輸出顯示领跛。
使用場景: 比如需要處理時間、數(shù)字等的的顯示格式撤奸;
52吠昭、axios是什么
易用、簡潔且高效的http庫胧瓜, 支持node端和瀏覽器端矢棚,支持Promise,支持攔截器等高級配置府喳。
53蒲肋、sass是什么?如何在vue中安裝和使用?
sass是一種CSS預編譯語言安裝和使用步驟如下兜粘。
- 用npm安裝加載程序( sass-loader申窘、 css-loader等加載程序)。
- 在 webpack.config.js中配置sass加載程序孔轴。
54剃法、Vue.js頁面閃爍
Vue. js提供了一個v-cloak指令,該指令一直保持在元素上路鹰,直到關聯(lián)實例結(jié)束編譯贷洲。當和CSS一起使用時,這個指令可以隱藏未編譯的標簽晋柱,直到實例編譯結(jié)束优构。用法如下。
[v-cloak]{
display:none;
}
<div v-cloak>{{ title }}</div>
55趣斤、如何解決數(shù)據(jù)層級結(jié)構(gòu)太深的問題
在開發(fā)業(yè)務時俩块,經(jīng)常會岀現(xiàn)異步獲取數(shù)據(jù)的情況,有時數(shù)據(jù)層次比較深浓领,如以下代碼: span 'v-text="a.b.c.d">, 可以使用vm.set("demo"玉凯,a.b.c.d)
56、vue常用指令
- v-model 多用于表單元素實現(xiàn)雙向數(shù)據(jù)綁定(同angular中的ng-model)
- v-bind 動態(tài)綁定 作用: 及時對頁面的數(shù)據(jù)進行更改
- v-on:click 給標簽綁定函數(shù)联贩,可以縮寫為@漫仆,例如綁定一個點擊函數(shù) 函數(shù)必須寫在methods里面
- v-for 格式: v-for=“字段名 in(of) 數(shù)組json” 循環(huán)數(shù)組或json(同angular中的ng-repeat)
- v-show 顯示內(nèi)容 (同angular中的ng-show)
- v-hide 隱藏內(nèi)容(同angular中的ng-hide)
- v-if 顯示與隱藏 (dom元素的刪除添加 同angular中的ng-if 默認值為false)
- v-else-if 必須和v-if連用
- v-else 必須和v-if連用 不能單獨使用 否則報錯 模板編譯錯誤
- v-text 解析文本
- v-html 解析html標簽
- v-bind:class 三種綁定方法:對象型 ‘{red:isred}’三元型 ‘isred?“red”:“blue”’數(shù)組型 ‘[{red:“isred”},{blue:“isblue”}]’
- v-once 進入頁面時 只渲染一次 不在進行渲染
- v-cloak 防止閃爍
- v-pre 把標簽內(nèi)部的元素原位輸出
57、router的區(qū)別
- $route是“路由信息對象”泪幌,包括path盲厌,params,hash祸泪,query吗浩,fullPath,matched没隘,name等路由信息參數(shù)懂扼。
- $router是“路由實例”對象包括了路由的跳轉(zhuǎn)方法,鉤子函數(shù)等
58右蒲、怎樣理解 Vue 的單項數(shù)據(jù)流
- 數(shù)據(jù)總是從父組件傳到子組件阀湿,子組件沒有權利修改父組件傳過來的數(shù)據(jù),只能請求父組件對原始數(shù)據(jù)進行修改瑰妄。這樣會防止從子組件意外改變父組件的狀態(tài)陷嘴,從而導致你的應用的數(shù)據(jù)流向難以理解。
- 注意:在子組件直接用 v-model 綁定父組件傳過來的 props 這樣是不規(guī)范的寫法间坐,開發(fā)環(huán)境會報警告灾挨。
- 如果實在要改變父組件的 props 值可以再data里面定義一個變量邑退,并用 prop 的值初始化它,之后用$emit 通知父組件去修改涨醋。
59瓜饥、虛擬DOM是什么?有什么優(yōu)缺點浴骂?
由于在瀏覽器中操作DOM是很昂貴的乓土。頻繁操作DOM,會產(chǎn)生一定性能問題溯警。這就是虛擬Dom的產(chǎn)生原因趣苏。Vue2的Virtual DOM 借鑒了開源庫 snabbdom 的實現(xiàn)。Virtual DOM本質(zhì)就是用一個原生的JS對象去描述一個DOM節(jié)點梯轻,是對真實DOM的一層抽象食磕。
優(yōu)點:
1、保證性能下限:框架的虛擬DOM需要適配任何上層API可能產(chǎn)生的操作喳挑,他的一些DOM操作的實現(xiàn)必須是普適的彬伦,所以它的性能并不是最優(yōu)的;但是比起粗暴的DOM操作性能要好很多伊诵,因此框架的虛擬DOM至少可以保證在你不需要手動優(yōu)化的情況下单绑,依然可以提供還不錯的性能,既保證性能的下限曹宴。
2搂橙、無需手動操作DOM:我們不需手動去操作DOM,只需要寫好 View-Model的 代碼邏輯笛坦,框架會根據(jù)虛擬DOM和數(shù)據(jù)雙向綁定区转,幫我們以可預期的方式更新視圖,極大提高我們的開發(fā)效率版扩。
3废离、跨平臺:虛擬DOM本質(zhì)上是JavaScript對象,而DOM與平臺強相關礁芦,相比之下虛擬DOM可以進行更方便地跨平臺操作蜻韭,例如服務器端渲染、weex開發(fā)等等宴偿。
缺點:
1湘捎、無法進行極致優(yōu)化:雖然虛擬DOM + 合理的優(yōu)化诀豁,足以應對大部分應用的性能需要窄刘,但在一些性能要求極高的應用中虛擬DOM無法進行針對性的極致優(yōu)化。
2舷胜、首次渲染大量DOM時娩践,由于多了一層DOM計算活翩,會比innerHTML插入慢。
60翻伺、Vuex 頁面刷新數(shù)據(jù)丟失怎么解決材泄?
需要做 vuex 數(shù)據(jù)持久化,一般使用本地儲存的方案來保存數(shù)據(jù)吨岭,可以自己設計存儲方案拉宗,也可以使用第三方插件。
推薦使用 vuex-persist (脯肉賽斯特)插件辣辫,它是為 Vuex 持久化儲存而生的一個插件旦事。不需要你手動存取 storage,而是直接將狀態(tài)保存至 cookie 或者 localStorage中急灭。
61姐浮、Vuex 為什么要分模塊并且加命名空間?
模塊: 由于使用單一狀態(tài)樹葬馋,應用的所有狀態(tài)會集中到一個比較大的對象卖鲤。當應用變得非常復雜時,store 對象就有可能會變得相當臃腫畴嘶。為了解決以上問題蛋逾,Vuex 允許我們將 store 分割成模塊(module)。每個模塊擁有自己的 state掠廓、mutation换怖、action、getter蟀瞧、甚至是嵌套子模塊沉颂。
命名空間: 默認情況下,模塊內(nèi)部的 action悦污、mutation铸屉、getter是注冊在全局命名空間的 — 這樣使得多個模塊能夠?qū)ν?mutation 或 action 做出響應。如果希望你的模塊具有更高的封裝度和復用性切端,你可以通過添加 namespaced:true 的方式使其成為帶命名的模塊彻坛。當模塊被注冊后,他所有 getter踏枣、action昌屉、及 mutation 都會自動根據(jù)模塊注冊的路徑調(diào)整命名。
62茵瀑、vue 中使用了哪些設計模式间驮?
- 1、工廠模式 - 傳入?yún)?shù)即可創(chuàng)建實例
- 虛擬 DOM 根據(jù)參數(shù)的不同返回基礎標簽的 Vnode 和組件 Vnode马昨。
- 2竞帽、單例模式 - 整個程序有且僅有一個實例
- vuex 和 vue-router 的插件注冊方法 install 判斷如果系統(tǒng)存在實例就直接返回掉扛施。
- 3、發(fā)布-訂閱模式屹篓。(vue 事件機制)
- 4短荐、觀察者模式条舔。(響應式數(shù)據(jù)原理)
- 5魄健、裝飾器模式(@裝飾器的用法)
- 6牍颈、策略模式,策略模式指對象有某個行為谍肤,但是在不同的場景中懦冰,該行為有不同的實現(xiàn)方案 - 比如選項的合并策略。
63谣沸、你都做過哪些 Vue 的性能優(yōu)化刷钢?
這里只列舉針對 Vue 的性能優(yōu)化,整個項目的性能優(yōu)化是一個大工程乳附。
- 對象層級不要過深内地,否則性能就會差。
- 不需要響應式的數(shù)據(jù)不要放在 data 中(可以使用 Object.freeze() 凍結(jié)數(shù)據(jù))
- v-if 和 v-show 區(qū)分使用場景
- computed 和 watch 區(qū)分場景使用
- v-for 遍歷必須加 key赋除,key最好是id值阱缓,且避免同時使用 v-if
- 大數(shù)據(jù)列表和表格性能優(yōu)化 - 虛擬列表 / 虛擬表格
- 防止內(nèi)部泄露,組件銷毀后把全局變量和時間銷毀
- 圖片懶加載
- 路由懶加載
- 異步路由
- 第三方插件的按需加載
- 適當采用 keep-alive 緩存組件
- 防抖举农、節(jié)流的運用
- 服務端渲染 SSR or 預渲染
64荆针、Vue.set 方法原理
在兩種情況下修改 Vue 是不會觸發(fā)視圖更新的。
- 1颁糟、在實例創(chuàng)建之后添加新的屬性到實例上(給響應式對象新增屬性)
- 2航背、直接更改數(shù)組下標來修改數(shù)組的值。
- Vue.set 或者說是 $set 原理如下:因為響應式數(shù)據(jù) 我們給對象和數(shù)組本身新增了ob屬性棱貌,代表的是 Observer 實例玖媚。當給對象新增不存在的屬性,首先會把新的屬性進行響應式跟蹤 然后會觸發(fā)對象 ob 的dep收集到的 watcher 去更新婚脱,當修改數(shù)組索引時我們調(diào)用數(shù)組本身的 splice 方法去更新數(shù)組今魔。
65、函數(shù)式組件使用場景和原理
函數(shù)式組件與普通組件的區(qū)別
- 1障贸、函數(shù)式組件需要在聲明組件時指定 functional:true
- 2错森、不需要實例化,所以沒有this篮洁,this通過render函數(shù)的第二個參數(shù)context代替
- 3涩维、沒有生命周期鉤子函數(shù),不能使用計算屬性嘀粱,watch
- 4激挪、不能通過$emit對外暴露事件,調(diào)用事件只能通過context.listeners.click的方式調(diào)用外部傳入的事件
- 5锋叨、因為函數(shù)組件時沒有實例化的垄分,所以在外部通過ref去引用組件時,實際引用的是HTMLElement
- 6娃磺、函數(shù)式組件的props可以不用顯示聲明薄湿,所以沒有在props里面聲明的屬性都會被自動隱式解析為prop,而普通的組件所有未聲明的屬性都解析到$attrs里面偷卧,并自動掛載到組件根元素上(可以通過inheritAttrs屬性禁止)
優(yōu)點:1.由于函數(shù)組件不需要實例化豺瘤,無狀態(tài),沒有生命周期听诸,所以渲染性要好于普通組件2.函數(shù)組件結(jié)構(gòu)比較簡單坐求,代碼結(jié)構(gòu)更清晰
使用場景:
一個簡單的展示組件,作為容器組件使用 比如 router-view 就是一個函數(shù)式組件晌梨。 “高階組件”—用于接受一個組件為參數(shù)桥嗤,返回一個被包裝過的組件。
相關代碼如下:
if (isTrue(Ctor.options.functional)) { // 帶有functional的屬性的就是函數(shù)式組件 return createFunctionalComponent(Ctor, propsData, data, context, children); } const listeners = data.on; data.on = data.nativeOn; installComponentHooks(data); // 安裝組件相關鉤子 (函數(shù)式組件沒有調(diào)用此方法仔蝌,從而性能高于普通組件)
66泛领、子組件為何不可以修改父組件傳遞的 Prop?
所有的 prop 都使得其父子 prop 之間形成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中敛惊,但是反過來則不行渊鞋。這樣會防止從子組件意外改變父級組件的狀態(tài),從而導致你的應用的數(shù)據(jù)流向難以理解瞧挤。