博客 / 詳情

返回

某知名it培訓班前端三階段vue相關面試題

1. Vue 的核心是什麼?

Vue 的核心主要包含兩點:

  • 數據驅動(Data-Driven)​:視圖由數據狀態決定,數據變更自動更新 DOM,無需手動操作 DOM;
  • 組件化(Component-Based)​:將頁面拆分為獨立、可複用的組件,降低耦合度,提升開發效率;
  • 補充:核心還包括響應式系統、虛擬 DOM 等底層支撐能力。

2. 請簡述你對 Vue 的理解

Vue 是一套​漸進式 JavaScript 框架​,核心定位是“漸進式”——可以按需使用核心功能(如響應式、組件),也可結合路由(Vue Router)、狀態管理(Vuex/Pinia)等生態擴展複雜應用;

  • 設計理念:輕量、易用、高效,兼顧開發體驗和運行性能;
  • 核心特性:響應式數據綁定、組件化、指令系統、虛擬 DOM、生命週期等;
  • 應用場景:從簡單的表單頁面到複雜的單頁應用(SPA)均可覆蓋,是前端主流框架之一。

3. 請簡述 Vue 的單向數據流

Vue 的單向數據流核心規則:​數據只能從父組件流向子組件,子組件不能直接修改父組件傳遞的 props​;

  • 具體表現:

    • 父組件通過 props 向子組件傳值,子組件只讀 props,不能直接修改;
    • 若子組件需修改數據,需通過觸發父組件的自定義事件,由父組件修改源數據,再反向更新子組件 props;
  • 目的:保證數據流向可追溯,避免多個組件隨意修改數據導致狀態混亂,符合“單向綁定”的設計思想。

4. Vue 常用的修飾符有哪些

Vue 的修飾符按用途可分為三類,核心常用如下:

類型 常用修飾符 作用舉例
事件修飾符 .stop、.prevent、.once .stop 阻止事件冒泡,.prevent 阻止默認行為,.once 只觸發一次
按鍵修飾符 .enter、.esc、.tab 監聽特定按鍵觸發事件(如 @keyup.enter)
表單修飾符 .trim、.number、.lazy .trim 去除輸入首尾空格,.number 轉為數字,.lazy 失去焦點後更新數據
鼠標修飾符 .left、.right、.middle 監聽鼠標特定按鍵(左鍵/右鍵/中鍵)

5. v-text 與 {{}}的區別

兩者均用於渲染文本,核心區別:

  • {{}}(插值表達式)​:

    • 可嵌入 HTML 標籤內(如 <div>姓名:{{name}}</div>);
    • 存在“閃爍問題”(頁面加載時可能先顯示 {{name}} 再渲染值,可通過 v-cloak 解決);
    • 支持簡單表達式(如 {{age + 1}});
  • v-text​:

    • 是指令,需直接綁定在標籤上(如 <div v-text="name"></div>);
    • 無閃爍問題,覆蓋標籤內所有內容(包括子節點);
    • 不支持複雜表達式,僅接收變量/簡單值;
  • 補充:兩者均會轉義 HTML(若需渲染 HTML 用 v-html)。

6. v-on 可以綁定多個方法嗎?

可以,有兩種實現方式:

  • 方式 1:綁定一個方法數組(Vue 2.4+ 支持)

    <button @click="[handleClick1, handleClick2]()">點擊觸發多個方法</button>
  • 方式 2:綁定一個統一方法,內部調用多個子方法

    <button @click="handleAll">點擊觸發多個方法</button>
    <script>
    export default {
      methods: {
        handleAll() {
          this.handleClick1();
          this.handleClick2();
        },
        handleClick1() { /* 邏輯1 */ },
        handleClick2() { /* 邏輯2 */ }
      }
    }
    </script>
  • 注意:數組方式中方法需加 () 執行,否則僅定義不觸發。

7. Vue 循環的 key 作用

key 是 Vue 列表渲染的核心屬性,作用:

  • 唯一標識節點​:Vue 根據 key 判斷節點是否為同一節點,避免複用錯誤(如輸入框值錯亂);
  • 提升更新效率​:當列表數據變化時,Vue 通過 key 精準定位需要更新的節點,而非重新渲染整個列表;
  • 注意:

    • key 需用唯一值(如 id),避免用 index(index 會隨數據順序變化,失去標識意義);
    • 無 key 時 Vue 會採用“就地更新”策略,可能導致 DOM 複用異常。

8. 什麼是計算屬性?

計算屬性(computed)是 Vue 用於處理派生數據的特性,基於依賴數據動態計算值:

  • 核心特性:

    • 緩存性​:依賴數據不變時,多次訪問計算屬性只會執行一次計算,提升性能;
    • 響應式​:依賴數據變化時,計算屬性自動重新計算並更新視圖;
    • 支持 get/set(默認 get,set 可手動修改依賴數據);
  • 示例:

    <script>
    export default {
      data() {
        return { a: 1, b: 2 };
      },
      computed: {
        sum() { // 只讀計算屬性
          return this.a + this.b;
        },
        fullName: { // 可讀寫計算屬性
          get() { return this.firstName + ' ' + this.lastName; },
          set(val) { const [first, last] = val.split(' '); this.firstName = first; this.lastName = last; }
        }
      }
    }
    </script>

