這次帶給大家如何優化Vue項目,優化Vue項目的注意事項有哪些,以下就是實戰案例,一起來看一下。
Vue 類別的專案開發中專案結構基本上都是類似Vue-cli 產生的方式,這種方式開發中,最常用到的模式是開啟代理進行mock 偵錯或遠端偵錯,也就是使用了Vue-cli 設定的設定proxyTable 或直接使用Webpack-dev-server提供的proxy 選項。它是採用了http-proxy 函式庫,所以具體配置可查看:
https://github.com/nodejitsu/node-http-proxy#options
利用設定的這些參數我們可以做更靈活的配置,達到更好的效果
使用需求
假設我們目前本地開發以下幾種狀態:
本地開發,資料使用本地的mock Server
#涉及權限介面使用本機mock 數據,其他全部使用指定的一台遠端機器
涉及權限介面使用本機mock 數據,其他數據分接口使用不同的遠端機器
所有介面使用同一台遠端機器
方案
先看下經典的proxyTable 寫法:
proxyTable: { '/authui/': { target: target, changeOrigin: true }, '/vendor/': { target: target, changeOrigin: true } }
其中用到了changeOrigin 字段,主要是用於改變請求的header。細化下需求:
本地開發:target 指向 localhost 的某個連接埠即可。至於host 的驗證肯定是不需要的
部分本地,其他固定的一台遠端機器:需要設定localhost 和遠端的位址,遠端位址多半是需要驗證host 的
同二,但機器有多台:需要手動配置多台機器
#同一台遠端機器,此時機器可能要嚴格驗證,即IP 也必須使用域名,配置好系統host 才可使用
說明:嚴格驗證host 和普通驗證host 區別主要在於嚴格驗證時,請求的url 必須是遠端機器的域名,
無法直接修改要求的header 的host 實現,即必須在系統host 層級配置好域名。
分析完成具體需求好,就開始準備實現的方式。原始開發方式是執行 npm run dev
,如果我們需要在命令列層級新增配置,就需要設定為 npm run dev --param=paramvalue
的方式。對於使用npm 的script
腳本執行的命令,
它參數的獲取無法透過process.env 獲得,而且透過 process.env.npm_config_paramName
的方式獲取,
使用現成的命令列參數解析庫也不是很方便,但為了省事,暫時還是使用npm 自帶的解析。
請求發起過程中需要以下幾個參數:
host: 發起請求需要指向的host,可能每台機器驗證並不相同
#port: 代理轉發的連接埠
receiver: 用於push 的遠端位址,內包含了ip 位址,為了省事,沒有單獨列出ip 位址
然後定義代理程式請求自訂類型,用於設定:
#local: 本機位址,即localhost
remote: 指定的遠端機器
其他自訂類型:用於在設定檔中已經指定的其他類型
原版本的請求,如'http://xxx' 或Object 類型的配置,此類代理永不處理
#根據需要,我們添加以下幾個參數用於控制代理指向位址:
rd: 遠端機器的位址
#focus: 嚴格模式,所有自訂類型的代理轉換為指定的rd 機器,只有在存在rd 參數時可用
allLocal:自訂類型代理程式全部指向本地
host:請求發現是否使用host,而不是IP 位址
總結一下(序號指向前面的需求):
需要使用host 來存取的情況:4
需要更改 host:除 localhost 外都需要更改
需要对已有类型进行转换:1: 需要将所有自定义类型都转换为 local, 2和3:什么也不转换,4:所有的自定义类型全部转换为
remote 类型
这么一看,貌似 host 是不需要的,它的存在主要是针对某些 机器可能需要使用 host 的方式,所以还是保留一下。
实现
逻辑理清了就很简单了,配置文件设置为:
module.export = { rd1: { host: 'dev1.example.com', port: 8838, receiver: 'http://1.1.1.1:8888/receiver' }, rd2: { host: 'dev2.example.com', port: 8838, receiver: 'http://1.1.1.1:8888/receiver' } }
proxyTable 配置方式
{ proxyTable: { '/api1': 'remote', '/api2': 'rd2', '/auth/xx': 'local', '/other': 'http://example.com' } }
获取 proxyTable 的代码:
// 处理 proxyTable const releaseConfig = require('../config/release.conf.js') const rdConfig = releaseConfig[process.env.npm_config_rd] const isAllRemote = process.env.npm_config_focus const useHost = isAllRemote || process.env.npm_config_host // 是否本机开发,本机开发 remote 会指向 local const isAllLocal = process.env.npm_config_allLocal module.exports = function (proxy) { const localUrl = `http://localhost:${proxy.localProxyPort}` const defaultHost = proxy.defaultRdHost || 'dev-example.com' const localProxyPort = proxy.localProxyPort || 8787 const finalConfig = formatReleaseConfig(releaseConfig) const remote = finalConfig.remote || {} if (process.env.npm_config_rd) { if (!rdConfig) { throw new TypeError('RD 机器名称不存在,请在 config/release.conf.js 中进行配置') } if (!remote.ip) { throw new Error('请配置 rd 机器的 receiver') } } if (isAllRemote && !rdConfig) { throw new TypeError('focus 只能在提供了 rd 名称后可设置') } function formatReleaseConfig (config) { const result = {} Object.keys(config).map((key) => { const value = config[key] const ipMatch = (value.receiver || '').match(/:\/\/(.*?):\d/) const ip = ipMatch && ipMatch[1] result[key] = { ip, host: value.host || defaultHost, port: value.port || '8391' } }) // 设置 remote if (rdConfig) { const ipMatch = (rdConfig.receiver || '').match(/:\/\/(.*?):\d/) const ip = ipMatch && ipMatch[1] result.remote = { ip, host: rdConfig.host || defaultHost, port: rdConfig.port || '8391' } } // 设置 local result.local = { ip: 'localhost', host: 'localhost', port: localProxyPort } return result } function setProxy (proxyTable) { const result = {} Object.keys(proxyTable).forEach((api) => { let type = proxyTable[api] const isCustomType = typeof type === 'string' && !/^http/.test(type) if (isCustomType && type !== 'remote' && type !== 'local' && !finalConfig[type]) { throw new TypeError(`代理类型${type}不正确,请提供 http 或 https 类型的接口,或者指定正确的 release 机器名称`) } if (type === 'remote' && !finalConfig.remote) { type = 'local' } if (isCustomType) { if (isAllRemote && type !== 'remote') { type = 'remote' } if (isAllLocal && type !== 'local') { type = 'local' } } const targetConfig = finalConfig[type] let target = type if (targetConfig) { target = { target: `http://${useHost ? targetConfig.host : targetConfig.ip}:${targetConfig.port}`, // 使用 host 时需要转换,其他不需要转换 headers: { host: `${targetConfig.host}:${targetConfig.port}` } } } result[api] = target }) return result } return { proxyTable: setProxy(proxy.proxyTable), host: remote.host || defaultHost } }
用法
用法中需要配置两种指向:系统 host 和浏览器代理 Host。
之所以要两种 host, 本质上是因为接口使用的域名
和我们的本地访问的域名是相同的,同一域名无法指向两个地址,所以相当于对浏览器端进行了拦截。
系统 host 推荐使用 switchHost 进行切换,浏览器推荐使用 whistle 进行切换。
本地开发
host 配置:无
whistle 配置:默认的域名
127.0.0.1 dev.example.com
启动命令:
npm run dev npm run dev --allLocal
注: 此时 proxyTable 中配置的 remote 全部转换为 local,在 allLocal 参数时将所有自定义类型转换为 local
本地 + 1 台远程
host 配置:无 whistle 配置:默认的域名 127.0.0.1 dev1.example.com 127.0.0.1 dev2.example.com
启动命令:
npm run dev --rd=rd1 npm run dev --rd=rd1 --host
注: --host 表示使用访问使用 host 而非 ip,使用时需要 host 地址
本地 + n 台远程
host 配置:无
whistle 配置:默认的域名
127.0.0.1 dev1.example.com
127.0.0.1 dev2.example.com
{ proxyTable: { '/api1': 'rd1', '/api2': 'rd2', '/auth/xx': 'local', '/other': 'http://example.com' } }
proxyTable 配置:
启动命令:
npm run dev
远程 1 台机器
host 配置:
1.1.1.1 dev1.example.com 1.1.1.1 dev2.example.com
whistle 配置:默认的域名
127.0.0.1 dev1.example.com 127.0.0.1 dev2.example.com
启动命令:
npm run dev --rd=rd1 --focus
组件优化
vue 的组件化深受大家喜爱,到底组件拆到什么程度算是合理,还要因项目大小而异,小型项目可以简单几个组件搞定,甚至不用 vuex,axios 等等,如果规模较大就要细分组件,越细越好,包括布局的封装,按钮,表单,提示框,轮播等,推荐看下 Element 组件库的代码,没时间写这么详细可以直接用 Element 库,分几点进行优化
•组件有明确含义,只处理类似的业务。复用性越高越好,配置性越强越好。
•自己封装组件还是遵循配置 props 细化的规则。
•组件分类,我习惯性的按照三类划分,page、page-item 和 layout,page 是路由控制的部分,page-item 属于 page 里各个布局块如 banner、side 等等,layout 里放置多个页面至少出现两次的组件,如 icon, scrollTop 等
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上是如何優化Vue項目的詳細內容。更多資訊請關注PHP中文網其他相關文章!