vue2项目升级到vue3经历分享2

升级的代价并不是那么简单,一篇文章vue2项目升级到vue3经历分享1,只好再写一篇。
1 cdn使用
在vue2中cdn使用,在public中放入js,如果cdn失效则取本地的js
1
vue.config.js中指定外部cdn资源的分发
1
在vue3中使用yarn add vite-plugin-cdn-import --dev,然后在vite.config.ts中配置

import cdn from 'vite-plugin-cdn-import'
cdn({
        modules: [
          {
            name: "element-plus",
            var: "ElementPlus",
            path: "https://cdn.jsdelivr.net/npm/element-plus@2.2.32/dist/index.full.min.js",
          },
          {
            name:"echarts", // 按需引入echarts
            var: "echarts",   
            path: "https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js",
          },
          {
            name: "axios",
            var: "axios",
            path: "https://cdn.jsdelivr.net/npm/axios@1.6.1/dist/axios.min.js",
          },
          {
            name: 'vue',
            var: 'Vue',
            path: 'https://cdn.jsdelivr.net/npm/vue@3.3.8/dist/vue.global.min.js',
          },
          {
            name:'vue-router',
            var: 'VueRouter',
            path: 'https://cdn.jsdelivr.net/npm/vue-router@4.2.5/dist/vue-router.global.min.js',
          },
        ],
      }),

执行yarn build:dev后就可以看到打包的效果,即开发环境默认是不启用cdn的
1
哪些需要引用cdn呢,安装yarn add rollup-plugin-visualizer --save
vite.config.ts中配置

import {visualizer} from 'rollup-plugin-visualizer'
visualizer({
        filename: './bundle-visualizer.html',
        open: true,
        gzipSize: true,
      }),

在执行yarn build之后,就可以看到,哪些文件大,就那个文件使用cdn进行加速
1
发布到生产环境,并不能总能如愿的顺利,提示下面的错误

aria.ts:22 Uncaught TypeError: Cannot read properties of undefined (reading 'defineComponent')
    at aria.ts:22:19
    at index.full.min.js:1:240
    at index.full.min.js:1:268
(anonymous) @ aria.ts:22
(anonymous) @ index.full.min.js:1
(anonymous) @ index.full.min.js:1
index.min.js:3 Uncaught SyntaxError: Cannot use import statement outside a module (at index.min.js:3:28)
index.8942f36c.js:44 Uncaught ReferenceError: ElIcons is not defined
    at Object.install (index.8942f36c.js:44:2101)
    at Object.use (vue.global.js:5190:20)
    at index.8942f36c.js:44:3839
install @ index.8942f36c.js:44
use @ vue.global.js:5190
(anonymous) @ index.8942f36c.js:44
index.8942f36c.js:31 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'error')
    at index.8942f36c.js:31:128159
    at vue-router.global.js:3615:39
    at Array.forEach (<anonymous>)
    at z (vue-router.global.js:3615:20)
    at vue-router.global.js:3335:19
(anonymous) @ index.8942f36c.js:31
(anonymous) @ vue-router.global.js:3615
z @ vue-router.global.js:3615
(anonymous) @ vue-router.global.js:3335
Promise.then (async)
L @ vue-router.global.js:3336
I @ vue-router.global.js:3262
(anonymous) @ index.8942f36c.js:31
await in (anonymous) (async)
(anonymous) @ vue-router.global.js:1991
(anonymous) @ vue-router.global.js:1963
runWithContext @ vue.global.js:5298
D @ vue-router.global.js:3387
(anonymous) @ vue-router.global.js:3739
Promise.then (async)
(anonymous) @ vue-router.global.js:3739
ne @ vue-router.global.js:3739
(anonymous) @ vue-router.global.js:3413
Promise.then (async)
V @ vue-router.global.js:3406
L @ vue-router.global.js:3328
L @ vue-router.global.js:3304
I @ vue-router.global.js:3262
install @ vue-router.global.js:3701
use @ vue.global.js:5190
(anonymous) @ index.8942f36c.js:44
index.8942f36c.js:44 Uncaught (in promise) ReferenceError: ElIcons is not defined
    at Object.install (index.8942f36c.js:44:2101)
    at Object.use (vue.global.js:5190:20)
    at index.8942f36c.js:44:3839

这个问题说明上面cdn配置,各js是有加载顺序,不能随便的写,vue的引入,要在element-plus之前
1

2 vite编译
2.1 多余标签的问题
下面的代码,在webpack中可以build通过,但是在vite中是不行,明显是代码错误,但是开发工程师却忽略了。
1
2.2 v-model cannot be used on a prop
是因为 prop 是单向数据流,父组件向子组件传递值,子组件不应直接修改这些值

 ERROR  error during build:                                                                                                          11:09:35
SyntaxError: v-model cannot be used on a prop, because local prop bindings are not writable.
Use a v-bind binding combined with a v-on listener that emits update:x event instead.
    at createCompilerError (E:\workspace\vuework\acc3\node_modules\@vue\compiler-core\dist\compiler-core.cjs.js:18:17)
    at Object.transformModel (E:\workspace\vuework\acc3\node_modules\@vue\compiler-core\dist\compiler-core.cjs.js:5052:21)