9. Vue 單頁面(SPA)的優缺點

優點 缺點
1. 無頁面刷新,體驗接近原生 App 1. 首屏加載慢(需加載整包 JS/CSS)
2. 組件化複用性高 2. SEO 不友好(頁面內容動態渲染)
3. 前後端分離,開發效率高 3. 路由切換需手動處理緩存/滾動
4. 數據管理更集中 4. 打包體積大,需按需加載優化

10. Vuex 是什麼?怎麼使用?在哪些場景下使用?

  • 定義​:Vuex 是 Vue 官方的​集中式狀態管理庫​,用於管理多組件共享的狀態(如用户信息、全局配置);
  • 使用步驟​:

    • 安裝:npm install vuex --save
    • 創建 store:

      import Vue from 'vue';
      import Vuex from 'vuex';
      Vue.use(Vuex);
      export default new Vuex.Store({
        state: { count: 0 }, // 狀態
        mutations: { increment(state) { state.count++ } }, // 同步修改狀態
        actions: { asyncIncrement({ commit }) { setTimeout(() => commit('increment'), 1000) } }, // 異步操作
        getters: { doubleCount(state) { return state.count * 2 } }, // 派生狀態
        modules: { /* 模塊拆分 */ }
      });
    • 掛載到 Vue 實例:new Vue({ store, ... })
    • 組件中使用:

      1. 讀取 state:this.$store.state.countmapState 輔助函數;
      2. 修改 state:this.$store.commit('increment')(同步)/ this.$store.dispatch('asyncIncrement')(異步);
  • 使用場景​:

    • 多組件共享同一狀態(如購物車、用户登錄狀態);
    • 組件層級深,props/emit 傳值繁瑣;
    • 需要追蹤狀態變更(Vuex 可記錄狀態修改日誌)。

11. Vuex 與 Pinia 的區別

Pinia 是 Vue 3 推薦的狀態管理庫,替代 Vuex 4,核心區別:

維度 Vuex Pinia
核心結構 分 state/mutations/actions/getters/modules 僅 state/actions/getters(無 mutations/modules)
模塊化 需通過 modules 嵌套,命名空間複雜 每個 store 獨立,天然模塊化,無需命名空間
TypeScript 支持差,需手動類型聲明 原生支持 TS,類型推斷更友好
代碼簡潔度 冗餘(如 mutations 必須同步) 簡潔(actions 可同步/異步,無需 commit)
Vue 版本支持 Vue 2/3(Vuex 3 對應 Vue 2,Vuex 4 對應 Vue 3) 主要支持 Vue 3(也可兼容 Vue 2)
調試 依賴 Vue Devtools,需配置 原生集成 Vue Devtools,調試更友好

12. Vue 路由的跳轉方式

Vue Router 的跳轉分兩類:聲明式(模板)和編程式(JS):

  • 聲明式(<router-link>)​:

    <!-- 基礎跳轉 -->
    <router-link to="/home">首頁</router-link>
    <!-- 帶參數 -->
    <router-link :to="{ path: '/user', query: { id: 1 } }">用户頁</router-link>
    <router-link :to="{ name: 'User', params: { id: 1 } }">用户頁</router-link>
  • 編程式($router.push/replace/go)​:

    // 基礎跳轉
    this.$router.push('/home');
    // 帶query參數(路徑拼接,如/user?id=1)
    this.$router.push({ path: '/user', query: { id: 1 } });
    // 帶params參數(需路由配置name,如/user/1)
    this.$router.push({ name: 'User', params: { id: 1 } });
    // 替換當前歷史記錄(不新增歷史)
    this.$router.replace('/home');
    // 前進/後退
    this.$router.go(-1); // 後退一頁

13. 跨域的解決方式

跨域是瀏覽器同源策略限制(協議、域名、端口任一不同即跨域),前端常用解決方案:

  1. Vue CLI 代理(開發環境)​:

    // vue.config.js
    module.exports = {
      devServer: {
        proxy: {
          '/api': {
            target: 'http://localhost:3000', // 後端接口地址
            changeOrigin: true, // 開啓跨域
            pathRewrite: { '^/api': '' } // 重寫路徑
          }
        }
      }
    }
  2. 後端 CORS(跨域資源共享)​:後端設置響應頭 Access-Control-Allow-Origin: *(或指定域名);
  3. JSONP​:僅支持 GET 請求,通過動態創建 <script> 標籤請求;
  4. Nginx 反向代理​:生產環境通過 Nginx 轉發請求,統一域名;
  5. WebSocket​:基於 TCP 協議,無跨域限制。

14. Vue 生命週期請簡述

Vue 生命週期是組件從創建到銷燬的全過程,分 8 個核心階段(Vue 2):

  1. 創建階段​:beforeCreate(實例初始化,數據/方法未掛載)→ created(數據/方法掛載完成,DOM 未生成);
  2. 掛載階段​:beforeMount(編譯模板,即將掛載 DOM)→ mounted(DOM 掛載完成,可操作 DOM);
  3. 更新階段​:beforeUpdate(數據更新,DOM 未重新渲染)→ updated(DOM 重新渲染完成);
  4. 銷燬階段​:beforeDestroy(實例即將銷燬,數據/方法仍可用)→ destroyed(實例銷燬,所有監聽/綁定解除);
  • Vue 3 補充:組合式 API 中用 onMounted/onUpdated 等鈎子替代選項式,新增 setup(替代 beforeCreate/created)。

