web面試必問的題

1. vue雙向數據綁定原理

vue是採用數據劫持結合發佈-訂閱的方式,通過object.defineProperty()來劫持各個屬性的setter,getter,在數據發生變動時發佈消息給訂閱者,觸發相應的監聽回調來渲染視圖
第一步:
需要observer的數據對象進行遞歸遍歷,包括子屬性對象的屬性,都加上setter,getter,這樣的話,給這個對象的某個值賦值,就會觸發setter,那麼就能監聽到數據變化
簡單來說就是實現一個數據監聽器Observer,它能夠對數據對象的所以屬性進行監聽,如果有變動就可以拿到最新的值並通知訂閱者


第二步:
compile解析模塊指令,講模塊中的變量替換成數據,然後初始化渲染頁面視圖,並將每個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變動,收到通知,更新視圖
簡單來說就是實現一個指令解析器Compile,對每個元素節點的指令進行掃描和解析,替換數據,綁定更新函數
第三步:
Watcher訂閱者時ObserverCompile之間的通訊橋樑,主要做的事情是:
1.在自身實例化時往屬性訂閱器(dep)裏面添加自己
2.自身必須有一個update()方法
3.待屬性變動dep.notice()通知時,能調用自身的update()方法,並觸發Compile中的綁定回調
簡單來說就是實現一個Watcher,作爲Observer和Compile的橋樑,能夠收到每個屬性變動的通知,綁定相應的回調函數,從而更新視圖
第四步:
MVVM作爲數據綁定的入口,整合Observer,Compile和Watcher三者,通過Observer來監聽自己的model數據變化,通過Compile來解析編譯模板指令,最終利用Watcher搭建起Observer和Compile之間的通信橋樑,達到數據變化->視圖更新; 視圖交互變化->數據model變更的雙向綁定效果









MVVM就是實現Vue雙向數據綁定的根本,MVVM本質上是MVC的改進版,即模型-視圖-視圖模型,【模型】指的是後端傳遞的數據。【視圖】指的是所看到的頁面。【視圖模型】MVVM的核心,他是連接view和model的橋樑。它有兩個方向: 一個是將【模型】轉換成【視圖】,即後端傳遞的數據轉換成所看到的頁面:實現方式是:數據綁定。第二個是【視圖】轉化成【模型】,即將所看到的頁面轉換成後端的數據:實現方式是:DOM事件監聽。這兩個方向都實現的話,我們稱之爲數據的雙向綁定

2.vue虛擬dom,diff算法

虛擬DOM就是爲了解決遊覽器性能問題而被設計出來的。

就是用對象來模擬dom元素和嵌套關係,指的就是用js對象的形式,來模擬頁面上的DOM嵌套關係

目的:實現頁面元素的高效更新,避免大量無謂的計算(若一次操作中有10次更新DOM的動作,虛擬DOM不會立即去操作DOM,而是將10次更新的diff內容保存到本地一個JS對象中,最終將這個JS對象一個姓attch到DOM樹上,再進行後續操作)

作用:用來比較兩次DOM結構

web界面由DOM樹(樹的意思就是數據結構)來搭建,當其中一部分發生變化時,其實就時對應某個DOM節點發生了變化

diff算法是作爲DOM的加速器,改進優化了頁面渲染的基礎和性能保障

用js對象表示dom樹結構,用這個樹建立一個真正的dom樹,插入到文檔中,狀態更新,重新構造一棵新樹,兩樹比較差異,把差異應用到真的dom樹上,更新視圖

3. 組件 通訊

1.父傳子
父組件是通過props屬性給子組件通信的
父組件代碼:

<template>
	<div>
		<h2>{
   
   {
   
   msg}}</h2>
		<Son :faMsg="msg"></Son>
	</div>
</template>
	
 <script>
	import Son from "./Son";
	export default {
   
   
		name:"HelloWorld",
		data(){
   
   
			return{
   
   
				msg:"父組件"
			}
		},
		components:{
   
   Son}
	}
 </script>

子組件代碼:

<template>
	<div>
		<h2>{
   
   {
   
   sonMsg}}</h2>
		<p>子組件接收到的內容是:{
   
   {
   
   faMsg}}</p>
	</div>
</template>
	
 <script>
	export default {
   
   
		name:"Son",
		data(){
   
   
			return{
   
   
				sonMsg:"子組件"
			}
		},
		props:['faMsg'], //接收faMsg值
		//還可以這樣,上面的不是很嚴謹
		props:{
   
   
			faMsg:{
   
   
				type:String,
				default:"123"
			}
		}
	}
 </script>

在父組件中給子組件標籤上綁定一個屬性, 屬性上掛載需要傳遞的值
在子組件通過props:[“自定義屬性名”]來接收數據

子傳父:
(1) 在父組件中給子組件標籤綁定一個自定義事件,給這個事件掛載需要調用的方法
(2) 在子組件的方法通過this.$emit(‘自定義事件名’)來調用這個方法

