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>