Vue企业开发实战中的常见疑难问题
- 1. 解决Vue动态路由参数变化,页面数据不更新
- 2. vue组件里定时器销毁问题
- 3. vue实现按需加载组件的两种方式
- 4. 组件之间,父子组件之间的通信方案
- 5. Vue中获取当前父元素,子元素,兄弟元素
- 6. 开发环境中代理的切换配置
1. 解决Vue动态路由参数变化,页面数据不更新
- 问题描述:遇到动态路由,如:/page/:id 从/page/1 切换到 /page/2 发现页面组件没有更新。
- 解决方式1:router-view 上增加一个不同:key值,这样vue就会识别这是不同的了。
<router-view :key="key"></router-view>
...
computed:{
key(){
return this.$route.path + Math.random();
}
}
- 解决方案2: 在组件内使用v2.2新增的beforeRouteUpdate
- 在当前路由改变,但是该组件被复用时调用
beforeRouteUpdate (to, from, next) {
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
2. vue组件里定时器销毁问题
- 问题描述:在a页面写一个定时器,每秒钟打印一次,然后跳转到b页面,此时可以看到,定时器依然在执行。
- 推荐的解决方式:通过$once这个事件侦听器器在定义完定时器之后的位置来清除定时器。
const timer = setInterval(() => {
// 定时器操作
}, 1000)
// 通过$once来监听定时器,在beforeDestroy钩子可以被清除。
this.$once('hook:beforeDestroy', () => {
clearInterval(timer);
})
- 也可以使用生命周期声明的方式:
export default {
beforeDestroy(){
clearInterval(timer);
}
}
3. vue实现按需加载组件的两种方式
- 使用resolve => require([‘./ComponentA’], resolve),方法如下:
const ComponentA = resolve => require(['./ComponentA'], resolve)
- 使用 () => import(), 具体代码如下:
const ComponentA = () => import('./ComponentA')
4. 组件之间,父子组件之间的通信方案
- 常规的: props 与 $emit()。
- 通过事件总线(bus),即通过发布订阅的方式。
- vuex(多层次组件、多页面公用数据一般用这个)
- 使用vue提供的 $parent / $children & $refs方法来通信。
- provide/inject方案。
- 深层次组件间的通信 $attrs, $listeners。
5. Vue中获取当前父元素,子元素,兄弟元素
<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
}
}
6. 开发环境中代理的切换配置
- 为了应对这样的跨域场景,在代码开发时,devServer要代理到本地后端。
- 测试时,又要去修改代理到测试环境,上线后,调试新问题有可能代理到线上环境。
- 该代码运行环境为Node.js,使用 process.env 可以获取到系统环境变量。
- 从而区分当前机器是公司的生产机器,还是个人的开发机器。
- 对vue.config.js的进行配置:
// 当前时间为了防止打包缓存不刷新,所以给每个js文件都加一个时间戳
const Timestamp = new Date().getTime();
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",
},
- 各环境的打包也可以如上配置。
1. 希望本文能对大家有所帮助,如有错误,敬请指出
2. 原创不易,还请各位客官动动发财的小手支持一波(关注、评论、点赞、收藏)
3. 拜谢各位!后续将继续奉献优质好文
4. 如果存在疑问,可以私信我(文底有V)