15. Vue 生命週期的作用

生命週期鈎子允許開發者在組件不同階段插入自定義邏輯,核心作用:

  1. 初始化邏輯​:created 中請求數據、初始化變量;
  2. DOM 操作​:mounted 中操作 DOM(如初始化第三方插件);
  3. 數據更新處理​:updated 中處理 DOM 更新後的邏輯;
  4. 資源清理​:beforeDestroy 中清除定時器、取消事件監聽,避免內存泄漏;
  5. 性能優化​:按需執行邏輯,避免無效代碼(如僅在掛載後請求數據)。

16. DOM 渲染在哪個生命週期階段內完成

  • 核心結論:mounted 階段完成 DOM 渲染;
  • 細節:

    • beforeMount:模板已編譯,但未掛載到 DOM($el 為虛擬 DOM);
    • mounted:真實 DOM 掛載完成,$el 指向真實 DOM 節點,可安全操作 DOM;
    • 若組件包含子組件,mounted 僅表示當前組件 DOM 掛載完成,子組件可能仍在掛載中。

17. Vue 路由的實現

Vue Router 的核心實現依賴​前端路由原理​,分兩步:

  1. 路由匹配​:

    1. 定義路由規則(routes 數組),每個規則包含 path、component 等;
    2. Vue Router 監聽 URL 變化,匹配對應路由規則;
  2. 視圖渲染​:

    1. 通過 <router-view> 組件作為路由出口,匹配到的組件渲染到該位置;
    2. 底層依賴 Vue 的組件系統,通過動態組件切換實現視圖更新;
  • 補充:路由模式(hash/history)決定 URL 的表現形式,底層分別基於 hashchange 事件和 History API。

18. 簡述 Vue 路由模式 hash 和 history

維度 hash 模式(默認) history 模式
URL 表現 帶#(如 http://xxx/#/home) 無#(如 http://xxx/home)
底層原理 基於 hashchange 事件,#後的內容不會發送到服務器 基於 HTML5 History API(pushState/replaceState)
服務器配置 無需配置,刷新頁面不會 404 需配置後端,刷新頁面需重定向到 index.html(否則 404)
兼容性 兼容所有瀏覽器(包括 IE) 僅支持 HTML5 瀏覽器
SEO 部分搜索引擎不識別#後內容 更友好,SEO 效果更好

19. Vue 路由傳參方式,params 與 query 方式和區別

  • 傳參方式​:分 query 和 params 兩種核心方式,均支持聲明式/編程式;
  • 核心區別​:
維度 query 參數 params 參數
URL 表現 拼接在路徑後(?key=value) 嵌入路徑中(/user/1)
路由配置 無需特殊配置 需在路由 path 中定義(如/user/:id)
刷新頁面 參數不會丟失 若路由未定義參數,刷新後丟失
取值方式 this.$route.query.key this.$route.params.key
可選性 可傳可不傳 路由定義的參數必須傳(否則跳轉失敗)
  • 示例:

    // query傳參
    this.$router.push({ path: '/user', query: { id: 1 } }); // URL: /user?id=1
    // params傳參(需路由name)
    this.$router.push({ name: 'User', params: { id: 1 } }); // URL: /user/1

20. Vue 數據綁定的幾種方式

Vue 數據綁定分三類,核心是響應式綁定:

  1. 單向綁定​:

    1. 插值表達式 {{}}:渲染文本;
    2. v-bind(簡寫 :):綁定屬性(如 :src="imgUrl":class="className");
  2. 雙向綁定​:

    1. v-model:主要用於表單元素(如 <input v-model="value">),本質是 v-bind+v-on 的語法糖;
  3. 一次性綁定​:

    1. v-once:綁定後數據變化不再更新視圖(如 <div v-once>{{name}}</div>)。

21. Vue 註冊一個全局組件

全局組件註冊後,所有 Vue 實例/組件均可直接使用,步驟:

// 1. 定義組件
const MyComponent = {
  template: `<div>{{msg}}</div>`,
  data() {
    return { msg: '全局組件' };
  }
};
// 2. 註冊全局組件(Vue 2)
import Vue from 'vue';
Vue.component('MyComponent', MyComponent);

// Vue 3(createApp方式)
import { createApp } from 'vue';
const app = createApp({});
app.component('MyComponent', MyComponent);
app.mount('#app');
  • 注意:全局組件需在 Vue 實例創建前註冊,否則無法使用。

22. Vue 的路由鈎子/路由守衞有哪些

Vue Router 的路由守衞分三類,用於控制路由跳轉權限:

  1. 全局守衞​(所有路由生效):

    1. router.beforeEach:路由跳轉前觸發(常用作登錄驗證);
    2. router.afterEach:路由跳轉後觸發(無權限控制);
    3. router.beforeResolve:所有組件內守衞和異步路由解析完成後觸發;
  2. 路由獨享守衞​(單個路由生效):

    const routes = [
      {
        path: '/user',
        component: User,
        beforeEnter: (to, from, next) => { // 僅/user路由生效
          if (/* 驗證 */) next();
          else next('/login');
        }
      }
    ];
  3. 組件內守衞​(組件內生效):

    1. beforeRouteEnter:進入組件前觸發(無法訪問 this,需通過 next 回調);
    2. beforeRouteUpdate:組件複用(如動態路由)時觸發;
    3. beforeRouteLeave:離開組件前觸發(如提示未保存)。

