1.vue框架使用注意事項和經驗
1.1 解決Vue動態路由參數變化,頁面數據不更新vue
問題描述:node
遇到動態路由如:/page/:id 從/page/1 切換到 /page/2 發現頁面組件沒有更新webpack
解決方式1: 給<router-view :key="key">增長一個不一樣:key值,這樣vue就會識別這是不一樣的了。ios
<router-view :key="key"></router-view> ... computed:{ key(){ return this.$route.path + Math.random(); } }
解決方案2: 在組件內使用v2.2新增的beforeRouteUpdategit
beforeRouteUpdate (to, from, next) { // 在當前路由改變,可是該組件被複用時調用 // 舉例來講,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候, // 因爲會渲染一樣的 Foo 組件,所以組件實例會被複用。而這個鉤子就會在這個狀況下被調用。 // 能夠訪問組件實例 `this` },
1.2 vue組件裏定時器銷燬問題**github
問題描述:web
在a頁面寫一個定時器,每秒鐘打印一次,而後跳轉到b頁面,此時能夠看到,定時器依然在執行。 推薦的解決方式: 經過$once這個事件偵聽器器在定義完定時器以後的位置來清除定時器。vuex
const timer = setInterval(() => { // 定時器操做 }, 1000) // 經過$once來監聽定時器,在beforeDestroy鉤子能夠被清除。 this.$once('hook:beforeDestroy', () => { clearInterval(timer); })
也可使用生命週期聲明的方式:vue-cli
export default { beforeDestroy(){ clearInterval(timer); } }
1.3 vue實現按需加載組件的兩種方式**element-ui
1.使用resolve => require(['./ComponentA'], resolve),方法以下:
const ComponentA = resolve => require(['./ComponentA'], resolve)
2 使用 () => import(), 具體代碼以下:
const ComponentA = () => import('./ComponentA')
1.4 組件之間,父子組件之間的通訊方案
組件之間的通訊方案:
- 經過事件總線(bus),即經過發佈訂閱的方式
- vuex
- 父子組件:
- 父組件經過prop向自組件傳遞數據
- 子組件綁定自定義事件,經過this.$emit(event,params) 來調用自定義事件
- 使用vue提供的$parent/$children & $refs方法來通訊
- provide/inject
- 深層次組件間的通訊 $attrs, $listeners
1.5 vue中 $event 的用法--獲取當前父元素,子元素,兄弟元素
<button @click="「fun($event)」">點擊</button> ... methods: { fun(e) { // e.target 是你當前點擊的元素 // e.currentTarget 是你綁定事件的元素 #得到點擊元素的前一個元素 e.currentTarget.previousElementSibling.innerHTML #得到點擊元素的第一個子元素 e.currentTarget.firstElementChild # 得到點擊元素的下一個元素 e.currentTarget.nextElementSibling # 得到點擊元素中id爲string的元素 e.currentTarget.getElementById("string") # 得到點擊元素的string屬性 e.currentTarget.getAttributeNode('string') # 得到點擊元素的父級元素 e.currentTarget.parentElement # 得到點擊元素的前一個元素的第一個子元素的HTML值 e.currentTarget.previousElementSibling.firstElementChild.innerHTML } }
1.6 axios二次封裝http請求
import axios from 'axios' import router from '@/router' import {removeSessionStorage} from './storage'; import Vue from 'vue' import { Message } from 'element-ui' // 引用element-ui的加載和消息提示組件 // 請求超時時間配置 axios.defaults.timeout = 30000; // api地址配置 axios.defaults.baseURL = ""; // console.log(process.env.VUE_APP_BASE_API) Vue.prototype.$http = axios // 在全局請求和響應攔截器中添加請求狀態 let loading = null // 請求攔截器 axios.interceptors.request.use( config => { config.headers = { 'Content-Type': 'application/json' }; // loading = Loading.service({ text: '拼命加載中' }) let token = sessionStorage.getItem('-_token_-'); if (token) { config.headers['token'] = token; } return config }, error => { return Promise.reject(error) } ) // 響應攔截器 axios.interceptors.response.use( response => { if (loading) { loading.close() } // 自定義錯誤碼,各公司根據約定都不同 // 此處省略業務處理代碼 let errorCode = response.data.errCode; if(errorCode==='000000'){ return Promise.resolve(response.data); }else { router.push({ name: 'error', params: { isTimeout: false, path: router.currentRoute.path, desc: '您請求的資源找不到(錯誤碼:404) ', }, }); } }, error => { if (loading) { loading.close(); } // 此處省略業務處理代碼 return Promise.reject(error); } );
1.7 開發環境中代理的切換配置
爲了應對這樣的跨域場景,在代碼開發時,devServer要代理到本地後端,測試時,又要去修改代理到測試環境,上線後,調試新問題有可能代理到線上環境
該代碼運行環境爲node.js,使用process.env能夠獲取到系統環境變量,從而區分當前機器是公司的生產機器,仍是我的的開發機器
對vue.config.js的進行配置
const Timestamp = new Date().getTime(); //當前時間爲了防止打包緩存不刷新,因此給每一個js文件都加一個時間戳 const proxyTargetMap = { prod: 'https://xxx.xxx.com/', dev: 'http://192.168.200.230:6379', test: 'http://test.xxx.com', local: 'http://localhost:8080/' } let proxyTarget = proxyTargetMap[process.env.API_TYPE] || proxyTargetMap.local module.exports = { publicPath: process.env.NODE_ENV === 'production' ? '/' : '/', outputDir: 'dist', assetsDir: 'static', lintOnSave: false, // 是否開啓eslint保存檢測 productionSourceMap: false, // 是否在構建生產包時生成sourcdeMap // 調整內部的 webpack 配置。 // 查閱 https://github.com/vuejs/vue-docs-zh-cn/blob/master/vue-cli/webpack.md chainWebpack: () => { }, //configureWebpack 這部分打包文件添加時間戳,防止緩存不更新 configureWebpack: { output: { // 輸出重構 打包編譯後的 文件名稱 【模塊名稱.版本號.時間戳】 filename: `[name].${process.env.VUE_APP_Version}.${Timestamp}.js`, chunkFilename: `[name].${process.env.VUE_APP_Version}.${Timestamp}.js` }, }, devServer : { proxy: { '/api' : { target: proxyTarget, changeOrigin: true, pathRewrite: { '^/api' : '' } } } } };
對應的package.json配置爲
看下面的cross-env API_TYPE=dev
cross-env是一個全局命令行工具,能夠根據不一樣的平臺更改當前的環境變量,從而實現了能夠在開發者的機器上,選擇性的調用開發模式或者生產模式
"scripts": { "serve": "vue-cli-service serve --mode development", + "serve:dev": "cross-env API_TYPE=dev vue-cli-service serve --mode development", + "serve:test": "cross-env API_TYPE=test vue-cli-service serve --mode development", "build": "vue-cli-service build --mode production", "test": "vue-cli-service build --mode test", },
</router-view>