处理方案
2
2
然后watch其变化即可
1
2.3 expects exactly one child element or component.
期望仅有一个子元素或组件作为其内容,但你可能提供了多个子元素或没有提供任何子元素
1
处理方案如下,按照下面进行拆分

 <transition name="fade-transform" mode="out-in">
      <tax-declaration ref="taxDeclaration" @change='change' v-if="isShow"/>
    </transition>
    <transition name="fade-transform" mode="out-in">
      <tax-add ref="taxAdd" @change='change' v-if="!isShow"/>
    </transition>

2.4 [vite:vue] v-model value must be a valid JavaScript member expression.
跟2.2一张,只是这是设置一个对象作为参数。
1
2.5 图片加载问题
下面的处理方式在vue3和vite架构中是不支持的

.voucher_debit {
      background: url("~@/assets/voucher/格.png");
      background-repeat: repeat-y;
      background-size: 100%;
    }

调整为

.voucher_debit {
      background: url("@/assets/voucher/ge.png");
      background-repeat: repeat-y;
      background-size: 100%;
    }

3 element-plus相关
3.1 table找不到doLayout问题
element-ui有的doLayout
1
即使调整为 this.$nextTick(,调试发现that.$refs.table还是为空
1
3.2 el-form-item__label问题
element-plus下写法有些变化,
1
element-ui下面就有
1
原先写法

<span slot="label">
            <span class="span-box" >
              <!-- <i class="iconfont iconicon1-12" /> -->
              <span> 账套启用年月 </span>
            </span>
          </span>

应调整为

<template #label>
            <span >
            <span class="span-box" >
              <!-- <i class="iconfont iconicon1-12" /> -->
              <span> 账套启用年月 </span>
            </span>
          </span>
          </template>

3.3 <el-popover调整
涉及slot="reference"改造,否则显示不出来

<el-button class="btn" type="text" style="color: #4f71ff;" slot="reference">备注</el-button>

应调整为

<template #reference>
                    <el-button class="btn" type="text" style="color: #4f71ff;">备注</el-button>
                    </template>

el-selectel-date-picker等需要添加:teleported="false",如下。否则el-popover自动关闭

<el-select v-model="form.startPeriod" class="filter-item" :teleported="false">
                  <el-option v-for="item in periodOptions" :key="item.period" :label="item.periodFormat" :value="item.period" />
                </el-select>

3.3 日期picker-options被弃用
看似是一个很简单的日期初始化,初始化为当前日期,结果出现了一个2024-02-01,搞不清楚换成element-plus后,是怎么赋值上去的。

<el-date-picker v-model="voucher.vDate" type="date" placeholder="选择日期" class="w185" @change="dateChange" :clearable='false' value-format="yyyy-MM-dd HH:mm:ss" :picker-options="pickerOptions"> </el-date-picker> 

1
之所以出现这个问题,一定是出在:picker-options="pickerOptions",因为不可能一个默认值都会出错,推论是element-plus将这个属性废弃了,查看官网果然没有此属性,取而代之的是disabled-date

pickerOptions(time){
        // 日期界定
        return this.dataList && this.dataList.length > 0 ? this.disabledDate(time) : this.disabledBindTime(time)
      },
 disabledDate(time) {  //结转当月
        const timeFormat = moment(time).format('YYYY-MM-DD')
        if (this.dataList.length > 0) {
          if (this.dataList.indexOf(timeFormat) >= 0) {
            return false
          }
          return true
        } else {
          return false
        }
      },

禁用日期现在好了,但是初始化日期的问题依旧没有解决。
在这里插入图片描述
这样只有一种可能就是出现再value-format上,element-plus不支持yyyy-MM-dd这种写法,改用YYYY-MM-DD,这样日期就对了。
下面的日期也有问题
1
同样的原因,element-plus日期格式需要写成全大写的。
1

3.4 el-checkbox-group样式问题
样式问题需要跟踪是怎么被覆盖的。
q
跟踪css中盒子模型,发现高度为0.对比应该是少了line-height,当然这个问题看似element-plus关系并不大
1
接着可以推测出less加载有问题,查看页面资源,发现有
1
继续调试样式发现.el-checkbox-group 把行高给重置为0了。
1
而elemetnui中是没有这个样式的,最终确认还是兼容性问题
1
于是重写一下,这样的问题,在列表界面给el-checkbox-group增加行高

  .el-checkbox-group{
    line-height: 40px;
  }

3.5 ElementPlusError: [ElAutocomplete] autocomplete suggestions must be an array
同样的代码一直到element-plus,那基本可以推断就是兼容性问题了。在下面的回调方法中添加[]问题处理
1
3.6 el-col自定义宽度
element-uiel-col中可以定义style,从而自定义设置宽度,但是这样就破坏自身的栅格系统。
1
其实这种情况完全可以避免,使用:span就可以,没必要这样搞。不清楚为什么工程师当初为什么要这么做。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

warrah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值