23. Vue 中如何進行動態路由設置?有哪些方式?怎麼獲取傳遞過來的參數?

  • 動態路由定義​:在路由 path 中用 :參數名 定義,匹配任意值;
  • 定義方式​:

    // 1. 基礎動態路由
    const routes = [
      { path: '/user/:id', name: 'User', component: User }
    ];
    // 2. 可選參數(加?)
    { path: '/user/:id?', component: User }
    // 3. 通配符(匹配所有)
    { path: '*', component: NotFound }
  • 獲取參數​:

    • 組件內通過 this.$route.params 獲取(如 this.$route.params.id);
    • 組合式 API 中用 useRoute

      import { useRoute } from 'vue-router';
      const route = useRoute();
      console.log(route.params.id);

24. Element UI 中常用組件有哪些?請簡述並説下他們的屬性有哪些

Element UI 是 Vue 2 主流 UI 庫,核心常用組件及屬性:

組件 用途 核心屬性
Button 按鈕 type(primary/success)、size(small/medium)、disabled、icon
Input 輸入框 v-model、placeholder、disabled、clearable、type(text/password)
Table 表格 data(數據源)、columns(列配置)、pagination(分頁)、border、height
Form 表單 model(表單數據)、rules(校驗規則)、label-width、inline
Dialog 彈窗 visible(顯示/隱藏)、title、width、modal(遮罩)、close-on-click-modal
Select 下拉選擇 v-model、options(選項)、multiple(多選)、disabled
Pagination 分頁 total(總條數)、page-size(每頁條數)、current-page(當前頁)、layout(佈局)

25. Vue CLI 中如何自定義指令

自定義指令用於擴展 DOM 操作,分全局/局部指令:

  • 全局自定義指令​(main.js):

    // Vue 2
    import Vue from 'vue';
    // 註冊v-focus指令(自動聚焦輸入框)
    Vue.directive('focus', {
      inserted(el) { // 指令綁定到元素並插入DOM時觸發
        el.focus();
      }
    });
    
    // Vue 3
    import { createApp } from 'vue';
    const app = createApp({});
    app.directive('focus', {
      mounted(el) { el.focus(); }
    });
  • 局部自定義指令​(組件內):

    <script>
    export default {
      directives: {
        focus: {
          inserted(el) { el.focus(); }
        }
      }
    }
    </script>
  • 指令鈎子:bind(綁定)、inserted(插入 DOM)、update(更新)等(Vue 3 調整為 created/mounted/updated)。

26. Vue 中指令有哪些

Vue 指令分內置指令和​自定義指令​,核心內置指令:

類別 指令 用途
數據綁定 v-text、v-html、v-bind 渲染文本/HTML、綁定屬性
事件綁定 v-on 綁定事件(簡寫 @)
雙向綁定 v-model 表單數據雙向綁定
條件渲染 v-if、v-else、v-show 條件顯示/隱藏 DOM
列表渲染 v-for 循環渲染列表
其他 v-once、v-cloak、v-pre 一次性綁定、解決閃爍、跳過編譯

27. Vue 如何定義一個過濾器

過濾器用於格式化數據(Vue 3 已移除,推薦用計算屬性/方法替代),Vue 2 定義方式:

  • 全局過濾器​(main.js):

    import Vue from 'vue';
    // 註冊全局過濾器(格式化時間)
    Vue.filter('formatTime', (value) => {
      return new Date(value).toLocaleString();
    });
  • 局部過濾器​(組件內):

    <script>
    export default {
      filters: {
        formatTime(value) {
          return new Date(value).toLocaleString();
        }
      }
    }
    </script>
  • 使用:{{ time | formatTime }}v-bind:title="time | formatTime"

28. 對 Vue 中 keep-alive 的理解

keep-alive 是 Vue 的內置組件,用於​緩存組件實例​,避免重複創建/銷燬:

  • 核心特性:

    • 包裹動態組件時,緩存不活動的組件,而非銷燬;
    • 觸發組件的 activated(激活)/deactivated(失活)鈎子;
  • 常用屬性:

    • include:僅緩存指定組件(如 include="User,Home");
    • exclude:排除指定組件;
    • max:最大緩存數量(超出則銷燬最久未使用的組件);
  • 應用場景:路由切換時緩存表單數據、列表滾動位置等(如 <keep-alive><router-view></router-view></keep-alive>)。

29. 如何讓組件中的 CSS 在當前組件生效

