1禀综、開發(fā)中常用的指令有哪些
v-model:一般用在表達輸入腰素,很輕松的實現(xiàn)表單控件和數(shù)據(jù)的雙向綁定
v-html: 更新元素的 innerHTML
v-show與v-if: 條件渲染, 注意二者區(qū)別
使用了v-if的時候秧了,如果值為false蹬耘,那么頁面將不會有這個html標簽生成。 v-show則是不管值為true還是false,html元素都會存在,只是CSS中的display顯示或隱藏
v-on : click: 可以簡寫為@click,@綁定一個事件。如果事件觸發(fā)了配乓,就可以指定事件的處理函數(shù)
v-for:基于源數(shù)據(jù)多次渲染元素或模板塊
v-bind: 當表達式的值改變時,將其產(chǎn)生的連帶影響惠毁,響應(yīng)式地作用于 DOM
語法:v-bind:title="msg"簡寫::title="msg"
2犹芹、請詳細說下你對vue生命周期的理解
vue生命周期總共分為8個階段: 創(chuàng)建前/后,載入前/后鞠绰,更新前/后腰埂, 銷毀前/后。
beforeCreate(創(chuàng)建前)vue實例的掛載元素$el和數(shù)據(jù)對象data都是undefined, 還未初始化
created(創(chuàng)建后) 完成了data數(shù)據(jù)初始化,el還未初始化
beforeMount(載入前) vue實例的$el和data都初始化了, 相關(guān)的render函數(shù)首次被調(diào)用蜈膨。實例已完成以下的配置:編譯模板屿笼,把data里面的數(shù)據(jù)和模板生成html。注意此時還沒有掛載html到頁面上翁巍。
mounted(載入后) 在el被新創(chuàng)建的vm.$el替換驴一,并掛載到實例上去之后調(diào)用。實例已完成以下的配置:用上面編譯好的html內(nèi)容替換el屬性指向的DOM對象灶壶。完成模板中的html渲染到html頁面中肝断。此過程中進行ajax交互
beforeUpdate(更新前) 在數(shù)據(jù)更新之前調(diào)用,發(fā)生在虛擬DOM重新渲染和打補丁之前⌒匦福可以在該鉤子中進一步地更改狀態(tài)担扑,不會觸發(fā)附加的重渲染過程。
updated(更新后) 在由于數(shù)據(jù)更改導(dǎo)致的虛擬DOM重新渲染和打補丁之后調(diào)用趣钱。調(diào)用時涌献,組件DOM已經(jīng)更新,所以可以執(zhí)行依賴于DOM的操作羔挡。然而在大多數(shù)情況下洁奈,應(yīng)該避免在此期間更改狀態(tài),因為這可能會導(dǎo)致更新無限循環(huán)绞灼。該鉤子在服務(wù)器端渲染期間不被調(diào)用利术。
beforeDestroy(銷毀前) 在實例銷毀之前調(diào)用。實例仍然完全可用低矮。
destroyed(銷毀后) 在實例銷毀之后調(diào)用印叁。調(diào)用后,所有的事件監(jiān)聽器會被移除军掂,所有的子實例也會被銷毀轮蜕。該鉤子在服務(wù)器端渲染期間不被調(diào)用。
3蝗锥、Vue的雙向數(shù)據(jù)綁定原理是什么
vue.js 是采用數(shù)據(jù)劫持結(jié)合發(fā)布者-訂閱者模式的方式跃洛,通過Object.defineProperty()來劫持各個屬性的setter,getter终议,在數(shù)據(jù)變動時發(fā)布消息給訂閱者汇竭,觸發(fā)相應(yīng)的監(jiān)聽回調(diào)。 具體實現(xiàn)步驟穴张,感興趣的可以看看:
當把一個普通 Javascript 對象傳給 Vue 實例來作為它的 data 選項時细燎,Vue 將遍歷它的屬性,用 Object.defineProperty 都加上 setter和getter 這樣的話皂甘,給這個對象的某個值賦值玻驻,就會觸發(fā)setter,那么就能監(jiān)聽到了數(shù)據(jù)變化
compile解析模板指令偿枕,將模板中的變量替換成數(shù)據(jù)璧瞬,然后初始化渲染頁面視圖,并將每個指令對應(yīng)的節(jié)點綁定更新函數(shù)渐夸,添加監(jiān)聽數(shù)據(jù)的訂閱者嗤锉,一旦數(shù)據(jù)有變動,收到通知捺萌,更新視圖
Watcher訂閱者是Observer和Compile之間通信的橋梁,主要做的事情是: 1、在自身實例化時往屬性訂閱器(dep)里面添加自己 2桃纯、自身必須有一個update()方法 3酷誓、待屬性變動dep.notice()通知時,能調(diào)用自身的update()方法态坦,并觸發(fā)Compile中綁定的回調(diào)盐数,則功成身退。
MVVM作為數(shù)據(jù)綁定的入口伞梯,整合Observer玫氢、Compile和Watcher三者,通過Observer來監(jiān)聽自己的model數(shù)據(jù)變化谜诫,通過Compile來解析編譯模板指令漾峡,最終利用Watcher搭起Observer和Compile之間的通信橋梁,達到數(shù)據(jù)變化 -> 視圖更新喻旷;視圖交互變化(input) -> 數(shù)據(jù)model變更的雙向綁定效果
//vue實現(xiàn)數(shù)據(jù)雙向綁定的原理就是用Object.defineproperty()重新定義(set方法)對象設(shè)置屬性值和(get方法)獲取屬性值的操縱來實現(xiàn)的生逸。
//Object.property()方法的解釋:Object.property(參數(shù)1,參數(shù)2且预,參數(shù)3) 返回值為該對象obj
//其中參數(shù)1為該對象(obj)槽袄,參數(shù)2為要定義或修改的對象的屬性名,參數(shù)3為屬性描述符锋谐,屬性描述符是一個對象遍尺,主要有兩種形式:數(shù)據(jù)描述符和存取描述符。這兩種對象只能選擇一種使用涮拗,不能混合使用乾戏。而get和set屬于存取描述符對象的屬性。
//這個方法會直接在一個對象上定義一個新屬性或者修改對象上的現(xiàn)有屬性多搀,并返回該對象歧蕉。
var model = {
message: ""
};
var models = myapp.querySelectorAll("[v-model=message]");
for (var i = 0; i < models.length; i++) {
models[i].onkeyup = function() {
model[this.getAttribute("v-model")] = this.value;
}
}
// 觀察者模式 / 鉤子函數(shù)
// defineProperty 來定義一個對象的某個屬性
Object.defineProperty(model, "message", {
set: function(newValue) {
var binds = myapp.querySelectorAll("[v-bind=message]");
for (var i = 0; i < binds.length; i++) {
binds[i].innerHTML = newValue;
};
var models = myapp.querySelectorAll("[v-model=message]");
for (var i = 0; i < models.length; i++) {
models[i].value = newValue;
};
this.value = newValue;
},
get: function() {
return this.value;
}
})
4、vue-router 有哪幾種導(dǎo)航守衛(wèi)?
全局守衛(wèi)
路由獨享守衛(wèi)
路由組件內(nèi)的守衛(wèi)
vue-router全局有三個守衛(wèi):
router.beforeEach 全局前置守衛(wèi) 進入路由之前
router.beforeResolve 全局解析守衛(wèi)(2.5.0+) 在beforeRouteEnter調(diào)用之后調(diào)用
router.afterEach 全局后置鉤子 進入路由之后
使用方法:
// main.js 入口文件
import router from './router'; // 引入路由
router.beforeEach((to, from, next) => {
next();
});
router.beforeResolve((to, from, next) => {
next();
});
router.afterEach((to, from) => {
console.log('afterEach 全局后置鉤子');
});
如果你不想全局配置守衛(wèi)的話康铭,你可以為某些路由單獨配置守衛(wèi):
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// 參數(shù)用法什么的都一樣,調(diào)用順序在全局前置守衛(wèi)后面惯退,所以不會被全局守衛(wèi)覆蓋
// ...
} } ] })
beforeRouteEnter 進入路由前, 在路由獨享守衛(wèi)后調(diào)用不能獲取組件實例this,組件實例還沒被創(chuàng)建
beforeRouteUpdate (2.2) 路由復(fù)用同一個組件時, 在當前路由改變从藤,但是該組件被復(fù)用時調(diào)用 可以訪問組件實例this
beforeRouteLeave 離開當前路由時, 導(dǎo)航離開該組件的對應(yīng)路由時調(diào)用催跪,可以訪問組件實例this
5、Vue的路由實現(xiàn):hash模式 和 history模式
在瀏覽器中符號?“#”夷野,#以及#后面的字符稱之為hash懊蒸,用window.location.hash讀取悯搔;
特點:hash雖然在URL中骑丸,但不被包括在HTTP請求中;用來指導(dǎo)瀏覽器動作,對服務(wù)端安全無用通危,hash不會重加載頁面铸豁。
hash模式下,僅hash符號之前的內(nèi)容會被包含在請求中菊碟,如http://www.xiaogangzai.com节芥,因此對于后端來說,即使沒有做到對路由的全覆蓋逆害,也不會返回404錯誤头镊。
history采用HTML5的新特性;且提供了兩個新方法:pushState()魄幕,replaceState()可以對瀏覽器歷史記錄棧進行修改相艇,以及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依賴的頁面膘盖。
6胧弛、組件之間的傳值通信
組件之間通訊分為三種: 父傳子、子傳父侠畔、兄弟組件之間的通訊
1. 父組件給子組件傳值
使用props结缚,父組件可以使用props向子組件傳遞數(shù)據(jù)。
父組件vue模板father.vue:
import child from './child.vue';
export default {
components: {
child
},
data () {
return {
message: 'father message';
}
}
}
子組件vue模板child.vue:
export default {
props: {
msg: {
type: String,
required: true
}
}
}
2. 子組件向父組件通信
父組件向子組件傳遞事件方法软棺,子組件通過$emit觸發(fā)事件红竭,回調(diào)給父組件。
父組件vue模板father.vue:
import child from './child.vue';
export default {
components: {
child
},
methods: {
func (msg) {
console.log(msg);
}
}
}
子組件vue模板child.vue:
點我
export default {
props: {
msg: {
type: String,
required: true
}
},
methods () {
handleClick () {
//........
this.$emit('msgFunc');
}
}
}
vue2中廢棄了$dispatch和$broadcast廣播和分發(fā)事件的方法喘落。父子組件中可以用props和$emit()茵宪。如何實現(xiàn)非父子組件間的通信,可以通過實例一個vue實例Bus作為媒介瘦棋,要相互通信的兄弟組件之中稀火,都引入Bus,然后通過分別調(diào)用Bus事件觸發(fā)和監(jiān)聽來實現(xiàn)通信和參數(shù)傳遞赌朋。Bus.js可以是這樣:
import Vue from 'vue'
export default new Vue()
在需要通信的組件都引入Bus.js:
子組件傳給兄弟組件
import Bus from '../common/js/bus.js'
export default{
methods: {
toBus () {
Bus.$emit('on', '來自兄弟組件')
}
}
}
另一個組件也import Bus.js在鉤子函數(shù)中監(jiān)聽on事件
import Bus from '../common/js/bus.js'
export default {
data() {
return {
message: ''
}
},
mounted() {
Bus.$on('on', (msg) => {
this.message = msg
})
}
}
7凰狞、Vue與Angular以及React的區(qū)別篇裁?
版本在不斷更新,以下的區(qū)別有可能不是很正確赡若。而且工作中只用到vue茴恰,對angular和react不怎么熟
Vue與AngularJS的區(qū)別
Angular采用TypeScript開發(fā), 而Vue可以使用javascript也可以使用TypeScript
AngularJS依賴對數(shù)據(jù)做臟檢查,所以Watcher越多越慢斩熊;Vue.js使用基于依賴追蹤的觀察并且使用異步隊列更新,所有的數(shù)據(jù)都是獨立觸發(fā)的伐庭。
AngularJS社區(qū)完善, Vue的學(xué)習(xí)成本較小
Vue與React的區(qū)別
vue組件分為全局注冊和局部注冊粉渠,在react中都是通過import相應(yīng)組件,然后模版中引用圾另;
props是可以動態(tài)變化的霸株,子組件也實時更新,在react中官方建議props要像純函數(shù)那樣集乔,輸入輸出一致對應(yīng)去件,而且不太建議通過props來更改視圖;
子組件一般要顯示地調(diào)用props選項來聲明它期待獲得的數(shù)據(jù)扰路。而在react中不必需尤溜,另兩者都有props校驗機制;
每個Vue實例都實現(xiàn)了事件接口汗唱,方便父子組件通信宫莱,小型項目中不需要引入狀態(tài)管理機制,而react必需自己實現(xiàn)哩罪;
使用插槽分發(fā)內(nèi)容授霸,使得可以混合父組件的內(nèi)容與子組件自己的模板;
多了指令系統(tǒng)际插,讓模版可以實現(xiàn)更豐富的功能碘耳,而React只能使用JSX語法;
Vue增加的語法糖computed和watch框弛,而在React中需要自己寫一套邏輯來實現(xiàn)辛辨;
react的思路是all in js,通過js來生成html功咒,所以設(shè)計了jsx愉阎,還有通過js來操作css,社區(qū)的styled-component力奋、jss等榜旦;而 vue是把html,css景殷,js組合到一起溅呢,用各自的處理方式澡屡,vue有單文件組件,可以把html咐旧、css驶鹉、js寫到一個文件中,html提供了模板引擎來處理铣墨。
react做的事情很少室埋,很多都交給社區(qū)去做,vue很多東西都是內(nèi)置的伊约,寫起來確實方便一些姚淆, 比如 redux的combineReducer就對應(yīng)vuex的modules, 比如reselect就對應(yīng)vuex的getter和vue組件的computed屡律, vuex的mutation是直接改變的原始數(shù)據(jù)腌逢,而redux的reducer是返回一個全新的state,所以redux結(jié)合immutable來優(yōu)化性能超埋,vue不需要搏讶。
react是整體的思路的就是函數(shù)式,所以推崇純組件霍殴,數(shù)據(jù)不可變媒惕,單向數(shù)據(jù)流,當然需要雙向的地方也可以做到来庭,比如結(jié)合redux-form吓笙,組件的橫向拆分一般是通過高階組件。而vue是數(shù)據(jù)可變的巾腕,雙向綁定面睛,聲明式的寫法,vue組件的橫向拆分很多情況下用mixin尊搬。
8叁鉴、vuex是什么?怎么使用佛寿?哪種功能場景使用它幌墓?
vuex 就是一個倉庫,倉庫里放了很多對象冀泻。其中 state 就是數(shù)據(jù)源存放地常侣,對應(yīng)于一般 vue 對象里面的 data
state 里面存放的數(shù)據(jù)是響應(yīng)式的,vue 組件從 store 讀取數(shù)據(jù)弹渔,若是 store 中的數(shù)據(jù)發(fā)生改變胳施,依賴這相數(shù)據(jù)的組件也會發(fā)生更新
它通過 mapState 把全局的 state 和 getters 映射到當前組件的 computed 計算屬性
Vuex有5種屬性: 分別是 state、getter肢专、mutation舞肆、action焦辅、module;
state
Vuex 使用單一狀態(tài)樹,即每個應(yīng)用將僅僅包含一個store 實例,但單一狀態(tài)樹和模塊化并不沖突椿胯。存放的數(shù)據(jù)狀態(tài)筷登,不可以直接修改里面的數(shù)據(jù)。
mutations
mutations定義的方法動態(tài)修改Vuex 的 store 中的狀態(tài)或數(shù)據(jù)哩盲。
getters
類似vue的計算屬性前方,主要用來過濾一些數(shù)據(jù)。
action
actions可以理解為通過將mutations里面處里數(shù)據(jù)的方法變成可異步的處理數(shù)據(jù)的方法廉油,簡單的說就是異步操作數(shù)據(jù)镣丑。view 層通過store.dispath來分發(fā) action。
vuex 一般用于中大型 web 單頁應(yīng)用中對應(yīng)用的狀態(tài)進行管理娱两,對于一些組件間關(guān)系較為簡單的小型應(yīng)用,使用 vuex 的必要性不是很大金吗,因為完全可以用組件 prop 屬性或者事件來完成父子組件之間的通信十兢,vuex 更多地用于解決跨組件通信以及作為數(shù)據(jù)中心集中式存儲數(shù)據(jù)。
使用Vuex解決非父子組件之間通信問題
vuex 是通過將 state 作為數(shù)據(jù)中心摇庙、各個組件共享 state 實現(xiàn)跨組件通信的旱物,此時的數(shù)據(jù)完全獨立于組件,因此將組件間共享的數(shù)據(jù)置于 State 中能有效解決多層級組件嵌套的跨組件通信問題卫袒。
vuex 作為數(shù)據(jù)存儲中心
vuex 的 State 在單頁應(yīng)用的開發(fā)中本身具有一個“數(shù)據(jù)庫”的作用宵呛,可以將組件中用到的數(shù)據(jù)存儲在 State 中,并在 Action 中封裝數(shù)據(jù)讀寫的邏輯夕凝。這時候存在一個問題宝穗,一般什么樣的數(shù)據(jù)會放在 State 中呢? 目前主要有兩種數(shù)據(jù)會使用 vuex 進行管理:
1码秉、組件之間全局共享的數(shù)據(jù)
2逮矛、通過后端異步請求的數(shù)據(jù) 比如做加入購物車、登錄狀態(tài)等都可以使用Vuex來管理數(shù)據(jù)狀態(tài)转砖。