我们在使用vue构建单页应用的时候,能给我们的效率带来很大的提升,但是紧随而来的也有一些新框架的问题。

1,比如我们公司在移动端微信上面的项目,如果所有项目都合并成一个,首页加载速度就会非常慢,所以我就去改webpack配置,把它变成多页应用。点击微信菜单后,只加载当前菜单项的所有内容,也就是以菜单项分为分页的标准,在当前菜单项里面通过vue的路由控制。

2,单页应用路由切换,微信的title不会改变,经过查阅资料,发现网上有一个解决方案,就是利用vue-wechat-title这个插件可以解决;

3,还有就是Vue使用动态组件或者router时,当多个视图使用/指向同一个组件时,如何能够生成多个新实例?比如文章页里面有个相关文章阅读,点击之后会一直复用文章页的组件,这个问题困扰我很久,网上查阅资料也没有具体的方法,在作者官网上市这么说的:

响应路由参数的变化

提醒一下,当使用路由参数时,例如从 /user/foo 导航到 user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。

复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch(监测变化) $route 对象:

const User = {template: '...',watch: {'$route' (to, from) {// 对路由变化作出响应...
    }}
}

道理说的很明白了,只要是同一个组件,不管你切换多少次,它都会共用一个数据模型,虽然通过路由监听的方式可以检测到同组件的路由切换,但是并没有什么卵用,因为它并没有解决创建多个数据实例的问题,每当切换页面的时候,页面都会去拉取页面,造成了请求和带宽的浪费,用户体验十分不好。那到底有没有解决办法呢?答案是肯定的。经过我不断地尝试,找到了一个解决办法,而且可行。具体思路就是我们通过自己去创建管理删除组件的实例,然后用vuex状态管理区存储它(这个也不是必选项,因为相同组件之间切换,组件的数据实例并不会销毁,切换页面后之前页面的数据依然可以使用)。我们通过在路由上面传递不同的参数来区分在不同路由的情况下来显示哪个数据实例。

这里面还有一些细节:

a:创建新路由页面的时候,要创建新实例;

b:返回路由后需要把当前的实例删除掉,不然会一直占用内存;

c:文章组件返回到列表组件,然后再进入文章组件后,文章组件实例不会再创建

解决办法:贴出我的具体代码

index.js

import Vue from 'vue';
import router from './router';
import store from './store';
import index from './components/index';
import vueWechatTitle from 'vue-wechat-title';Vue.use(vueWechatTitle);
Vue.config.productionTip = false;
//绑定vue
new Vue({el: '#contract',router,store,template: '<index/>',components: {index}
});

router.js

import Vue from 'vue';
import Router from 'vue-router';
import contractList from './components/contract-list';
import contractDetail from './components/contract-detail';Vue.use(Router);
const router = new Router({routes: [{path: '/',name: 'contractList',meta: {title: '合同列表',keepAlive:true},component: contractList},{path: '/contractDetail/:timestamp',name: 'contractDetail',meta: {title: '合同详情',keepAlive:true},component: contractDetail}]
});
export default router;

store.js

import Vue from 'vue';
import Vuex from 'vuex';Vue.use(Vuex);const state = {};
const actions = {};
const getters = {};
const mutations = {addData: (state, res) => {if (!state.hasOwnProperty(res.key)) {Vue.set(state, res.key, res.value);}console.log('set', state);},//增deleteData: (state, key) => {console.log(key);delete state[key];console.log('del', state);},//删updateData: (state, res) => {if (state.hasOwnProperty(res.key)) {for (let item in res.value) {state[res.key][item] = res.value[item];}}console.log('updateData', state);},//改getData: (state, key) => {if (state.hasOwnProperty(key)) {return state[key];} else {return null;}console.log('get', state);}//查
};export default new Vuex.Store({state,actions,getters,mutations
});

下面是模板页面

index.vue

<template><div id="contract"><keep-alive><router-view v-if="$route.meta.keepAlive" v-wechat-title="$route.meta.title"></router-view></keep-alive><router-view v-if="!$route.meta.keepAlive" v-wechat-title="$route.meta.title"></router-view></div>
</template>
<script>export default {data() {return {}},computed: {},created() {},mounted() {},methods: {},watch: {}}
</script>

contract-list.vue

<template><div id="contract-list"><input type="text" v-model="msg"><router-link :to="'/contractDetail/'+new Date().getTime()">点击进详情页</router-link></div>
</template>
<script>export default {data() {return {msg: ''}},computed: {},created() {},mounted() {},methods: {},watch: {}}
</script>
<style scoped>#contract-list {color: red;}
</style>

contract-detail.vue

<template><div id="contract-detail"><input type="text" v-if="currentData" v-model="currentData.msg"> 我是合同详情页<router-link :to="'/contractDetail/'+new Date().getTime()">进如下页详情</router-link>{{currentData}}</div>
</template>
<script>import {mapState} from 'vuex';export default {data() {return {}},computed: {currentKey() {return this.$route.name + this.$route.params.timestamp;},...mapState({currentData(state) {return state[this.currentKey];}})},created() {console.log('created');this.initModel();},mounted() {console.log('mounted');},methods: {createModel() {class model {constructor() {this.msg = '';}}return new model();},initModel() {this.$nextTick(function () {if (!this.$store.state.hasOwnProperty(this.currentKey)) {console.log('initModel-set');this.$store.commit('addData', {key: this.currentKey,value: this.createModel()});}});}},watch: {currentData: {handler: function (value) {console.log('watch-set', this.currentKey);this.$nextTick(function () {this.$store.commit('updateData', {key: this.currentKey,value: value});});},deep: true}},beforeRouteUpdate(to, from, next) {console.log('beforeRouteUpdate1', to, from);//清除老对象if (to.params.timestamp < from.params.timestamp) {this.$store.commit('deleteData', from.name + from.params.timestamp);}//创建新对象
      console.log('beforeRouteUpdate2', to, from);if (to.name == from.name) {console.log(to.name, from.name, to.name == from.name);this.initModel();}next();},beforeRouteLeave(to, from, next) {console.log('beforeRouteLeave', to, from);this.$store.commit('deleteData', from.name + from.params.timestamp);this.$destroy();next();}}