通過樣式隔離實現,核心方式:

  1. scoped 屬性​(推薦):

    <style scoped>
    .box { color: red; } // 僅當前組件生效
    </style>
    1. 原理:Vue 為組件 DOM 添加唯一屬性(如 data-v-xxx),CSS 自動添加屬性選擇器,實現隔離;
  2. CSS Modules​:

    <style module>
    .box { color: red; }
    </style>
    <template>
      <div :class="$style.box">內容</div>
    </template>
    1. 原理:類名被編譯為唯一哈希值,避免衝突;
  3. 深度選擇器​(如需修改子組件樣式):

    <style scoped>
    ::v-deep .child-box { color: blue; } // Vue 2
    :deep(.child-box) { color: blue; } // Vue 3
    </style>

30. Vue 生命週期一共有幾個階段

  • Vue 2​:分 4 個大階段,8 個核心鈎子:

    • 創建階段(2 個):beforeCreate、created;
    • 掛載階段(2 個):beforeMount、mounted;
    • 更新階段(2 個):beforeUpdate、updated;
    • 銷燬階段(2 個):beforeDestroy、destroyed;
    • 補充:還有 activated/deactivated(keep-alive 組件)、errorCaptured(錯誤捕獲)等鈎子;
  • Vue 3​:組合式 API 中鈎子更細分,核心階段一致,鈎子名調整為 onXxx(如 onMounted),新增 setup(替代 beforeCreate/created)。

31. MVVM 和 MVC 的區別

兩者均為軟件架構模式,核心區別:

維度 MVC(Model-View-Controller) MVVM(Model-View-ViewModel)
核心角色 Model(數據)、View(視圖)、Controller(控制器,連接 M/V) Model(數據)、View(視圖)、ViewModel(橋樑,雙向綁定)
數據流向 單向(Model→Controller→View) 雙向(View←→ViewModel←→Model)
耦合度 View 和 Model 需通過 Controller 通信,耦合較高 View 和 Model 完全解耦,由 ViewModel 中轉
核心特性 手動更新視圖(需 Controller 操作 DOM) 自動更新視圖(數據驅動,ViewModel 實現響應式)
應用框架 jQuery、Backbone.js Vue、React(類 MVVM)、Angular

32. Vue 組件中的 data 為什麼是函數

核心原因:​保證組件實例的獨立性​,避免多個組件實例共享同一數據對象;

  • 原理:

    • 若 data 是對象,所有組件實例會引用同一個對象,修改一個實例的 data 會影響其他實例;
    • 若 data 是函數,每次創建組件實例時,函數返回一個新的對象,各實例數據獨立;
  • 示例:

    <script>
    export default {
      // 正確:函數返回新對象
      data() {
        return { count: 0 };
      },
      // 錯誤:所有實例共享count
      // data: { count: 0 }
    }
    </script>
  • 補充:根實例(new Vue({}))的 data 可以是對象(僅一個實例,無共享問題)。

33. Vue 雙向綁定原理

Vue 2 基於​Object.defineProperty​,Vue 3 基於​Proxy​,核心流程:

  • Vue 2​:

    • 數據劫持:通過 Object.defineProperty 監聽 data 中所有屬性的 get/set;
    • 依賴收集:模板編譯時,訪問屬性觸發 get,收集依賴(Watcher);
    • 派發更新:修改屬性觸發 set,通知 Watcher 更新視圖;
    • 缺陷:無法監聽數組下標/長度變化、對象新增屬性;
  • Vue 3​:

    • 數據代理:通過 Proxy 代理整個 data 對象,支持監聽數組/對象所有變化;
    • 依賴收集/派發更新邏輯與 Vue 2 類似,但效率更高;
  • 核心公式:MVVM = 數據劫持 + 發佈-訂閲模式

34. Vue 組件中的傳值方式

組件傳值分 7 種核心場景,覆蓋父子/兄弟/跨級:

場景 傳值方式 示例
父 → 子 props 子組件定義 props,父組件 :prop="value"
子 → 父 自定義事件($emit) 子組件 this.$emit('event', data),父組件 @event="handle"
兄弟組件 事件總線/Vuex/Pinia 事件總線:Vue.prototype.$bus = new Vue()$bus.$emit/$on
跨級組件 provide/inject 父組件 provide 提供數據,子組件 inject 注入
任意組件 Vuex/Pinia 全局狀態管理,直接讀取/修改共享數據
路由傳參 query/params 跳轉路由時攜帶參數
本地存儲 localStorage/sessionStorage 持久化傳值(非響應式)

35. Bootstrap 的原理

Bootstrap 是前端 UI 框架,核心原理:

  1. 柵格系統​:基於 Flex/Grid 佈局,將頁面分為 12 列,通過 col-xs-*/col-md-* 等類實現響應式佈局;
  2. 響應式設計​:通過媒體查詢(@media)適配不同屏幕尺寸(移動端/平板/PC);
  3. 預定義樣式​:提供按鈕、表單、導航等組件的 CSS 樣式,直接複用;
  4. jQuery 插件​:內置輪播、彈窗、下拉菜單等交互插件(Bootstrap 5 移除 jQuery,改用原生 JS);
  5. 變量/混合器​(Sass 版本):支持自定義主題,通過變量覆蓋默認樣式。

36. Vue 兄弟組件傳值

