SPA單頁 Web 應(yīng)用 (single-page application)
簡單理解為:僅僅在web頁面初始化時(shí)加載相應(yīng)的HTML、JavaScript、CSS踱蛀,一旦頁面加載完成了嫁佳,SPA不會(huì)因?yàn)橛脩舻牟僮鞫M(jìn)行頁面的重新加載或跳轉(zhuǎn)蝠引,而是利用 JavaScript 動(dòng)態(tài)的變換HTML的內(nèi)(采用的是div切換顯示和隱藏)怜俐,從而實(shí)現(xiàn)UI與用戶的交互梳杏。
SPA的優(yōu)缺點(diǎn)
1容贝、優(yōu)點(diǎn):
∫(1)由于避免了頁面的重新加載楼眷,SPA 可以提供較為流暢的用戶體驗(yàn)。得益于ajax树姨,我們可以實(shí)現(xiàn)無跳轉(zhuǎn)刷新摩桶,又多虧了瀏覽器的histroy機(jī)制,我們用hash的變化從而可以實(shí)現(xiàn)推動(dòng)界面變化帽揪。
∠跚濉(2)只要使用支持HTML5和CSS3的瀏覽器就可以執(zhí)行復(fù)雜的SPA,讓開發(fā)SPA網(wǎng)頁程序的入門和使用門檻降低不少转晰。
2芦拿、缺點(diǎn):
以SPA方式開發(fā)的網(wǎng)站不容易管理也不夠安全。因?yàn)闆]了一頁一頁的網(wǎng)頁給搜索引擎的爬蟲來爬查邢,所以蔗崎,在搜索引擎最佳化(SEO)的工作上,需要花費(fèi)額外的功夫扰藕。因?yàn)闆]有換頁缓苛,需要自定義狀態(tài)來取代傳統(tǒng)網(wǎng)頁程序以網(wǎng)址來做判斷。
vue 生命周期
vue每個(gè)組件都是獨(dú)立的邓深,每個(gè)組件都有一個(gè)屬于它的生命周期未桥,從一個(gè)組件創(chuàng)建、數(shù)據(jù)初始化芥备、掛載冬耿、更新、銷毀萌壳,這就是一個(gè)組件所謂的生命周期
beforeCreate:實(shí)例組件剛創(chuàng)建亦镶,元素DOM和數(shù)據(jù)都還沒有初始化,暫時(shí)不能在這個(gè)周期里面進(jìn)行生命操作
created:數(shù)據(jù)data已經(jīng)初始化完成袱瓮,方法也已經(jīng)可以調(diào)用缤骨,但是DOM未渲染。
beforeMount:DOM未完成掛載尺借,數(shù)據(jù)也初始化完成绊起,但是數(shù)據(jù)的雙向綁定還是顯示{{}}
mounted:數(shù)據(jù)和DOM都完成掛載,在上一個(gè)周期占位的數(shù)據(jù)把值給渲染進(jìn)去褐望±兆可以在這邊請求,不過created請求會(huì)更好一些瘫里。這個(gè)周期適合執(zhí)行初始化需要操作DOM的方法实蔽。
beforeUpdate:只要是頁面數(shù)據(jù)改變了都會(huì)觸發(fā),數(shù)據(jù)更新之前谨读,頁面數(shù)據(jù)還是原來的數(shù)據(jù)局装,當(dāng)你請求賦值一個(gè)數(shù)據(jù)的時(shí)候會(huì)執(zhí)行這個(gè)周期,如果沒有數(shù)據(jù)改變不執(zhí)行劳殖。
updated:只要是頁面數(shù)據(jù)改變了都會(huì)觸發(fā)铐尚,數(shù)據(jù)更新完畢,頁面的數(shù)據(jù)是更新完成的哆姻。
beforeDestroy:鉤子函數(shù)在實(shí)例銷毀之前調(diào)用宣增。在這一步,實(shí)例仍然完全可用矛缨。
destroyed:鉤子函數(shù)在Vue 實(shí)例銷毀后調(diào)用爹脾。調(diào)用后,Vue 實(shí)例指示的所有東西都會(huì)解綁定箕昭,所有的事件監(jiān)聽器會(huì)被移除灵妨,所有的子實(shí)例也會(huì)被銷毀。
MVVM框架設(shè)計(jì)理念
MVVM分為Model落竹、View泌霍、ViewModel三者。
Model 代表數(shù)據(jù)模型述召,數(shù)據(jù)和業(yè)務(wù)邏輯都在Model層中定義朱转;
View 代表UI視圖,負(fù)責(zé)數(shù)據(jù)的展示桨武;
ViewModel 負(fù)責(zé)監(jiān)聽 Model 中數(shù)據(jù)的改變并且控制視圖的更新肋拔,處理用戶交互操作;
Model 和 View 并無直接關(guān)聯(lián)呀酸,而是通過 ViewModel 來進(jìn)行聯(lián)系的凉蜂,Model 和 ViewModel 之間有著雙向數(shù)據(jù)綁定的聯(lián)系。因此當(dāng) Model 中的數(shù)據(jù)改變時(shí)會(huì)觸發(fā) View 層的刷新性誉,View 中由于用戶交互操作而改變的數(shù)據(jù)也會(huì)在 Model 中同步窿吩。
這種模式實(shí)現(xiàn)了 Model 和 View 的數(shù)據(jù)自動(dòng)同步,因此開發(fā)者只需要專注對數(shù)據(jù)的維護(hù)操作即可错览,而不需要自己操作 dom纫雁。
vue data中聲明一個(gè)空對象,obj.attr = 5視圖會(huì)刷新嗎倾哺?
不會(huì)刷新
原因在于在Vue實(shí)例創(chuàng)建時(shí)轧邪,obj.attr 并未聲明刽脖,因此就沒有被Vue轉(zhuǎn)換為響應(yīng)式的屬性,自然就不會(huì)觸發(fā)視圖的更新忌愚,這時(shí)就需要使用Vue的全局api—— $set()
Vue雙向綁定實(shí)現(xiàn)原理
2.x 原理:Object.defineProperty()曲管,然后重新定義了get()、set()
3.0 采用es6的proxy硕糊,(Proxy用于修改某些操作的默認(rèn)行為院水,也可以理解為在目標(biāo)對象之前架設(shè)一層攔截,外部所有的訪問都必須先通過這層攔截简十,因此提供了一種機(jī)制檬某,可以對外部的訪問進(jìn)行過濾和修改。)取代之前的object.defineProperty()
Vue 的響應(yīng)式原理核心是通過 ES5 的保護(hù)對象的 Object.defindeProperty 中的訪問器屬性中的 get 和 set 方法螟蝙,data 中聲明的屬性都被添加了訪問器屬性恢恼,當(dāng)讀取 data 中的數(shù)據(jù)時(shí)自動(dòng)調(diào)用 get 方法,當(dāng)修改 data 中的數(shù)據(jù)時(shí)胶逢,自動(dòng)調(diào)用 set 方法厅瞎,檢測到數(shù)據(jù)的變化,會(huì)通知觀察者 Wacher初坠,觀察者 Wacher自動(dòng)觸發(fā)重新渲染 當(dāng)前組件(子組件不會(huì)重新渲染),生成新的虛擬 DOM 樹和簸,Vue 框架會(huì)遍歷并對比新虛擬 DOM 樹和舊虛擬 DOM 樹中每個(gè)節(jié)點(diǎn)的差別,并記錄下來碟刺,最后加載操作锁保,將所有記錄的不同點(diǎn),局部修改到真實(shí) DOM 樹上半沽。
1爽柒、監(jiān)聽器Observer:用來劫持并監(jiān)聽所有屬性,如果有變動(dòng)的者填,就通知訂閱者浩村。
2、訂閱者Watcher占哟,可以收到屬性的變化通知并執(zhí)行相應(yīng)的函數(shù)心墅,從而更新視圖
v-for中為何使用key
使用v-for更新已渲染的元素列表時(shí),默認(rèn)用就地復(fù)用策略;列表數(shù)據(jù)修改的時(shí)候,他會(huì)根據(jù)key值去判斷某個(gè)值是否修改,如果修改,則重新渲染這一項(xiàng),否則復(fù)用之前的元素;
key的作用主要是為了高效的更新虛擬DOM。
我們經(jīng)常會(huì)使用index(即數(shù)組的下標(biāo))來作為key,但其實(shí)這是不推薦的一種使用方法;
另外vue中在使用相同標(biāo)簽名元素的過渡切換時(shí)榨乎,也會(huì)使用到key屬性怎燥,其目的也是為了讓vue可以區(qū)分它們,否則vue只會(huì)替換其內(nèi)部屬性而不會(huì)觸發(fā)過渡效果蜜暑。
子組件注冊方式
局部注冊
- 1.import 導(dǎo)入
- 2.components注冊
- 3.以標(biāo)簽的形式铐姚,渲染在頁面里
全局注冊 - 1.在main.js中import導(dǎo)入組件,
- 2.使用Vue.component(標(biāo)簽名肛捍,組件模塊)全局注冊
區(qū)別:1.局部注冊只可以在對應(yīng)引用.vue文件中使用隐绵。
2.全局注冊可以在任意地方使用..
父子組件通訊方式:
1.父組件向子組件傳值
- 在父組件的子組件中通過屬性值方式傳值
- 子組件通過props接收
2.子組件向父組件傳值 - 父組件通過@符號向子組件傳遞一個(gè)事件方法
- 子組件使用this.$emit(事件方法之众,數(shù)據(jù),數(shù)據(jù))
- 父組件通過methods方法中的形參接收數(shù)據(jù)依许。
vue父子組件 渲染過程
同步引入 例子: import Page from '@/components/page'
1.加載渲染過程
父beforeCreated---父created----父beforeMount --- 子beforeCreated---子created----子beforeMount --- 子mounted --- 父mounted
2.子組件更新過
父beforeUpdate---子beforeUpdate----子updated---父updated
3.銷毀過程
父beforeDestroy---子beforeDestroy----子destroyed---父destroyed
異步引入 例子:const Page = () => import('@/components/page')
或者: const Page = resolve => require(['@/components/page'], page)
1.加載渲染過程
父組件的beforeCreate酝枢、created、beforeMount悍手、mounted --> 子組件的beforeCreate、created袍患、beforeMount坦康、mounted
2.子組件更新過
父beforeUpdate---父updated ---子beforeUpdate----子updated
3.銷毀過程
父beforeDestroy---父destroyed---子beforeDestroy----子destroyed
vuecli2.0 和 vue3.0 區(qū)別
1:目錄結(jié)構(gòu)不一樣
vuecli2.0有build目錄 有static目錄
vuecli3.0沒有build目錄 有pulic目錄
2:webpack的配置文件不一樣
vuecli2.0有build目錄 放置的是對應(yīng)的 webpack的配置文件
vuecli3.0已經(jīng)內(nèi)嵌了webpack得配置 ,如果有修改需要新建一個(gè)
vue.config.js文件
3:創(chuàng)建項(xiàng)目的命令不一樣
4:vuecli3.0有對應(yīng)的可視化的界面
Dom 和 虛擬dom
虛擬dom javascript中的一個(gè)內(nèi)置對象,用來描述真實(shí)的dom
vue和react框架中诡延,采用的都是虛擬dom
在頁面第一次渲染完成后滞欠,會(huì)生成一個(gè)js對象,用來描述真實(shí)的dom肆良,之后當(dāng)數(shù)據(jù)有更新或者變化的時(shí)候筛璧,
會(huì)在生成一個(gè)虛擬dom,然后新的虛擬dom和舊的dom進(jìn)行對比(同級對比惹恃,采用的是diff算法)夭谤,找出差異,進(jìn)行更新巫糙,
生成新的虛擬dom朗儒,然后和真實(shí)的dom對比,修改真實(shí)dom中有變化的那一塊
回流:當(dāng)渲染樹中的一部分或者全部因?yàn)樵氐某叽绮窝汀⒉季肿沓㈦[藏等改變而需要重新構(gòu)建的時(shí)候,這時(shí)候就會(huì)發(fā)生回流
重繪:完成回流以后浙值,瀏覽器會(huì)重新繪制受到影響的部分元素到屏幕中
什么時(shí)候會(huì)發(fā)生回流恳不?
1、添加或者刪除可見的DOM元素的時(shí)候
2开呐、元素的位置發(fā)生改變
3烟勋、元素尺寸改變
4、內(nèi)容改變
5负蚊、頁面第一次渲染的時(shí)候
直接操作dom的時(shí)候神妹,引起頁面回流和重會(huì)的次數(shù)很多,而虛擬的dom是不會(huì)發(fā)生回流和重會(huì)的家妆,它會(huì)把要渲染的先統(tǒng)一放到一個(gè)對象中鸵荠,然后通過document.fragment一次性比較并修改真實(shí)DOM中需要改的部分,可以只渲染局部伤极,大大減少了dom的操作蛹找,提高了性能
跟keep-alive有關(guān)的生命周期是哪些姨伤?描述下這些生命周期
activated和deactivated兩個(gè)生命周期函數(shù)
1.activated:當(dāng)組件激活時(shí),鉤子觸發(fā)的順序是created->mounted->activated
2.deactivated: 組件停用時(shí)會(huì)觸發(fā)deactivated庸疾,當(dāng)再次前進(jìn)或者后退的時(shí)候只觸發(fā)activated
computed乍楚、watch的區(qū)別
computed當(dāng)做屬性使用,可以依賴其他 computed届慈,甚至是其他組件的 data必須有返回值徒溪,不能與 data 中的屬性重復(fù);有緩存的功能金顿;不能接受參數(shù)臊泌;
watch可以監(jiān)聽data中的屬性,也可以監(jiān)聽vuex狀態(tài)揍拆; 監(jiān)聽的屬性必須是存在的渠概;允許異步;可接受兩個(gè)參數(shù)
總結(jié):當(dāng)有一些數(shù)據(jù)需要隨著另外一些數(shù)據(jù)變化時(shí)嫂拴,建議使用 computed
當(dāng)有一個(gè)通用的響應(yīng)數(shù)據(jù)變化的時(shí)候播揪,要執(zhí)行一些業(yè)務(wù)邏輯或異步操作的時(shí)候建議使用 watch
let const var 區(qū)別
1.var定義的變量,作用域是整個(gè)封閉函數(shù)筒狠,是全域的猪狈;let定義的變量,作用域是在塊級或者字塊中辩恼;
2.變量提升:不論通過var聲明的變量處于當(dāng)前作用于的第幾行罪裹,都會(huì)提升到作用域的最頂部。
而let聲明的變量不會(huì)在頂部初始化运挫,凡是在let聲明之前使用該變量都會(huì)報(bào)錯(cuò)(引用錯(cuò)誤ReferenceError)状共;
3,只要塊級作用域內(nèi)存在let谁帕,它所聲明的變量就會(huì)綁定在這個(gè)區(qū)域峡继;
4,let不允許在相同作用域內(nèi)重復(fù)聲明(報(bào)錯(cuò)同時(shí)使用var和let匈挖,兩個(gè)let)
const用來專門聲明一個(gè)常量碾牌,它跟let一樣作用于塊級作用域,沒有變量提升儡循,重復(fù)聲明會(huì)報(bào)錯(cuò)舶吗,不同的是const聲明的常量不可改變,聲明時(shí)必須初始化(賦值)
es6 的特有的類型择膝, 常用的操作數(shù)組的方法都有哪些誓琼?
① let const 兩者都有塊級作用域 ② 箭頭函數(shù) ③ 模板字符串 ④ 解構(gòu)賦值
⑤ for of 循環(huán) ⑥ import 、export 導(dǎo)入導(dǎo)出 ⑦ set 數(shù)據(jù)結(jié)構(gòu) ⑧ ...展開運(yùn)算符
⑨ 修飾器 @ ⑩ class 類繼承 ? async、await ? promise ? Symbol
? Proxy 代理
操作數(shù)組常用的方法:
ES5:concat 腹侣、join 叔收、push、pop傲隶、shift饺律、unshift、slice跺株、splice复濒、substring 和 substr 、sort乒省、 reverse芝薇、indexOf 和 lastIndexOf 、every作儿、some、filter馋劈、map攻锰、forEach、reduce
ES6:find妓雾、findIndex娶吞、fill、copyWithin械姻、Array.from妒蛇、Array.of、entries楷拳、values绣夺、key、includes
super
1.作為函數(shù)使用
代表的是父類的構(gòu)造函數(shù)欢揖,返回的是子類的實(shí)例陶耍,即super內(nèi)部的this指的是子類的實(shí)例,因此super()在這里相當(dāng)于父類.prototype.constructor.call(this)她混。
2.super作為對象時(shí)烈钞,在普通方法中,指向父類的原型對象(A.prototype.p())坤按;在靜態(tài)方法中毯欣,指向父類。
導(dǎo)航鉤子有哪幾種臭脓,分別如何用酗钞,如何將數(shù)據(jù)傳入下一個(gè)點(diǎn)擊的路由頁面
1、全局導(dǎo)航守衛(wèi)
前置守衛(wèi)
router.beforeEach((to, from, next) => {
// do someting
});
后置鉤子(沒有 next 參數(shù))
router.afterEach((to, from) => {
// do someting
});
2、路由獨(dú)享守衛(wèi)
cont router = new VueRouter({
routes: [
{
path: '/file',
component: File,
beforeEnter: (to, from ,next) => {
// do someting
}
}
]
});
3算吩、 組件內(nèi)的導(dǎo)航鉤子
組件內(nèi)的導(dǎo)航鉤子主要有這三種:beforeRouteEnter留凭、beforeRouteUpdate、beforeRouteLeave偎巢。他們是直接在路由組件內(nèi)部直接進(jìn)行定義的
路由懶加載 (延遲加載或按需加載蔼夜,即在需要的時(shí)候的時(shí)候進(jìn)行加載)
運(yùn)用懶加載則可以將頁面進(jìn)行劃分,需要的時(shí)候加載頁面压昼,可以有效的分擔(dān)首頁所承擔(dān)的加載壓力求冷,減少首頁加載用時(shí)
只會(huì)在進(jìn)入當(dāng)前這個(gè)路由時(shí)候才會(huì)走 component
1、vue異步組件實(shí)現(xiàn)懶加載:component:resolve=>(require(['需要加載的路由的地址'])窍霞,resolve)
2匠题、webpack提供的require.ensure()
3、ES6 提出的import方法:const HelloWorld = ()=>import('需要加載的模塊地址')