父組件代碼:

<template>
   <div>
     <h2>{
   
   {
   
    msg }}</h2>
     <p>父組件接手到的內容:{
   
   {
   
    username }}</p>
     <son psMsg="我是你爸爸" @transfer="getUser"></son> 
      <!-- 監聽子組件觸發的transfer事件,然後調用getUser方法 -->
   </div>
 </template>
 <script>
 import son from './Son'
 export default {
   
   
   name: 'HelloWorld',
   data () {
   
   
     return {
   
   
       msg: '父組件',
       username:'',
     }
   },
   components:{
   
   son},
   methods:{
   
   
     getUser(msg){
   
   
       this.username= msg
     }
   }
 }
 </script>

子組件代碼:

	 <template>
   <div class="son">
     <p>{
   
   {
   
    sonMsg }}</p>
     <p>子組件接收到內容:{
   
   {
   
    psMsg }}</p>
     <!--<input type="text" v-model="user" @change="setUser">-->
     <button @click="setUser">傳值</button>
   </div>
 </template>
 <script>
 export default {
   
   
   name: "son",
   data(){
   
   
     return {
   
   
       sonMsg:'子組件',
       user:'子傳父的內容'
     }
   },
   props:['psMsg'],
   methods:{
   
   
     setUser:function(){
   
   
       this.$emit('transfer',this.user)//觸發transfer方法,this.user 爲向父組件傳遞的數據
     }
   }
 }
 </script>

兄弟通信: 比如說vuex 就可以說是一個兄弟通信

4. vuex

首先我們要知道Vuex是一個專爲vue.js應用程序開發的狀態管理模式,它由五部分組成:
分別是:state,actions,mutations,getters,modules
在這裏插入圖片描述
vuex的五部分分別是:


  • state:存儲狀態
  • actions:可以包含異步操作
  • getters:類似vue組件中的計算屬性,會對state數據進行計算(會被緩存)
  • mutations:唯一可以對state數據修改的場所
  • modules:模塊化管理倉庫,每個模塊都擁有自己的 state,actions,mutations,getters,modules

Vuex一般用來存儲在vue.js中大量出現的數據,比如說token,我們就可以把token存放在Vuex中,當然購物車也是要用到Vuex的.

數據持久化
問題:存儲在vuex中的狀態,刷新頁面會丟失。
爲了解決刷新頁面數據丟失,纔有了數據持久化。
最簡單的做法就是利用插件 vuex-persistedState
1.安裝
cnpm i vuex-persistedState -S
備註:
-S 是 --save的簡寫,意思是:把插件安裝到dependencies(生成環境依賴)中
-D 是 --save-dev的簡寫,意思是:把插件安裝到devDependencies(開發環境依賴)中
2.使用








import createPersistedState from 'vuex-persistedstate'

const store = new Vuex.Store({
   
   
  state,
  mutations,
  actions,
  getters,
  plugins: [createPersistedState({
   
   
    storage: sessionStorage,
    key: "token"
  })]//會自動保存創建的狀態。刷新還在
})

參數:
storage:存儲方式。(sessionStorage,localStarage) key:定義本地存儲中的key

模塊化管理數據(modules)
1.什麼時候需要用到模塊管理vuex數據

項目龐大,數據信息量特別大的時候,我們可以考慮分模塊形式管理數據,比如user模塊管理用戶信息數據,cart模塊管理購物車數據,shop模塊管理商品信息數據

5. vue-router(路由原理,路由守衛,路由傳參)

路由實現原理:

概念:
通過改變URL,在不重新請求頁面的情況下,更新頁面視圖。
實現方式:
vue-router通過hashHistory interface兩種方式實現前端路由,更新視圖但不重新請求頁面”是前端路由原理的核心之一,目前在瀏覽器環境中這一功能的實現主要有兩種方式:
1.hash ---- 利用URL中的hash(’#’);
2.利用History interface在HTML5中的新增方法




6. vue生命週期

簡單粗暴:
答: 總共分爲8個階段。創建前/後 , 掛載前/後 , 更新前/後 , 銷燬前/後
創建前/後: beforeCreated創建前,vue實例的掛載元素$el和數據對象data都是undefined,還未初始化。在created階段/創建後,vue實例的數據對象data有了,$el還沒有。
掛載前/後: beforeMount掛載前,vue實例的eldata都初始化了,但是還沒有掛載html 到頁面上。在Mounted階段/掛載後,模板中的 HTML 渲染到 HTML 頁面中,此時一般可以做一些 ajax 操作,mounted 只會執行一次。
更新前/後: 當data變化時,會觸發beforeUpdateupdated方法
銷燬前/後:destroy階段/銷燬前,對data的改變不會再觸發週期函數,說明此時vue實列已經解除了事件監聽和dom綁定,但是dom結構依然存在。destroyed階段,組件銷燬
在這裏插入圖片描述





7. 自定義指令,自定義過濾器

8. 自定義組件

9. 常用的指令,修飾符

10. vue2.0和vue3.0的區別

11. keep-alive

概念:
是Vue的內置組件,當它包裹動態組件時,會緩存不活動的組件實例,而不是銷燬它們。
keep-alive是一個抽象組件:它自身不會渲染一個DOM元素,也不會出現的父組件鏈中。
作用:
在組件切換的過程中,把切換出去的組件保留在內存中,防止重複渲染DOM,減少加載事件以及性能消耗,提高用戶體驗性
原理:
created鉤子函數調用時將需要緩存的 VNode 節點保存在 this.cache 中/在 render(頁面渲染) 時,如果VNodename 符合緩存條件(可以用 include 以及 exclude 控制),則會從 this.cache 中取出之前緩存的 VNode實例進行渲染
VNode: 虛擬DOM,其實就是一個JS對象
參數:







  • include - 字符串或者正則表達式。只有匹配的組件會被緩存。
  • exclude - 字符串或正則表達式。然後匹配的組件都不會緩存。
  • max - 數字。最多可以緩存多少組件實例

對生命週期函數變化:
被包含在keep-alive中的組件,會多出來兩個生命週期的鉤子函數,activateddeactiveated
1.activated
在keep-alive組件激活時調用
2.deactivated
在keep-alive組件離開時調用




//正常的生命週期:beforeRouterEnter --> created -->mounted --> updated --> destroyed


//使用keepAlive後生命週期:
//首次進入緩存頁面 :beforeRouterEnter --> created -->mounted --> updated --> destroyed
//再次進入緩存頁面 :beforeRouteEnter --> activated --> deactivated
//注:
//1、這裏的activated非常有用,因爲頁面被緩存時,created,mounted等生命週期均失效,你若想進行一些操作,那麼可以在activated內完成(下面會舉個栗子:列表頁回到上次瀏覽位置)
//2、activated   keep-alive組件激活時調用,該鉤子在服務器端渲染期間不被調用。 
//3、deactivated   keep-alive組件停用時調用,該鉤子在服務端渲染期間不被調用

可以結合Router中的meta,來緩存部分頁面

12. 多環境變量

13. 對axios封裝,(url統一管理,axios請求攔截,響應攔截,函數封裝)

14. element-ui,vant-ui 按需引入

15. sass配置

16. rem , vw/vh 適配

rem適配:
使用vant裏面的遊覽器適配,
Vant 中的樣式默認使用 px 作爲單位,如果需要使用 rem 單位,推薦使用以下兩個工具:

postcss-pxtorem 是一款 postcss 插件,用於將單位轉化爲 rem
lib-flexible用於設置 rem 基準值
安裝 lib-flexiblepostcss-plugin-px2rem
cnpm i lib-flexible postcss-plugin-px2rem --save-dev
配置rem: mian.js 導入



import 'lib-flexible/flexible'; //rem 就可以生效了

配置px–> rem:創建vue.config.js

//可以在此配置的基礎上根據項目需求進行修改。
module.exports = {
   
   
   
    css: {
   
   
        loaderOptions: {
   
   
            postcss: {
   
   
                plugins: [
                    require('postcss-plugin-px2rem')({
   
   
                        rootValue:75, //換算基數, 默認100  ,這樣的話把根標籤的字體規定爲1rem爲50px,這樣就可以從設計稿上量出多少個px直接在代碼中寫多上px了。
                        // unitPrecision: 5, //允許REM單位增長到的十進制數字。
                        //propWhiteList: [],  //默認值是一個空數組,這意味着禁用白名單並啓用所有屬性。
                        // propBlackList: [], //黑名單
                        // exclude: /(page_pc)/i,  //默認false,可以(reg)利用正則表達式排除某些文件夾的方法,例如/(node_module)/ 。如果想把前端UI框架內的px也轉換成rem,請把此屬性設爲默認值
                        exclude: /node_modules/i,
                        // selectorBlackList: ['van-'], //要忽略並保留爲px的選擇器,我們一般不轉換vantui中的大小
                        // ignoreIdentifier: false,  //(boolean/string)忽略單個屬性的方法,啓用ignoreidentifier後,replace將自動設置爲true。
                        // replace: true, // (布爾值)替換包含REM的規則,而不是添加回退。
                        mediaQuery: false,  //(布爾值)允許在媒體查詢中轉換px。
                        minPixelValue: 3 //設置要替換的最小像素值(3px會被轉rem)。 默認 0
                    }),
                ]
            }
        }
    },
}

17. webpack配置(配置跨域,路徑別名,打包分析,cdn引入,去掉console.log,單獨打包第三方模塊,ie兼容,eslint規範,圖片壓縮)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章