兄弟組件無直接傳值通道,常用 3 種方式:

  1. 事件總線(Vue 2)​:

    // 1. 全局註冊總線
    import Vue from 'vue';
    Vue.prototype.$bus = new Vue();
    // 2. 組件A發送事件
    this.$bus.$emit('sendData', data);
    // 3. 組件B接收事件(mounted中)
    this.$bus.$on('sendData', (data) => { /* 處理數據 */ });
    // 4. 銷燬時解綁(避免內存泄漏)
    beforeDestroy() {
      this.$bus.$off('sendData');
    }
  2. Vuex/Pinia​:將共享數據存入全局狀態,兄弟組件直接讀取/修改;
  3. 父組件中轉​:組件 A→ 父組件($emit)→ 組件 B(props)。

37. 如果一個組件需要在多個項目中使用怎麼辦

核心方案:​組件封裝併發布為 npm 包​,步驟:

  1. 組件封裝​:

    1. 抽離組件的通用邏輯,參數通過 props 暴露,事件通過$emit 觸發;
    2. 避免硬編碼,支持自定義樣式/配置;
  2. 打包發佈​:

    1. 用 Vue CLI/lib 模式打包:vue-cli-service build --target lib --name my-component src/index.js
    2. 配置 package.json(main 指向打包後的文件,指定版本、依賴等);
    3. 發佈到 npm(npm publish);
  3. 其他方案​:

    1. 搭建私有 npm 倉庫(如 Verdaccio),存放內部組件;
    2. 通過 Git submodule 引入組件源碼(適合頻繁修改的場景);
    3. 使用 Monorepo 管理多項目共享組件(如 pnpm workspace)。

38. 簡述槽口(Slot)