</script>
<style scoped>#contract-detail {color: green;}
</style>

转载于:https://www.cnblogs.com/pixel2012/p/7532451.html

vue踩坑以及自己的解决办法总结,相关推荐

  1. Vue踩坑 npm ERR code ELIFECYCLE

    Vue踩坑 npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! supermall@0.1.0 serve: vue-cli-service serv ...

  2. Vue 踩坑笔记: 引入 ElementUI 时打包失败修复记录(ERROR in ./node_modules/element-ui/lib/theme-chalk/index.css)

    Vue 踩坑笔记: 引入 ElementUI 时打包失败修复记录(ERROR in ./node_modules/element-ui/lib/theme-chalk/index.css Module ...

  3. vue 路由地址不跳转 解决办法

    这里写自定义** vue 路由地址不跳转 解决办法 这是我的报错原因,因为我是一个后端开发对vue不了解 我的报错原因是因为: menu.json 中的路径 path:****** name***** ...

  4. Vue运行出现Missing semicolon错误,解决办法

    vue出现 Missing semicolon错误,解决办法 用vscode开发vue项目,运行时出现Missing semicolon报错 通过命返回的错误可以看到,它提示我们是App.vue十一行 ...

  5. Vue踩坑之旅(一)—— 数组、对象的监听

    作为一个接触 vue 才一个多月的小白,马上就接手基于 vue 的大型商城项目,其间真是跌跌撞撞踩了好多坑(o(╥﹏╥)o).在此写下自己的踩坑之旅,希望给跟我一样还在自学 vue 的同学一些帮助,另 ...

  6. vue踩坑- 报错npm ERR! cb() never called!

    在vue项目中引入饿了么elementUI组件的步骤之中,出现以下的错误: D:\my-project-first>npm i element-ui -S Unhandled rejection ...

  7. 【seata系列】centos服务器带你踩坑搭建seata以及解决MySQL8.0无法启动问题

    目录 准备 配置 registry.conf file.conf 创建相关表和数据库 启动 踩坑 运行 准备 通过github下载安装包:https://github.com/seata/seata/ ...

  8. 移动硬盘安装ubuntu-16.04,疯狂踩坑、分析及解决方法

    一直想在移动硬盘里安装一个ubuntu系统,尝试了四五天,我想我基本各种问题都在踩坑,知识欠缺太多了,以防以后ubuntu再次崩溃,在这整理一篇在移动硬盘安装整个ubuntu-16.04的流程. 参考 ...

  9. vue history 微信jssdk授权失败解决办法

    bug再现: 前提保证后端签名都正确,我的是正确的,前端时不时会出现授权失败的情况. IOS微信访问vue history模式的页面, A页面,需要微信授权,调用jssdk使用扫描二维码接口,打开方式 ...

最新文章

  1. 一文了解神经网络的基本原理
  2. Github上删除fork的仓库
  3. IOS APP 国际化 程序内切换语言实现 不重新启动系统(支持项目中stroyboard 、xib 混用。完美解决方案)
  4. object references an unsaved transient instance【异常】
  5. (传送门)instant run原理
  6. HttpClient 教程 (二)
  7. 打了断点为直接运行完_黑社会行为?男子驾校身亡,家属看现场被保安围殴,手臂被打断...
  8. 《JavaScript》高级程序设计---第3章
  9. BZOJ2388: 旅行规划
  10. Matlab之abs、double与char函数
  11. 你必须知道:localStorage、sessionStorage 和 Cookie 区别在什么地方
  12. AAC 音频数据结构实例分析:
  13. Unity 制作旋转门 推拉门 柜门 抽屉 点击自动开门效果 开关门自动播放音效 (附带编辑器扩展代码)
  14. Tomcat学习之路
  15. 星期几—YYYY-MM-DD,表示一个日期,你知道是星期几吗?
  16. Python学习笔记(小甲鱼版)
  17. 很是惆怅,不知如何看待自己智能车竞赛获奖结果
  18. CDN是什么?CDN的作用
  19. Zigbee——协调器组建网络
  20. [转]九型人格的一句话描述

热门文章

  1. 工厂利用计算机实现温度调节属于,工厂利用计算机系统实现温度调节、阀门开关,该应用属于()。A.过程控制B.数据处理C.科学计算D.C...
  2. 计算机自带的桌面远程,如何远程控制电脑桌面
  3. MOne︱基于词包的无监督多主题得分 练习题
  4. qt msvc编译中文乱码解决
  5. FBI为车主支招:如何预防汽车黑客
  6. 原创:CSS3技术-雪碧图自适应缩放与精灵动画方案
  7. 动态多点*** 单云双HUB
  8. 17.和优化相关的hint
  9. 2013元旦成都九寨沟攻略
  10. vmware的原理和影子页表