1、vue中 key
值的作用
key的特殊性主要用在Vue的虛擬DOM算法,再新舊nodes對比時辨別VNodes。如果不使用key,Vue會使用一種最大限度減少動態元素並且盡可能的嘗試修復/再利用相同類型元素的算法。使用key,它會基於key的變化重新排列元素順序,並且會移除key不存在的元素。
有相同父元素的子元素必須有獨特的key。重復的key會造成渲染錯誤。
最常見的用例是結合 v-for:
1 <ul> 2 <li v-for="item in items" :key="item.id">... 3 </li> 4 </ul>
它也可以用於強制替換元素/組件而不是重復使用它。當你遇到如下場景時它可能會很有用:
完整地觸發組件的生命周期鈎子 觸發過渡
1 <transition> 2 <span :key="text">{{ text }}</span> 3 </transition>
當 text 發生改變時,<span> 會隨時被更新,因此會觸發過渡。
2.vue中子組件調用父組件的方法
子組件調用父組件的方法可以使用this.$emit()
第一種方法是在子組件里用$emit
向父組件觸發一個事件,父組件監聽這個事件就行了。
$emit
父組件
1 <template> 2 <div> 3 <child @fatherMethod="fatherMethodOther"></child> 4 </div> 5 </template> 6 <script> 7 import child from './child'; 8 export default { 9 components: { 10 child 11 }, 12 methods: { 13 fatherMethodOther(str) { 14 console.log(str); 15 } 16 } 17 }; 18 </script>
子組件
1 <template> 2 <div> 3 <button @click="childMethod">點擊</button> 4 </div> 5 </template> 6 <script> 7 export default { 8 methods: { 9 childMethod() { 10 this.$emit('fatherMethod', 'hello'); 11 } 12 } 13 }; 14 </script>
第二種方法是直接在子組件中通過this.$parent.event來調用父組件的方法
$parent
父組件
1 <template> 2 <div> 3 <child></child> 4 </div> 5 </template> 6 <script> 7 import child from './child'; 8 export default { 9 components: { 10 child 11 }, 12 methods: { 13 fatherMethod(str) { 14 console.log(str); 15 } 16 } 17 }; 18 </script>
子組件
1 <template> 2 <div> 3 <button @click="childMethod">點擊</button> 4 </div> 5 </template> 6 <script> 7 export default { 8 methods: { 9 childMethod() { 10 this.$parent.fatherMethod('hello'); 11 } 12 } 13 }; 14 </script>
-
vue等單頁面應用及其優點
優點:
1.具有桌面應用的及時性,網站的可移植性和可訪問性。
2.用戶體驗好,塊,內容改變不需要重新加載整個頁面
3.基於上面一點,SPA相對對服務器壓力小。
4.良好的前后端分離。SPA和RESTful架構一起使用,后端不再負責模板渲染、
輸出頁面工作,web前端和各種移動終端地位對等,后端API通用化。
5.同一套后端程序代碼,不用修改就可以用於Web界面、手機、平板等多種客戶端;缺點:
1、不利於SEO。(如果你看中SEO,那就不應該在頁面上使用JavaScript,
你應該使用網站而不是Web應用)
2、初次加載耗時相對增多。
3、導航不可用,如果一定要導航需要自行實現前進、后退。4.vue.js的兩個核心是什么?
數據驅動和組件化。
5.vue的雙向綁定的原理是什么?
vue數據雙向綁定是通過數據劫持結合發布者-訂閱者模式的方式來實現的。具體實現過程:
我們已經知道實現數據的雙向綁定,首先要對數據進行劫持監聽,所以我們需要設置一個監聽器Observer,用來監聽所有屬性。如果屬性發上變化了,就需要告訴訂閱者Watcher看是否需要更新。因為訂閱者是有很多個,所以我們需要有一個消息訂閱器Dep來專門收集這些訂閱者,然后在監聽器Observer和訂閱者Watcher之間進行統一管理的。接着,我們還需要有一個指令解析器Compile,對每個節點元素進行掃描和解析,將相關指令對應初始化成一個訂閱者Watcher,並替換模板數據或者綁定相應的函數,此時當訂閱者Watcher接收到相應屬性的變化,就會執行對應的更新函數,從而更新視圖。因此接下去我們執行以下3個步驟,實現數據的雙向綁定:
1.實現一個監聽器Observer,用來劫持並監聽所有屬性,如果有變動的,就通知訂閱者。
2.實現一個訂閱者Watcher,可以收到屬性的變化通知並執行相應的函數,從而更新視圖。
3.實現一個解析器Compile,可以掃描和解析每個節點的相關指令,並根據初始化模板數據以及初始化相應的訂閱器。
流程圖如下:
二. v-show和v-if指令的共同點和不同點?
-
v-show指令是通過修改元素的display的css屬性達到讓其顯示或者隱藏
-
v-if指令是直接銷毀和重建DOM達到讓元素顯示和隱藏的效果
-
(注意:v-if 可以實現組件的重新渲染)
三. 如何讓CSS只在當前組件中起作用?
將當前組件<style>修改為<style scoped>
四. <keep-alive></keep-alive>的作用是什么?
<keep-alive></keep-alive>
包裹動態組件時,會緩存不活動的組件實例,主要用於保留組件狀態或避免重新渲染。
對列表組件使用<keep-alive></keep-alive>
進行緩存, 這樣用戶每次返回列表的時候,都能從緩存中快速渲染,而不是重新渲染
五. Vue中引入組件的步驟?
六.請列舉出3個Vue中常用的生命周期鈎子函數?
vue的生命周期分為8個階段,創建前/后,載入前/后,更新前/后,銷毀前/后。
第一次頁面加載需要beforeCreate,created,beforeMount,mounted四個鈎子函數。
1) beforeCreate---創建前
組件實例被創建,組件屬性計算之前,數據對象data都為undefined,未初始化。
2)created---創建后
組件實例創建完成,屬性已經綁定數據對象data已存在,但DOM未生成,$el未存在。
3)beforeMount---掛載前
vue實例的$el和data都已初始化,掛載之前為虛擬的dom節點,data.message未替換。
4)mounted---掛載后
vue實例掛載完成,data.message替換,ajax請求等一系列操作。
5)beforeUpdate---更新前
當data發生變化,會觸發此方法。
6)updated---更新后l
當data發生變化,會觸發此方法。
7)beforeDestory--銷毀前
組件銷毀前調用。
8)destoryed---銷毀后
組件銷毀后調用,對data的改變不會再觸發周期函數,vue實例已解除事件監聽和dom綁定,但dom結構依然存在。
七.請簡述下Vuex的原理和使用方法
數據單向流動
一個應用可以看作是由上面三部分組成: View, Actions,State,
數據的流動也是從View => Actions => State =>View 以此達到數據的單向流動.
但是項目較大的, 組件嵌套過多的時候, 多組件共享同一個State會在數據傳遞時出現很多問題
.Vuex就是為了解決這些問題而產生的.
Vuex可以被看作項目中所有組件的數據中心,我們將所有組件中共享的State抽離出來,
任何組件都可以訪問和操作我們的數據中心
Vuex的組成:一個實例化的Vuex.Store由state, mutations和actions三個屬性組成:
1. state中保存着共有數據
2. 改變state中的數據有且只有通過mutations中的方法,且mutations中的方法必須是同步的
3. 如果要寫異步的方法,需要些在actions中, 並通過commit到mutations中進行state中數據的更改.
八.為什么v-if和v-for不能連用?
-
v-for優先級高於v-if,如果連在一起使用的話會把v-if給每一個元素都添加上,
重復運行於每一個v-for循環中,會造成性能浪費
-
可以將v-if寫在v-for的外層
九.定義vue-router的動態路由?怎么獲取傳過來的動態參數?
設置:在router目錄下的index.js文件中,對path屬性加上/:id
獲取:使用router對象的params.id
十.v-for中為什么要用key
因為vue組件高度復用,增加Key可以標識組件的唯一性,key的作用主要是為了高效的更新虛擬DOM,
-
無key時,會存在“就地復用”的問題。(同一組件標簽相同,key相同就會復用)
-
有key時,只需移動無需重新創建dom。
十一.Vue中v-html會導致那些問題?
-
-
但是有的時候我們需要渲染的html片段中有插值表達式,或者按照Vue模板語法給dom元素綁定了事件。
-
在單文件組件里,scoped 的樣式不會應用在 v-html 內部,因為那部分 HTML 沒有被 Vue 的模板編譯器處理。如果你希望針對 v-html 的內容設置帶作用域的 CSS,你可以替換為 CSS Modules 或用一個額外的全局 <style>元素手動設置類似 BEM 的作用域策略。
-
后台返回的html片段,以及css樣式和js,但是返回的js是不執行的,因為瀏覽器在渲染的時候並沒有將js渲染,這時要在$nextTick中動態創建script標簽並插入
十二.Vue組件如何通信?
https://www.cnblogs.com/fundebug/p/10884896.html
十三.什么是作用域插槽?
插槽可以控制html模板的顯示與不顯示。作用域插槽其實就是帶數據的插槽。
原來父組件可以通過綁定數據傳遞給子組件。作用域插槽就可以通過子組件綁定數據傳遞給父組件。
十四.vue-router有哪幾種路由守衛?
路由守衛為: 全局守衛:beforeEach 后置守衛:afterEach 全局解析守衛:beforeResolve 路由獨享守衛:beforeEnter
十五.組件中的data為什么是一個函數?
在 new Vue()
中,data
是可以作為一個對象進行操作的,然而在 component
中,data
只能以函數的形式存在,不能直接將對象賦值給它。
當data選項是一個函數的時候,每個實例可以維護一份被返回對象的獨立的拷貝,這樣各個實例中的data不會相互影響,是獨立的。
vue核心知識——vuex
十六.不用Vuex會帶來什么問題?
一、可維護性會下降,你要想修改數據,你得維護三個地方
二、可讀性會下降,因為一個組件里的數據,你根本就看不出來是從哪來的
三、增加耦合,大量的上傳派發,會讓耦合性大大的增加,本來Vue用Component就是為了減少耦合,
現在這么用,和組件化的初衷相背。
1.vuex有哪幾種屬性?
有五種,分別是 State、 Getter、Mutation 、Action、 Module。
2、vuex的State特性是?
一、Vuex就是一個倉庫,倉庫里面放了很多對象。其中state就是數據源存放地,對應於與一般Vue對象里面的data 二、state里面存放的數據是響應式的,Vue組件從store中讀取數據,若是store中的數據發生改變,依賴這個數據的組件也會發生更新 三、它通過mapState把全局的 state 和 getters 映射到當前組件的 computed 計算屬性中
3、vuex的Getter特性是?
一、getters 可以對State進行計算操作,它就是Store的計算屬性 二、 雖然在組件內也可以做計算屬性,但是getters 可以在多組件之間復用 三、 如果一個狀態只在一個組件內使用,是可以不用getters
4、vuex的Mutation特性是?
一、Action 類似於 mutation,不同在於: 二、Action 提交的是 mutation,而不是直接變更狀態。 三、Action 可以包含任意異步操作
5、Vue.js中ajax請求代碼寫在組件的methods中還是vuex的actions中?
一、如果請求來的數據是不是要被其他組件公用,僅僅在請求的組件內使用,就不需要放入vuex 的state里。 二、如果被其他地方復用,這個很大幾率上是需要的,如果需要,請將請求放入action里,方便復用,並包裝成promise返回,在調用處用async await處理返回的數據。如果不要復用這個請求,那么直接寫在vue文件里很方便。
十七.Ajax請求放在那個生命周期中?
答案:mounted
vue本身不支持發送AJAX請求,需要使用vue-resource、axios等插件實現
等到異步渲染開啟的時候,created 就可能被中途打斷,中斷之后渲染又要重做一遍,想一想,在 created 中做ajax調用,代碼里看到只有調用一次,但是實際上可能調用 N 多次,這明顯不合適。 相反,若把發ajax 放在 mounted,因為 mounted 在第二階段,所以絕對不會多次重復調用,這才是ajax合適的位置.
十八.v-model中的實現原理級如何自定義v-model?
VUE中的v-model可以實現雙向綁定,但是原理是什么呢?往下看看吧
根據官方文檔的解釋,v-model其實是一個語法糖,它會自動的在元素或者組件上面解析為 :value="" 和 @input="", 就像下面這樣
1 // 標准寫法 2 <input v-model="name"> 3 4 // 等價於 5 <input :value="name" @input="name = $event.target.value"> 6 7 // 在組件上面時 8 <div :value="name" @input="name = $event"></div>
1.當在input輸入框輸入內容時,會自動的觸發input事件,更新綁定的name值。
2.當name的值通過JavaScript改變時,會更新input的value值
根據上面的原理,vue就通過v-model實現雙向數據綁定
看了前面的解釋,對於v-model有了一定的理解。下面我們就來實現自己組件上面的v-model吧
需求:實現一個簡單的點擊按鈕,每次點擊都自動的給綁定值price加100。 組件名為 AddPrice.vue
1 // AddPrice.vue 2 // 通過props接受綁定的value參數 3 <template> 4 <div @click="$emit('input',value + 100 )">點擊加錢<div> 5 </template> 6 7 <script> 8 export default { 9 props: ['value'] 10 } 11 12 </script> 13 14 // 在父組件中調用 15 <add-price v-model="price"></add-price>
組件中使用props接受傳入的參數值value, 組件點擊事件觸發並 使用$emit調用父組件上的input事件,實現了自定義的雙向綁定
十九.響應式數據的原理是什么?
1、聲明式
只需要聲明在哪里where,做什么what,而無需關系如何實現how
1 //此map方法就是,聲明式的,只告訴map要實現獲取2倍,然后map具體怎么實現不關心 2 var arr = [1,2,3,4]; 3 var newArr = arr.map((item,index)=>{ 4 return item*2; 5 })
2、命令式
需要以具體的代碼表達在哪里where,做什么what,以及如何實現how
1 //forEach就是命令式,會具體操作數組,還有如何得到結果push 2 var arr = [1,2,3,4]; 3 var newArr = []; 4 arr.forEach((item,index)=>{ 5 newArr.push(item*2); 6 })
聲明式的理解:
1)DOM狀態只是數據狀態的一種映射
2)所有的邏輯盡可能在狀態的層面去進行
3)當狀態變化了,View會被框架自動更新到合理的狀態
3、響應式數據原理
vue響應式的核心就是Object.defindProperty
作用:直接在一個對象上定義一個新的屬性,或者修改一個對象的現有屬性
語法:Object.definProperty(obj,prop,descriptor)
參數:obj要在其上定義屬性的對象,prop要定義的或要修改的屬性的名稱,descriptor將被定義或修改的屬性描述符
數據描述
configurable:是否可以刪除屬性,默認false
enumberable:此屬性是否可以被枚舉,默認false
value: 該屬性對應的值,默認undefined
writable: 屬性的值是否可以被重寫,默認false
訪問器描述
getter:是一種獲得屬性值的方法
setter:是一種設置屬性值的方法
1 //數據劫持,轉成getter和setter 2 function observer(obj){ 3 Object.keys(obj).forEach((item)=>{ 4 defineReactive(obj,item,obj[item]) 5 }) 6 } 7 8 function defineReactive(obj,key,value){ 9 Object.defineProperty(obj,key,{ 10 enumerable:true, 11 configurable:true, 12 get(){ 13 return value; 14 }, 15 set(newValue){ 16 if(value == newValue){return} 17 //value相當於是一個公用的存儲空間,把最新的值存進去;訪問也是訪問這里面的最新的值 18 value=newValue; 19 //此處還會放一些其他復雜的操作,收集依賴,通知變化等 20 } 21 }) 22 }
vue響應式原理理解:
1、把一個普通的js對象傳給Vue實例的data選項對象
2、Vue將遍歷此對象的所有的屬性,並使用Object.defineProperty把這些屬性全部轉換為getter/setter
3、Vue內部會對數據進行劫持操作,進而追蹤依賴,在屬性被訪問和修改時通知變化
二十.Vue中是如何檢查數組變化?
1.使用函數劫持的方式,重寫了數組的方法 2.vue 將 data 中的數據,進行了原型鏈重寫,指向了自己定義的數組原型方法,這樣當調用數組 api 的時候,可以通知依賴更新,如果數組中包含着引用類型,則會對數組中的引用類型再次進行監控。
二十一.Vue中Computed的特點?
在computed中,可以定義一些屬性,這些屬性,叫做計算屬性。計算屬性的本質就是一個方法,只不過,我們在使用這些計算屬性的時候,是把它們的名稱,直接當做屬性來使用,並不會把計算屬性當做方法來使用。
三個注意事項:
一、計算屬性在引用的時候,一定不要加()去調用,直接把它當作普通的屬性去使用就好了;
二、只要計算屬性這個function內部所用到的data中的數據發生了變化,就會立即重新計算這個計算屬性的值;
三、計算屬性的求值結果,會被緩存起來,方便下次繼續使用;如果計算屬性方法中,所依賴的任何數據,都沒有發生過變化,則不會重新對計算屬性求值。