Slot(插槽)是 Vue 組件的內容分發機制,允許父組件向子組件插入自定義內容:

  • 核心類型​:

    • 默認插槽​:子組件 <slot></slot>,父組件直接寫內容;
    • 具名插槽​:子組件 <slot name="header"></slot>,父組件 <template v-slot:header>內容</template>(簡寫 #header);
    • 作用域插槽​:子組件向父組件傳遞數據,父組件自定義渲染邏輯:

      <!-- 子組件 -->
      <slot :user="user"></slot>
      <!-- 父組件 -->
      <template v-slot:default="slotProps">
        {{ slotProps.user.name }}
      </template>
  • 作用:提升組件靈活性,實現組件內容的自定義渲染。

39. 簡述 watch

watch 是 Vue 的​偵聽器​,用於監聽數據變化並執行自定義邏輯:

  • 核心特性:

    • 監聽單個/多個數據(如 data、props、計算屬性);
    • 支持深度監聽(deep: true)、立即執行(immediate: true);
    • 可監聽對象屬性(如 'user.name');
  • 示例:

    <script>
    export default {
      data() {
        return { user: { name: '張三' }, count: 0 };
      },
      watch: {
        // 監聽基本類型
        count(newVal, oldVal) {
          console.log('count變化:', newVal, oldVal);
        },
        // 監聽對象(深度監聽)
        user: {
          handler(newVal) {
            console.log('user變化:', newVal);
          },
          deep: true,
          immediate: true // 初始化時執行一次
        },
        // 監聽對象單個屬性
        'user.name'(newVal) {
          console.log('姓名變化:', newVal);
        }
      }
    }
    </script>

40. 簡述 Vant UI

Vant UI 是有贊開源的​移動端 Vue UI 組件庫​,核心特點:

  1. 適配場景​:專注移動端(H5/小程序),適配各種屏幕尺寸;
  2. 版本支持​:Vant 2 支持 Vue 2,Vant 3/4 支持 Vue 3;
  3. 核心組件​:Button、Cell、List、PullRefresh、Swipe、Dialog、Toast 等;
  4. 特性​:

    1. 輕量:按需引入,減少打包體積;
    2. 易用:API 簡潔,文檔完善;
    3. 兼容:支持小程序(微信/支付寶)、H5、App(通過 uni-app);
  5. 使用方式​:

    npm i vant
    # 按需引入(需配置babel-plugin-import)
    import { Button } from 'vant';
    Vue.use(Button);

41. 計算屬性與 watch 的區別

維度 計算屬性(computed) 偵聽器(watch)
核心用途 派生數據(如 a+b) 監聽數據變化執行副作用(如請求、修改 DOM)
緩存性 有緩存,依賴不變則不重新計算 無緩存,數據變化即觸發
返回值 必須有返回值 無需返回值
語法 聲明式(類似變量) 命令式(函數)
適用場景 簡單的同步數據計算 異步操作、複雜的邏輯處理
深度監聽 自動深度監聽對象屬性 需手動設置 deep: true
  • 示例對比:

    // 計算屬性:適合簡單計算
    computed: { fullName() { return this.first + ' ' + this.last; } }
    // watch:適合異步邏輯
    watch: { firstName(newVal) { this.$axios.get('/api', { params: { name: newVal } }); } }

42. MVVM 框架是什麼?它和其他框架的區別是什麼?哪些場景適合?

  • MVVM 定義​:MVVM(Model-View-ViewModel)是前端架構模式,核心是 ViewModel 作為 View 和 Model 的橋樑,實現數據與視圖的雙向綁定;
  • 與其他框架的區別​:

    • 與 jQuery(無架構):MVVM 數據驅動,無需手動操作 DOM;jQuery 需手動選擇 DOM、修改內容;
    • 與 React(類 MVVM):React 核心是單向數據流(State→View),需手動 setState 更新;Vue(MVVM)原生支持雙向綁定;
    • 與 Angular(全量 MVVM):Vue 更輕量、易用,Angular 功能全但學習成本高;
  • 適用場景​:

    • 中大型單頁應用(SPA):數據交互頻繁,需高效管理狀態;
    • 表單類應用:雙向綁定簡化表單處理;
    • 移動端/H5 應用:輕量、高性能,適配移動端;
    • 不適用場景:簡單靜態頁面(如純展示頁),用 jQuery/原生 JS 更高效。

43. Vue 首屏加載慢的原因,怎麼解決的,白屏時間怎麼檢測,怎麼解決白屏問題

(1)首屏加載慢的原因
  1. 打包體積大:未按需引入組件/庫、未壓縮代碼、包含無用依賴;
  2. 網絡問題:請求資源過大、網絡延遲高;
  3. 渲染阻塞:JS 執行時間長,阻塞 DOM 渲染;
  4. 服務器響應慢:接口請求耗時久。
(2)解決方法
  1. 優化打包體積​:

    1. 按需引入(如 Element UI/Vant);
    2. 路由懶加載:const Home = () => import('./Home.vue')
    3. 壓縮代碼(Vue CLI 默認開啓)、移除 console;
    4. CDN 引入第三方庫(如 Vue、Vue Router),減少打包體積;
  2. 網絡優化​:

    1. 開啓 Gzip 壓縮(Nginx 配置);
    2. 使用 HTTP/2、靜態資源 CDN;
    3. 預加載/預取(<link rel="preload">);
  3. 渲染優化​:

    1. 首屏骨架屏(Skeleton);
    2. 異步組件、懶加載圖片;
    3. 服務端渲染(SSR)/靜態站點生成(SSG)。
(3)白屏時間檢測
  1. 瀏覽器 Performance 面板​:

    1. 記錄首屏時間(First Contentful Paint, FCP)、最大內容繪製(LCP);
    2. 查看 JS 執行、資源加載耗時;
  2. 代碼埋點​:

    // 監聽DOM加載完成
    document.addEventListener('DOMContentLoaded', () => {
      console.log('DOM加載完成時間:', Date.now() - performance.timing.navigationStart);
    });
    // 監聽首屏繪製
    new PerformanceObserver((entryList) => {
      const entry = entryList.getEntries()[0];
      console.log('首屏時間:', entry.startTime);
    }).observe({ type: 'paint', buffered: true });
(4)解決白屏問題
  1. 骨架屏:首屏加載時顯示佔位骨架,替代空白;
  2. 預加載關鍵資源:優先加載首屏所需 CSS/JS;
  3. 服務端渲染(SSR):服務端生成首屏 HTML,直接返回;
  4. 減小首屏 JS 體積:路由懶加載、按需引入,只加載首屏必要代碼。

44. Vue 雙向數據綁定中,怎麼實現一側數據改變之後通知另一側

核心是​發佈-訂閲模式​,分兩步:

  1. 數據劫持/代理​:

    1. Vue 2 用 Object.defineProperty 監聽數據的 setter,Vue 3 用 Proxy 監聽對象變化;
  2. 依賴收集與派發更新​:

    1. 當視圖渲染訪問數據時(getter),收集依賴(Watcher,關聯視圖);
    2. 當數據修改時(setter),觸發派發更新,通知所有相關 Watcher 執行更新邏輯,重新渲染視圖;
    3. 反向(視圖 → 數據):v-model 監聽輸入事件(input/change),修改對應數據,完成雙向綁定。

45. Vuex 流程

Vuex 的核心數據流向是​單向循環​:

  1. 組件通過 dispatch 觸發​Action​(可執行異步操作);
  2. Action 通過 commit 提交​Mutation​;
  3. Mutation 修改​State​(唯一能修改 State 的方式);
  4. State 變化觸發​Getter​(可選,派生數據);
  5. 組件監聽 State/Getter 變化,更新視圖;
  • 簡化流程:組件 → Action → Mutation → State → 組件(同步操作可直接 commit Mutation)。

46. Vuex 怎麼請求異步數據

Vuex 中異步數據請求需在 Action 中執行,步驟:

// 1. 定義Action
const store = new Vuex.Store({
  state: { userList: [] },
  mutations: {
    SET_USER_LIST(state, data) {
      state.userList = data;
    }
  },
  actions: {
    // 異步請求數據
    async fetchUserList({ commit }) {
      try {
        const res = await this.$axios.get('/api/user/list');
        commit('SET_USER_LIST', res.data); // 提交Mutation修改State
      } catch (err) {
        console.error('請求失敗:', err);
      }
    }
  }
});
// 2. 組件中觸發Action
this.$store.dispatch('fetchUserList');
  • 注意:Mutation 只能執行同步操作,異步操作必須放在 Action 中。

47. Vuex 中 Action 如何提交給 Mutation

Action 通過 commit 方法提交 Mutation,有兩種方式:

  1. 解構 context 對象​(推薦):

    actions: {
      increment({ commit }) { // 解構commit
        commit('INCREMENT'); // 提交Mutation
      }
    }
  2. 完整 context 對象​:

    actions: {
      increment(context) {
        context.commit('INCREMENT'); // context包含commit/dispatch/state等
      }
    }
  • 帶參數提交:commit('INCREMENT', payload)(payload 為任意類型數據)。

48. route 與 router 的區別

維度 $route $router
核心含義 當前路由信息對象 路由實例(導航控制器)
包含內容 path、params、query、name 等 push、replace、go 等導航方法
用途 讀取當前路由參數/信息 觸發路由跳轉
示例 this.$route.params.id this.$router.push('/home')

49. Vuex 有哪幾種狀態和屬性

Vuex 的核心屬性(5 個):

  1. state​:存儲全局狀態(唯一數據源);
  2. mutations​:同步修改 state 的方法(唯一入口);
  3. actions​:異步操作,提交 mutation 修改 state;
  4. getters​:派生狀態(類似計算屬性,基於 state 計算);
  5. modules​:模塊化拆分 state,解決單一狀態樹體積過大問題。

50. Vuex 的 state 特性是?

  1. 唯一性​:整個應用只有一個 state(單一狀態樹);
  2. 響應式​:state 中的數據是響應式的,修改後視圖自動更新;
  3. 只讀性​:不能直接修改 state,必須通過 mutation;
  4. 可模塊化​:通過 modules 拆分 state,每個 module 有獨立的 state/mutations 等;
  5. 組件訪問​:通過 this.$store.statemapState 輔助函數訪問。

51. Vuex 的 getter 特性是?

  1. 緩存性​:依賴的 state 不變時,多次訪問 getter 不會重新計算;
  2. 派生狀態​:基於 state 計算新值(如過濾列表、計算總數);
  3. 只讀性​:不能直接修改 getter,需修改依賴的 state;
  4. 可傳參​:通過返回函數實現傳參(如 getters.getUserById(state) => (id) => state.users.find(u => u.id === id));
  5. 組件訪問​:通過 this.$store.gettersmapGetters 輔助函數訪問。

52. Vuex 的 mutation 特性是?

  1. 同步性​:必須是同步函數(異步操作會導致狀態變更無法追蹤);
  2. 唯一修改入口​:只能通過 mutation 修改 state;
  3. 參數​:第一個參數是 state,第二個是 payload(可選,傳遞數據);
  4. 可追蹤​:Vue Devtools 可記錄 mutation 的調用記錄,便於調試;
  5. 調用方式​:通過 store.commit('mutationName', payload),不能直接調用。

53. Vuex 的 action 特性是?

  1. 異步性​:支持異步操作(如請求數據、定時器);
  2. 不直接修改 state​:需提交 mutation 修改 state;
  3. 參數​:第一個參數是 context 對象(包含 commit/dispatch/state/getters);
  4. 支持 Promise​:action 可返回 Promise,便於鏈式調用;
  5. 調用方式​:通過 store.dispatch('actionName', payload),組件中可通過 async/await 等待執行完成。

54. Vuex 的優勢

  1. 集中式管理​:多組件共享狀態統一存儲,避免狀態分散;
  2. 可追蹤性​:所有狀態修改通過 mutation,便於調試和日誌記錄;
  3. 單向數據流​:狀態變更流程清晰,降低維護成本;
  4. 模塊化​:支持 modules 拆分狀態,適配大型應用;
  5. 生態集成​:與 Vue Devtools 深度集成,可視化調試;
  6. 複用性​:公共邏輯(如數據請求)可封裝在 action 中,多組件複用。

55. 簡述 Vue 路由懶加載

路由懶加載(按需加載)是代碼分割的一種方式,核心是將路由組件拆分為獨立的 JS 包,只有訪問該路由時才加載對應的包:

  • 實現方式​:

    // 基礎懶加載
    const Home = () => import('./views/Home.vue');
    // 帶分包命名(webpackChunkName),便於打包後識別
    const User = () => import(/* webpackChunkName: "user" */ './views/User.vue');
    const routes = [
      { path: '/home', component: Home },
      { path: '/user', component: User }
    ];
  • 優勢​:

    • 減小首屏 JS 包體積,提升首屏加載速度;
    • 按需加載,節省帶寬和資源;
  • 原理​:基於 ES6 的動態 import 語法,webpack 打包時自動拆分代碼塊。

56. v-for 和 v-if 的區別

維度 v-for v-if
核心用途 循環渲染列表 條件渲染 DOM
優先級 更高(Vue 2) 更低(Vue 2)
執行時機 每次渲染都循環所有數據 條件為 true 時才渲染 DOM
性能 循環所有數據,性能開銷大 僅渲染滿足條件的 DOM
結合使用 不推薦直接結合(Vue 2 中 v-for 優先級高,會先循環再判斷,性能差) 推薦用 computed 過濾數據後再循環
  • 優化建議:

    // 錯誤:v-for和v-if同節點
    <div v-for="item in list" v-if="item.visible">{{item.name}}</div>
    // 正確:先過濾數據
    computed: {
      filteredList() {
        return this.list.filter(item => item.visible);
      }
    }
    <div v-for="item in filteredList" :key="item.id">{{item.name}}</div>
  • Vue 3 調整:v-if 優先級高於 v-for,同節點使用會報錯,強制開發者先過濾數據。
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.