第一題:說(shuō)一下rem和em的區(qū)別:rem與em都是相對(duì)單位镜廉,我們使用它們的目的就是為了適應(yīng)各種手機(jī)屏幕娇唯。
rem是根據(jù)html根節(jié)點(diǎn)來(lái)計(jì)算的,而em是繼承父元素的字體视乐。
對(duì)于em和rem的區(qū)別一句話概括:em相對(duì)于父元素敢茁,rem相對(duì)于根元素。
rem中的r意思是root(根源)彰檬,這也就不難理解了。
第二題:用過(guò)彈性盒嗎逢倍?
答:彈性盒子容器的屬性與應(yīng)用
display:flex/inline-flex
flex-direction
flex-wrap
justify-content
align-items
align-content
flex-flow
彈性盒子子項(xiàng)的屬性與應(yīng)用
order
align-self
flex
flex-grow
flex-shrink
flex-basis
彈性盒子布局
flex居中/T字布局
可動(dòng)態(tài)增加導(dǎo)航欄
等分布局
圣杯布局
流式布局
一、彈性盒子容器的屬性與應(yīng)用
1.1.定義彈性盒子display:flex/inline-flex
在盒模型(box)中剖析了單個(gè)元素的盒模型結(jié)構(gòu)碉哑,那么display則是用來(lái)定義盒子在文檔中的模型結(jié)構(gòu)挚币,比如display:inline表示為內(nèi)聯(lián)元素妆毕,display:block表示為塊級(jí)元素,dispaly:inline-block表示為行級(jí)塊元素笛粘;還可以設(shè)置dispaly:table表示為表格等,而這篇博客是來(lái)剖析CSS3的彈性盒子薪前,flex表示為彈性塊級(jí)盒子关斜,inline-block表示為行級(jí)塊盒子,這兩者的區(qū)別與塊級(jí)元素和行級(jí)塊元素是一樣的痢畜,就是于相鄰元素的排列方式不同。
注:display在CSS屬性中被分類為布局裁着,與float二驰、clear、visibility桶雀、overflow劃分為同一類別的屬性,但是在這個(gè)分類中都是首先基于display的展示行為為基礎(chǔ)矗积,才有浮動(dòng)敞咧,清除浮動(dòng),是否可見(jiàn)休建,溢出處理等狀態(tài)。所以display作為布局的核心功能测砂,除了定義外部的元素與元素之間的排列方式,從CSS2到CSS3更是通過(guò)擴(kuò)展display的參數(shù)由原來(lái)內(nèi)部固定的結(jié)構(gòu)模型擴(kuò)展到了可自定義的結(jié)構(gòu)模型砌些,就是彈性盒子flex。
在彈性盒子中仑荐,原來(lái)的margin,pading,content還有width的內(nèi)部計(jì)算方式都不在基于瀏覽器內(nèi)核默認(rèn)的模型來(lái)計(jì)算,而是通過(guò)與flex相關(guān)的一系列屬性來(lái)定義計(jì)算盒子內(nèi)部項(xiàng)(內(nèi)部元素)的排列布局释漆。這部分CSS內(nèi)容對(duì)應(yīng)著瀏覽器內(nèi)核渲染頁(yè)面時(shí)內(nèi)部調(diào)用的layout()方法∧型迹可以這么來(lái)說(shuō),原來(lái)的layout()直接通過(guò)識(shí)別塊級(jí)元素栈戳、行級(jí)塊元素、行級(jí)元素子檀、表格這四種固定實(shí)現(xiàn)的布局模型直接調(diào)用固定的計(jì)算模型計(jì)算出元素在頁(yè)面中展示的(結(jié)構(gòu))樣式,而CSS3中的flex布局模式則需要瀏覽器內(nèi)核調(diào)用自定義的flex相關(guān)參數(shù)來(lái)展示元素的(結(jié)構(gòu))樣式
第三題:undefined 和null的區(qū)別:
答:目前褂痰,null和undefined基本是同義的症虑,只有一些細(xì)微的差別。
null表示"沒(méi)有對(duì)象"谍憔,即該處不應(yīng)該有值。典型用法是:
(1) 作為函數(shù)的參數(shù)习贫,表示該函數(shù)的參數(shù)不是對(duì)象。
(2) 作為對(duì)象原型鏈的終點(diǎn)颤绕。
Object.getPrototypeOf(Object.prototype)
// null
undefined表示"缺少值",就是此處應(yīng)該有一個(gè)值屋厘,但是還沒(méi)有定義。典型用法是:
(1)變量被聲明了汗洒,但沒(méi)有賦值時(shí)父款,就等于undefined瞻凤。
(2) 調(diào)用函數(shù)時(shí),應(yīng)該提供的參數(shù)沒(méi)有提供阀参,該參數(shù)等于undefined瞻坝。
(3)對(duì)象沒(méi)有賦值的屬性,該屬性的值為undefined所刀。
(4)函數(shù)沒(méi)有返回值時(shí),默認(rèn)返回undefined浮创。
var i;
i // undefined
function f(x){console.log(x)}
f() // undefined
var? o = new Object();
o.p // undefined
var x = f();
x // undefined
第四題:Vue,組件之間的傳通性有哪些方法溜族?
答:. vue父子組件通信
vue父子組件通信可以用Vue.$emit自定義事件來(lái)解決。
// 父組件
<single-address @edit-address="editAddress">
// 子組件
methods: {
editAddress () {
? this.$emit('edit-address', false)
}
}
當(dāng)然也可以使用props方式解決煌抒。
// 父組件
// 子組件
{{ addressitems.partment }}{{ addressitems.address }}
export default {
? props: {
? ? addressitems: Object
? }
}
二. 非父子組件通信
非父子組件通信同樣也可以用Vue.$emit自定義事件來(lái)解決
var bus = new Vue()
// 組件A
bus.$emit('id-selected', 1)
// 組件B
bus.$on('id-selected', function (id) {
console.log(id)
})
三. vue跨組件跨模塊通信
雖然父子組件厕倍,非父子組件間的通信vue都可以有辦法解決,但是如果項(xiàng)目結(jié)構(gòu)復(fù)雜化以后绑青,這樣的自定義事件變多以后代碼難以管理屋群,所以還是建議使用vuex。
接下來(lái)就講一講vuex這個(gè)東西吧芍躏。vuex,官方的說(shuō)法就是Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式对竣。如果之前沒(méi)有接觸過(guò)應(yīng)用狀態(tài)管理這一塊的內(nèi)容的話,可能光看文檔是很難看明白的否纬。按個(gè)人的理解來(lái)說(shuō),vuex最大的作用就是把部分父子組件之間頻繁的通信過(guò)程簡(jiǎn)單化睛驳,所以烙心,對(duì)于一些父子組件通信并不頻繁的情況來(lái)說(shuō)淫茵,并不應(yīng)該使用vuex,當(dāng)然這也意味著匙瘪,如果你對(duì)父子組件之間的通信還不是很明確的話,可以先學(xué)習(xí)一下這一塊的知識(shí)丹喻。
vuex有四個(gè)核心概念,其中state和getters主要是用于數(shù)據(jù)的存儲(chǔ)與輸出驻啤,而mutations和actions是用于提交事件并修改state中的數(shù)據(jù)荐吵。
也是以購(gòu)物車的業(yè)務(wù)來(lái)舉例,首先由于vue的限制先煎,頁(yè)面中所有的數(shù)據(jù)都需要一個(gè)初始化,這樣才能在之后業(yè)務(wù)邏輯中響應(yīng)式地修改數(shù)據(jù)(修改數(shù)據(jù)的同時(shí)變化頁(yè)面內(nèi)容)薯蝎。這里我們可以在vue組件中使用ajax獲取數(shù)據(jù),獲取到的數(shù)據(jù)直接賦給state中的數(shù)據(jù):
// global.Domain.centerUrl是我自己定義的全局變量占锯,這種就可以更方便的管理前端數(shù)據(jù)請(qǐng)求接口的地址了
? ? ? getDataFromBackend () {
? ? ? ? this.$http({
? ? ? ? ? method: 'get',
? ? ? ? ? url: global.Domain.centerUrl + 'order'
? ? ? ? }).then(function (response) {
? ? ? ? ? let res = response.data
? ? ? ? ? // state.order是因?yàn)槲覍?duì)整個(gè)應(yīng)用進(jìn)行了分模塊的設(shè)計(jì),order是我其中的一個(gè)模塊消略,后面會(huì)講如何劃分模塊
? ? ? ? ? // $store是vue實(shí)例的全局屬性,這個(gè)屬性可以直接獲取vuex狀態(tài)樹(shù)中的所有state數(shù)據(jù)
? ? ? ? ? this.$store.state.order.orderitems = res.orderitems
? ? ? ? })
? ? ? }
getters的用法與計(jì)算屬性基本一致却紧,computed會(huì)用的話那這個(gè)也基本就會(huì)用了。
接下來(lái)就是重頭戲mutations了晓殊。mutations原意是突變伤提,這里可以理解為立即修改吧。也就是說(shuō)肿男,mutations可以修改state中的數(shù)據(jù)砚著,但是有一個(gè)限制痴昧,那就是只能同步修改,而不能異步赶撰,你想要按個(gè)定時(shí)器過(guò)2秒鐘修改state,那對(duì)不起了您哪豪娜,不行。但是瘤载,想要異步修改state,也不是不行鸣奔,光靠mutations一個(gè)人是不行的了,還得要靠actions挎狸,而且actions還不能直接操作state,他需要異步提交給mutations锨匆,然后再由mutations同步修改state數(shù)據(jù)。聽(tīng)上去挺麻煩的一件事情啊恐锣,還是直接看代碼吧。
? mutations: {
? ? correctIfcollect (state) {
? ? ? state.ifcollectwrap = true
? ? },
? ? modifyIfcollect (state) {
? ? ? state.ifcollectwrap = false
? ? },
? ? // 收藏成功事件
? ? collectSuccess (state) {
? ? ? state.ifcollect = true
? ? ? state.collectmsg = '收藏成功'
? ? },
? ? // 取消收藏事件
? ? collectCancel (state) {
? ? ? state.ifcollect = false
? ? ? state.collectmsg = '取消收藏'
? ? }
? },
? actions: {
? ? // actions有一個(gè)必要的參數(shù)commit土榴,用于提交事件到mutations中
? ? collectPopup ({commit, state}) {
? ? ? let oTimer = ''
? ? ? clearTimeout(oTimer)
? ? ? if (!state.ifcollect) {
? ? ? ? commit('collectSuccess')
? ? ? ? commit('correctIfcollect')
? ? ? ? oTimer = setTimeout(function () {
? ? ? ? ? commit('modifyIfcollect')
? ? ? ? }, 2000)
? ? ? } else {
? ? ? ? commit('collectCancel')
? ? ? ? commit('correctIfcollect')
? ? ? ? oTimer = setTimeout(function () {
? ? ? ? ? commit('modifyIfcollect')
? ? ? ? }, 2000)
? ? ? }
? ? }
? }
? ? // 假如有數(shù)據(jù)需要從組件傳到actions中時(shí),需要兩個(gè)大括號(hào)学搜,第一個(gè)大括號(hào)放commit或者state這類vuex參數(shù)论衍,而第二個(gè)大括號(hào)放傳進(jìn)來(lái)的參數(shù)
? ? // 這里使用vuex actions調(diào)用了兩個(gè)mutations的方法實(shí)現(xiàn)一個(gè)功能,是因?yàn)榈诙€(gè)函數(shù)中有一個(gè)參數(shù)是需要第一個(gè)函數(shù)提供的
? ? changePos ({commit}, {index}) {
? ? ? commit('changeHandle', index)
? ? ? commit('changePos', index)
? ? }
總的來(lái)說(shuō)坯台,在我看懂了vuex以后,我總是覺(jué)得有一個(gè)vuex來(lái)分擔(dān)一下data的功能那是再好不過(guò)了蜒蕾,這樣不光能夠更好地管理我的應(yīng)用,同時(shí)也能夠提高我.vue單文件的可讀性咪啡。
那么這里就有一個(gè)問(wèn)題了,我們都知道一個(gè)稍微大一點(diǎn)的項(xiàng)目撤摸,那數(shù)據(jù)量都是很多的,如果整個(gè)項(xiàng)目里的數(shù)據(jù)都寫在一個(gè)vuex文件里的話就顯得整個(gè)文件太大太重了准夷,這與我們想要提高文件的可讀性是相悖的。所以我們需要有一個(gè)分模塊的意識(shí)來(lái)管理vuex衫嵌,管理應(yīng)用的狀態(tài)。
而vuex也正好提供了這個(gè)功能(vuex還真的是夠強(qiáng)大)楔绞,在具體使用的過(guò)程中,我會(huì)先把那些需要與其他組件交互的組件中的數(shù)據(jù)都提取出來(lái)放到vuex里面管理墓律,而那些完全沒(méi)有交互的數(shù)據(jù)還是放在組件的data中,例如標(biāo)識(shí)該組件的標(biāo)題數(shù)據(jù)等等耻讽。然后,這里我們就可以用到vuex的模塊管理功能针肥,愉快地把數(shù)據(jù)按照組件之間的功能聯(lián)系來(lái)分離,并把它們拆分到一個(gè)個(gè)小文件中啦具则。
// 這是vuex總的管理文件,將各模塊統(tǒng)一在一起博肋,從而將每一個(gè)分支都連接到vuex這個(gè)總的狀態(tài)樹(shù)上
// 引入vue
import Vue from 'vue'
// 引入vuex
import Vuex from 'vuex'
// 引入應(yīng)用狀態(tài)管理
import goodshandleStore from './goodshandle'
import orderStore from './order'
import addressStore from './address'
import shopcarStore from './shopcar'
import merchantStore from './merchant'
import couponStore from './coupon'
Vue.use(Vuex)
export default new Vuex.Store({
? modules: {
? ? handle: goodshandleStore,
? ? order: orderStore,
? ? address: addressStore,
? ? shopcar: shopcarStore,
? ? merchant: merchantStore,
? ? coupon: couponStore
? }
})