vue1升级vue2踩坑指南
vue1升级vue2踩坑指南
- 升级原因
- 版本选择
- 老的package.json:
- 新的package.json:
- vue官方说明
- 语法/组件使用变化
- ready钩子
- $index & $key
- limitBy
- v-html
- events
- vue-router
- redirect
- 注册路由&动态配置路由
- v-link
- 监听路由
- vue-validator
- 全局注册绑定vee-validate & 报错信息支持多语言
- vue-validator和vee-validate的简单使用对比
- vue-i18n
- 最后
升级原因
15年的老项目,还是使用的fis3来构建项目。去年底换到mac开发后在macos12环境下无法使用热更新,每次需要保存后重新暂停服务再启动服务很费时间。。。。且fis3官方已经不再维护相关组件也已经很兼容了,,,寻找解决方案无果后长痛不如短痛,直接换webpack吧
版本选择
最终vue版本为2.1.0此版本刚好可以使用vue-loader10.0.1版本其他的似乎都会报错。vue-template-compiler和vue版本对应即可
老的package.json:
{"name": "faq","version": "1.0.0","description": "description","main": "main.js","dependencies": {"normalize.css": "^4.0.0","v-viewer": "^1.6.3","viewerjs": "^1.10.2","vue": "^1.0.16","vue-i18n": "^4.7.1","vue-image-swipe": "^1.0.5","vue-resource": "^0.7.4","vue-router": "^0.7.11","vue-toasted": "^1.1.28","vue-touch": "^1.0.2","vue-validator": "^2.0.0","vueify-insert-css": "^1.0.0"},"devDependencies": {"babel-plugin-add-module-exports": "^0.1.2","babel-plugin-transform-es3-member-expression-literals": "^6.8.0","babel-plugin-transform-es3-property-literals": "^6.8.0","babel-plugin-transform-runtime": "^6.1.2","babel-preset-es2015": "^6.5.0","buffer": "^4.5.1","fis-parser-babel": "xiangshouding/fis-parser-babel","fis-postprocessor-autoprefixer": "0.0.5","fis3-command-inspect": "^1.0.3","fis3-deploy-replace": "^1.0.2","fis3-deploy-skip-packed": "0.0.3","fis3-hook-commonjs": "^0.1.10","fis3-hook-node_modules": "^1.0.11","fis3-hook-npm": "^1.0.1","fis3-hook-relative": "^1.0.6","fis3-parser-vue": "^0.1.0","fis3-postpackager-loader": "^1.3.13","is-buffer": "^1.1.3","process": "^0.11.2","vue-hot-reload-api": "^1.3.2"},"scripts": {"test": "echo \"Error: no test specified\" && exit 1","dev": "fis3 release -wL","build-test": "rm -rf ./dist/test && fis3 release test","build": "rm -rf ./dist/prod && fis3 release prod"},"author": "author"
}
新的package.json:
{"name": "faq","version": "1.0.1","private": true,"scripts": {"serve": "vue-cli-service serve","build": "vue-cli-service build","lint": "vue-cli-service lint"},"dependencies": {"@babel/preset-env": "^7.18.2","babel-eslint": "^10.1.0","core-js": "^3.8.3","fastclick": "^1.0.6","jquery": "^3.6.0","normalize.css": "^4.0.0","url-loader": "^2.3.0","v-viewer": "^1.6.4","vee-validate": "^2.2.15","vue": "^2.1.0","vue-i18n": "^5.0.3","vue-loader": "^10.0.1","vue-resource": "^0.7.4","vue-router": "^3.5.0","vue-touch": "^2.0.0-beta.4"},"devDependencies": {"@babel/core": "^7.12.16","@babel/eslint-parser": "^7.12.16","@vue/cli-plugin-babel": "~5.0.0","@vue/cli-plugin-eslint": "~5.0.0","@vue/cli-service": "~5.0.0","eslint": "^7.32.0","eslint-plugin-vue": "^8.0.3","vue-template-compiler": "^2.1.0"},"eslintConfig": {"root": true,"env": {"node": true},"extends": ["plugin:vue/essential","eslint:recommended"],"parserOptions": {"parser": "@babel/eslint-parser"},"rules": {}},"browserslist": ["> 1%","last 2 versions","not dead"]
}
vue官方说明
vue升级指南
从官方的说明中可以看出变化其实还是(不多的) 很多的…
语法/组件使用变化
这里只赘述我遇到的问题了,我没遇到的我就不写了
ready钩子
ready钩子移除了 可以替换为mounted钩子 效果不变
$index & $key
<!-- vue1写法 -->
<div v-for="item in items">{{$index}}
<div>
<!-- vue2写法 -->
<div v-for="(item, index) in items">{{index}}
<div>
limitBy
<!-- vue1写法 -->
<p v-for="item in items | limitBy 10">{{ item }}</p>
<!-- vue2写法 也可以选择官方那种computed写法-->
<p v-for="item in items.slice(0, 10)">{{ item }}</p>
v-html
<!-- vue1写法 -->
<p>{{{ data }}}</p>
<!-- vue2写法 -->
<p v-html="data" />如果之前有使用过滤器的话 也要改一下写法
vue2似乎对html的模板也有要求,之前是可以在template渲染的,现在必须为真实渲染的标签div,span等
<!-- vue1写法 -->
<p>{{{ data | highlight keyword}}}</p>
<!-- vue2写法 -->
<p v-html="$options.filters.highlight(data, keyword)" />
events
events钩子移出了,我选择使用eventbus去注册监听事件 使用eventbus时要注意及时销毁,不然会重复注册
#main.js
window.eventHub = new Vue()#faq.vue
mounted(){eventHub.$on('search', function(keyword){....})
},
beforeDestroy(){eventHub.$off('search', function(){ })
}#search.vue
eventHub.$emit('search', keyword)
vue-router
vue-router我选择直接使用3版本了,和2的变化不大反正都是从0.7升。。
redirect
router.redirect废弃了,要在注册路由时直接声明
{path: '/',redirect: '/faq'
}
注册路由&动态配置路由
我们项目本来使用了很多动态修改redirect的地方,本来想着可以通过router.addRoute动态去修改但是事实并不是像文档所说 而是会报一个重复定义路由的错误
所以这里我采用了(伪)动态路由的方法去实现,思路就是需要改变redirect时重置路由再赋值即可 虽说性能不好,但是实现功能还是没问题的!
import Vue from 'vue'
import VueRouter from 'vue-router'
import hotspotView from '../view/hotspot.vue'
import faqView from '../view/faq.vue'
import chatView from '../view/chat.vue'
import chooseIssueTypeView from '../view/choose-type.vue'
import createIssueView from '../view/create-issue.vue'
import messageListView from '../view/message-list.vue'
import messageView from '../view/message.vue'
import coinHistoryView from '../view/coin-history.vue'
import esHistoryView from '../view/es-history.vue'
import questionListView from '../view/question-list.vue'
import faqQuestionListView from '../view/faq-all-question.vue'
import cateTypeView from '../view/cate-type.vue'
import cateListView from '../view/cate-list.vue'
import cateDetailView from '../view/cate-detail.vue'
import helpView from '../view/help.vue'
import elementsView from '../view/elements.vue'
import elementsDetailView from '../view/elements-detail.vue'
import texiaoView from '../view/texiao.vue'
import texiaoDetailView from '../view/texiao-detail.vue'
import daojuView from '../view/daoju.vue'
import daojuDetailView from '../view/daoju-detail.vue'
import elegroup from '../view/elegroup'
import esTransferPlatform from '../view/es-transfer-platform.vue'
import defaultRealname from '../view/default-realname.vue'const routerView = {template: '<router-view keep-alive />'
}const routerViewWithoutKeepAlive = {template: '<router-view/>'
}Vue.use(VueRouter)const baseRoutes = [{path: '/faq',component: routerView,children: [{ path: '', name: 'faq', component: faqView}, { path: 'faq-all-question', name: 'faq-all-question', component: faqQuestionListView}]},{path: '/robot',name: 'chat',component: chatView},{path: '/help',name: 'help',component: helpView}
]
window.asyncRoutes = [{path: '/hotspot',component: routerView,children: [{ path: '', name: 'hotspot', component: hotspotView},{ path: 'question-list/:index', name: 'question-list', component: questionListView}]},{path: '/',name: 'home',redirect: '/faq'},{path: '/create-issue',component: routerViewWithoutKeepAlive,children: [{ path: '', name: 'issue-type', component: chooseIssueTypeView}, { path: ':issueType',component: createIssueView}]}
]
const createRouter = () => new VueRouter({routes: baseRoutes
})export const router = createRouter()// 先执行一遍添加 后续每次重置即可
for (let i = 0; i < window.asyncRoutes.length; i++) {router.addRoute(window.asyncRoutes[i])
}// 这地方为了提高可用性参数要传数组
export function addFaqRouter(datas) {datas.forEach(data => {for (let ii = 0; ii < window.asyncRoutes.length; ii++) {var item = window.asyncRoutes[ii]if (item && item.name && item.name == data.name) {Object.keys(data).forEach(k => {window.asyncRoutes[ii][k] = data[k]})} else if (item.children) {for (let jj = 0; jj < item.children.length; jj++) {var itemjj = item.children[jj]if (itemjj && itemjj.name && itemjj.name == data.name) {Object.keys(data).forEach(k => {window.asyncRoutes[ii]['children'][jj][k] = data[k]})}}}}})const newRouter = createRouter()router.matcher = newRouter.matcherfor (let i = 0; i < window.asyncRoutes.length; i++) {router.addRoute(window.asyncRoutes[i])}
}
重置路由操作
import { addFaqRouter } from '@/router'addFaqRouter([{path: '/',name: 'home',redirect: '/create-issue/default'}, {path: '/create-issue',name: 'create-issue',redirect: '/create-issue/default'}])
v-link
<!-- vue1写法 -->
<a class="faq" v-link="{ name: 'faq'}">{{$t('link.faq')}}</a><!-- vue2写法 -->
<router-link :to="{name:'faq'}" class="faq">{{ $t('link.faq') }}
</router-link>
监听路由
# data和deactivate移除掉了
<!-- vue1写法 -->
route: {data({ to: { query: { index } } }) {console.log(index)},deactivate() {console.log("deactivate")}
}
<!-- vue2写法 -->
mounted(){let index = this.$route.query.index;
},
beforeDestroy() {console.log("deactivate")
}
vue-validator
vue-validator神坑。。直接不支持vue2了。各个版本几乎都试过了在vue2上无论如何都跑不起来不是这错就是那错,最后选择使用vee-validate来替代了,使用后感觉相见恨晚啊。比vue-validator要好用不少!
全局注册绑定vee-validate & 报错信息支持多语言
main.js
import VeeValidate from 'vee-validate'
Vue.use(VeeValidate, { events: 'blur|change|input' })
validate.js
const dictionary = {en: {messages: {required: () => _faq.$t('form.requiredError'),min: (_, params) => _faq.$t('form.contentRequiredError', { count: params[0] }),phone: (_, params) => _faq.$t('form.phoneError'),decimal: (_, params) => _faq.$t('form.numberError')}}
}
const veeExtends = {phone: {validate: (value) => {return /^1[3456789][0-9]\d{8}$/.test(value)},getMessage: () => _faq.$t('form.phoneError')}
}
export default { dictionary, veeExtends }
由于要多语言支持,所以需要在vm加载后调用不然会报$t的错误,我目前在app.vue执行
import Vue from 'vue'
import vee from '@/assets/js/app/validate'
import { Validator } from 'vee-validate'
created(){window._faq = thisValidator.localize(vee.dictionary)for (const extend in vee.veeExtends) {Validator.extend(extend, vee.veeExtends[extend])}
}
vue-validator和vee-validate的简单使用对比
vue-validator
<span>{{ $validation['test'] && $validation['test'].errors | firstError }}</span>
<validator name="validation"><input type="text" :placeholder="placeholder"v-model="content.test" field="test" v-validate="{ minlength: { rule: 6,message: $t('form.contentRequiredError', { count: 6 }) },required: true}">
</validator>
vee-validate
{{ errors.first('test')}}
<input v-model="content.test" v-validate="required|min:6" type="text"
:placeholder="placeholder" name="test" >
是不是vee-validate更简单一点,且不需要重复定义错误信息初始化一次即可。
vue-i18n
如果之前使用的5.0.3之前的版本就建议切换到5.0.3此版本刚好支持到vue2.2。注册方式不变,Vue.local和vue.config.lang也可以正常使用!强烈推荐!!
最后
虽说vue本身的变化并不多,但是项目使用的组件适配性以及他们相关的变化加起来还是有很客观的工作量。。本来我还认为我们这是个小项目,现在我不认为了
vue1升级vue2踩坑指南相关推荐
- 墨瞳漫画 升级vue2 踩坑
概述 升级的话呢,还是比较简单,就按官方文档来,改写一下某些api,本文主要讲文档中说的不清晰的一些坑 vue-router 官方文档中推荐使用watcher来监测$route的改变,当路由变化时就去 ...
- pytorch .item_从数据到模型,你可能需要1篇详实的pytorch踩坑指南
原创 · 作者 | Giant 学校 | 浙江大学 研究方向 | 对话系统.text2sql 熟悉DL的朋友应该知道Tensorflow.Pytorch.Caffe这些成熟的框架,它们让广大AI爱好者 ...
- tabbar角标 小程序_【沃行课堂】恭喜你遇到“坑”,小程序踩坑指南
上周我们的开发小哥哥带领我们一起领略了开发中遇到的各种问题,以及基于SaaS模式的平台技术架构及实现.本周我们换个方向,由高级开发工程师秋哥带领大家共同探讨下小程序开发中踩过的坑.秋哥会从公司的几个小 ...
- android 字体文件压缩,Android 字体使用踩坑指南
Android 字体使用踩坑指南 最近项目改版,根据ui的设计,需要使用到三字体.在使用过程中遇到一些坑,于是有了这个避坑指南! 字体压缩 第一个坑!字体库的体积太大. 字体压缩的前提是要使用的内容是 ...
- weex 一个传说级巨坑-- 2018最新版weex踩坑指南(weex navigator 多界面跳转)
先说结论,本人极度非常 不推荐weex作为任何商用开发 有很多人会说了... 你瞎扯.. 你看别人阿里.. 啊飞猪... 啊那个支付宝... 人家不是用得好好的么... 当然这也是我们公司作为技术选型 ...
- 内网穿透,使用 IPv6 公网访问内网设备踩坑指南
本文是开启宽带 IPv6 功能并使用公网 IPv6 地址访问内网设备的踩坑指南.IPv6 是目前个人体验最优的内网访问方案,个人体验远胜过 ZeroTier,frp 等方案. 场景 将个人设备暴露于公 ...
- Git Commit Message校验踩坑指南
背景 在团队多人开发中,规范的commit message可以快速定位代码提交历史,回溯问题根源,方便组内多人协作,提高团队效率. 本篇文章主要包含以下两方面内容: commitizen/cz-cli ...
- MacBook通过XGP玩女神异闻录5皇家版不踩坑指南
XGP是微软Xbox游戏通行证服务,全称Xbox Game Pass,俗称西瓜皮. 女神异闻录5皇家版(P5R)登录了全平台,XGP会员可以通过云游戏在MacBook中游玩,本篇为MacBook玩P5 ...
- 联调中通wincall平台-踩坑指南
开发踩坑指南 初始化阶段 new CTIPlus({token: user.token, //tokenagentPhone: user.phone, //坐席工号或者手机号agNo: user.ag ...
最新文章
- 一步一步学习C#(一)
- SP2916 GSS5 - Can you answer these queries V
- JAVA 查找某个目录是否存在,如果存在,打印出来
- android旋转缩放布局,Android学习笔记(一):双指缩放及旋转计算
- Git撤销之世上真有后悔药
- MSP---企业上云需要考虑的问题
- 真实的网络赚钱经历:另类推广引流操作CPA!
- 基于2018年世界杯赛事法国队夺冠进球数据分析
- jQuery获取兄弟元素
- thinkpad x1e 隐士进入bios
- Hedgehog 信号通路与癌症
- scp命令上传文件到服务器
- wps不想让读个文档显示为多个标签页,而是打开多个窗口,方便多个文档的比对工作?
- 关于poi操作word,word转换pdf预览,这边文章就够了
- 开始创建第一个npm的微信小程序项目
- cpu要和gpu搭配吗_高端显卡一定要配高档CPU吗?
- 哥德尔不完全性定理 悖论式陈述 PM不可判定命题,和哥德尔可表达性定理——哥德尔读后之十八
- 【Bioinfo Blog 012】【R Code 010】——生存分析(Kaplan-Meier Cox)
- c#语言入门 刘老师,c#单元测试实例(学习刘老师视频)
- c语言程序点亮数码管,怎样点亮数码管
热门文章
- SDK:BUMO IOS SDK
- 10年编程无师自通(转)
- MATLAB优化转向器,汽车电动转向器动力学建模与控制仿真研究(MATLAB仿真)
- 【医疗健康项目】传智健康项目(五)
- FlyAI竞赛服务平台赛题上新——手写英文字体识别(名企内推)
- 离线解决Rabbitmq启动报“line 80: erl: command not found”
- 英语二阅读真题题型分布归纳和解题思路
- python 代理服务器 身份验证_如何使用Python+Selenium设置代理身份验证(用户和密码)...
- ThinkPHP+JQuery实现ajax无刷新登录验证(详解+相关问题)
- OpenCV 实现基于边界的模板匹配-适用部分覆盖和光照变化情况