<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                前幾篇文章我們介紹了 Vue 項目構建及運行的前期工作,包括 webpack 的配置、環境變量的使用等,在了解并掌握了這些前期準備工作后,那么接下來我們可以走進 Vue 項目的內部,一探其內部配置的基本構成。 ![](https://img.kancloud.cn/f0/a9/f0a9d8cb16d5788b1707115f63f157d4_565x308.gif) ## 配置 ### 1\. 路由配置 由于 Vue 這類型的框架都是以一個或多個單頁構成,在單頁內部跳轉并不會重新渲染 HTML 文件,其路由可以由前端進行控制,因此我們需要在項目內部編寫相應的路由文件,Vue 會解析這些文件中的配置并進行對應的跳轉渲染。 我們來看一下 CLI 給我們生成的 router.js 文件的配置: ``` /* router.js */ import Vue from 'vue' import Router from 'vue-router' import Home from './views/Home.vue' // 引入 Home 組件 import About from './views/About.vue' // 引入 About 組件 Vue.use(Router) // 注冊路由 export default new Router({ routes: [{ path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About }] }) ``` 這份配置可以算是最基礎的路由配置,有以下幾點需要進行優化: * 如果路由存在二級目錄,需要添加 base 屬性,否則默認為 "/" * 默認路由模式是 hash 模式,會攜帶 # 標記,與真實 url 不符,可以改為 history 模式 * 頁面組件沒有進行按需加載,可以使用 `require.ensure()` 來進行優化 下面是我們優化結束的代碼: ``` /* router.js */ import Vue from 'vue' import Router from 'vue-router' // 引入 Home 組件 const Home = resolve => { require.ensure(['./views/Home.vue'], () => { resolve(require('./views/Home.vue')) }) } // 引入 About 組件 const About = resolve => { require.ensure(['./views/About.vue'], () => { resolve(require('./views/About.vue')) }) } Vue.use(Router) let base = `${process.env.BASE_URL}` // 動態獲取二級目錄 export default new Router({ mode: 'history', base: base, routes: [{ path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About }] }) ``` 改為 history 后我們 url 的路徑就變成了 `http://127.0.0.1:8080/vue/about`,而不是原來的 `http://127.0.0.1:8080/vue/#/about`,但是需要注意頁面渲染 404 的問題,具體可查閱:[HTML5 History 模式](https://router.vuejs.org/zh/guide/essentials/history-mode.html)。 而在異步加載的優化上,我們使用了 webpack 提供的 require.ensure() 進行了代碼拆分,主要區別在于沒有優化前,訪問 Home 頁面會一起加載 About 組件的資源,因為它們打包進了一個 app.js 中: ![](https://img.kancloud.cn/3b/33/3b3332cbada12b454faef17e019e7d27_809x87.gif) 但是優化過后,它們分別被拆分成了 2.js 和 3.js: ![](https://img.kancloud.cn/bb/f8/bbf831f35998fe5297150f734e51999b_813x107.gif) ![](https://img.kancloud.cn/ad/3c/ad3c9352f67db988fb8cdf1268ff864f_812x108.gif) 如此,只有當用戶點擊了某頁面,才會加載對應頁面的 js 文件,實現了按需加載的功能。 > webpack 在編譯時,會靜態地解析代碼中的 require.ensure(),同時將模塊添加到一個分開的 chunk 當中。這個新的 chunk 會被 webpack 通過 jsonp 來按需加載。 關于 `require.ensure()` 的知識點可以參考官方文檔:[require.ensure](https://webpack.js.org/api/module-methods/#require-ensure)。 當然,除了使用 require.ensure 來拆分代碼,[Vue Router](https://router.vuejs.org/zh/guide/advanced/lazy-loading.html#%E6%8A%8A%E7%BB%84%E4%BB%B6%E6%8C%89%E7%BB%84%E5%88%86%E5%9D%97) 官方文檔還推薦使用動態 `import` 語法來進行代碼分塊,比如上述 require.ensure 代碼可以修改為: ``` // 引入 Home 組件 const Home = () => import('./views/Home.vue'); // 引入 About 組件 const About = () => import('./views/About.vue'); ``` 其余代碼可以保持不變,仍然可以實現同樣的功能。如果你想給拆分出的文件命名,可以嘗試一下 webpack 提供的 `Magic Comments`(魔法注釋): ``` const Home = () => import(/* webpackChunkName:'home'*/ './views/Home.vue'); ``` ### 2\. Vuex 配置 除了 vue-router,如果你的項目需要用到 [Vuex](https://vuex.vuejs.org/zh/) ,那么你應該對它有一定的了解,Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。這里我們先來看一下使用 CLI 生成的配置文件 store.js 中的內容: ``` import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { }, mutations: { }, actions: { } }) ``` 該配置文件便是 Vuex 的配置文件,主要有 4 個核心點:state、mutations、actions 及 getter,詳細的介紹大家可以參考官方文檔:[核心概念](https://vuex.vuejs.org/zh/guide/state.html),這里我用一句話介紹它們之間的關系就是:**我們可以通過 actions 異步提交 mutations 去 修改 state 的值并通過 getter 獲取**。 需要注意的是不是每一個項目都適合使用 Vuex,如果你的項目是中大型項目,那么使用 Vuex 來管理錯綜復雜的狀態數據是很有幫助的,而為了后期的拓展性和可維護性,這里不建議使用 CLI 生成的一份配置文件來管理所有的狀態操作,我們可以把它拆分為以下目錄: ``` └── store ├── index.js # 我們組裝模塊并導出 store 的地方 ├── actions.js # 根級別的 action ├── mutations.js # 根級別的 mutation └── modules ├── moduleA.js # A模塊 └── moduleB.js # B模塊 ``` ![](https://img.kancloud.cn/24/b9/24b974c1f2dcb194c2adfb2effb1d98d_885x301.gif) 與單個 store.js 文件不同的是,我們按模塊進行了劃分,每個模塊中都可以包含自己 4 個核心功能。比如模塊 A 中: ``` /* moduleA.js */ const moduleA = { state: { text: 'hello' }, mutations: { addText (state, txt) { // 這里的 `state` 對象是模塊的局部狀態 state.text += txt } }, actions: { setText ({ commit }) { commit('addText', ' world') } }, getters: { getText (state) { return state.text + '!' } } } export default moduleA ``` 上方我們導出 A 模塊,并在 index.js 中引入: ``` /* index.js */ import Vue from 'vue' import Vuex from 'vuex' import moduleA from './modules/moduleA' import moduleB from './modules/moduleB' import { mutations } from './mutations' import actions from './actions' Vue.use(Vuex) export default new Vuex.Store({ state: { groups: [1] }, modules: { moduleA, // 引入 A 模塊 moduleB, // 引入 B 模塊 }, actions, // 根級別的 action mutations, // 根級別的 mutations // 根級別的 getters getters: { getGroups (state) { return state.groups } } }) ``` 這樣項目中狀態的模塊劃分就更加清晰,對應模塊的狀態我們只需要修改相應模塊文件即可。詳細的案例代碼可參考文末 github 地址。 ### 3\. 接口配置 在項目的開發過程中,我們也少不了與后臺服務器進行數據的獲取和交互,這一般都是通過接口完成的,那么我們如何進行合理的接口配置呢?我們可以在 src 目錄下新建 services 文件夾用于存放接口文件: ``` └── src └── services ├── http.js # 接口封裝 ├── moduleA.js # A模塊接口 └── moduleB.js # B模塊接口 ``` 為了讓接口便于管理,我們同樣使用不同的文件來配置不同模塊的接口,同時由于接口的調用 ajax 請求代碼重復部分較多,我們可以對其進行簡單的封裝,比如在 http.js 中(fetch為例): ``` /* http.js */ import 'whatwg-fetch' // HTTP 工具類 export default class Http { static async request(method, url, data) { const param = { method: method, headers: { 'Content-Type': 'application/json' } }; if (method === 'GET') { url += this.formatQuery(data) } else { param['body'] = JSON.stringify(data) } // Tips.loading(); // 可調用 loading 組件 return fetch(url, param).then(response => this.isSuccess(response)) .then(response => { return response.json() }) } // 判斷請求是否成功 static isSuccess(res) { if (res.status >= 200 && res.status < 300) { return res } else { this.requestException(res) } } // 處理異常 static requestException(res) { const error = new Error(res.statusText) error.response = res throw error } // url處理 static formatQuery(query) { let params = []; if (query) { for (let item in query) { let vals = query[item]; if (vals !== undefined) { params.push(item + '=' + query[item]) } } } return params.length ? '?' + params.join('&') : ''; } // 處理 get 請求 static get(url, data) { return this.request('GET', url, data) } // 處理 put 請求 static put(url, data) { return this.request('PUT', url, data) } // 處理 post 請求 static post(url, data) { return this.request('POST', url, data) } // 處理 patch 請求 static patch(url, data) { return this.request('PATCH', url, data) } // 處理 delete 請求 static delete(url, data) { return this.request('DELETE', url, data) } } ``` 封裝完畢后我們在 moduleA.js 中配置一個 github 的開放接口:`https://api.github.com/repos/octokit/octokit.rb` ``` /* moduleA.js */ import Http from './http' // 獲取測試數據 export const getTestData = () => { return Http.get('https://api.github.com/repos/octokit/octokit.rb') } ``` 然后在項目頁面中進行調用,會成功獲取 github 返回的數據,但是一般我們在項目中配置接口的時候會直接省略項目 url 部分,比如: ``` /* moduleA.js */ import Http from './http' // 獲取測試數據 export const getTestData = () => { return Http.get('/repos/octokit/octokit.rb') } ``` 這時候我們再次調用接口的時候會發現其調用地址為本地地址:`http://127.0.0.1:8080/repos/octokit/octokit.rb`,那么為了讓其指向 `https://api.github.com`,我們需要在 vue.config.js 中進行 devServer 的配置: ``` /* vue.config.js */ module.exports = { ... devServer: { // string | Object 代理設置 proxy: { // 接口是 '/repos' 開頭的才用代理 '/repos': { target: 'https://api.github.com', // 目標地址 changeOrigin: true, // 是否改變源地址 // pathRewrite: {'^/api': ''} } }, } ... } ``` 在 devServer 中 我們配置 proxy 進行接口的代理,將我們本地地址轉換為真實的服務器地址,此時我們同樣能順利的獲取到數據,不同點在于接口狀態變成了 304(重定向): ![](https://img.kancloud.cn/3e/91/3e91ca8fee0ea466145f3f404129df9f_810x127.gif) ### 4\. 公共設施配置 最后我們項目開發中肯定需要對一些公共的方法進行封裝使用,這里我把它稱之為公共設施,那么我們可以在 src 目錄下建一個 common 文件夾來存放其配置文件: ``` └── src └── common ├── index.js # 公共配置入口 ├── validate.js # 表單驗證配置 └── other.js # 其他配置 ``` 在入口文件中我們可以向外暴露其他功能配置的模塊,比如: ``` /* index.js */ import Validate from './validate' import Other from './other' export { Validate, Other, } ``` 這樣我們在頁面中只需要引入一個 index.js 即可。 ## 結語 本文介紹了 Vue 單頁應用的一些基本配置,從項目構建層面闡述了各文件的主要配置方式和注意點,由于本文并不是一篇文檔類的配置說明,并不會詳細介紹各配置文件的 API 功能,大家可以訪問文中列出的官方文檔進行查閱。 本案例代碼地址:[single-page-project](https://github.com/luozhihao/vue-project-code/tree/master/single-page-project) ## 思考 & 作業 * devServer 中 proxy 的 key 值代表什么?如果再添加一個 `/reposed` 的配置會產生什么隱患? * 如何配置 webpack 使得 `require.ensure()` 拆分出的 js 文件具有自定義文件名?
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看