草庐IT

如何实现Vue2项目升级Vue3?

前端王睿 2023-09-22 原文

Vue3正式版已经发布有两年多了,如今它也已成为Vue的默认开发版本,如果你想要对之前Vue2项目进行升级重构,可以从以下几个维度入手:

① 构建工具
② 入口文件
③ 插件
④ 指令
⑤ 路由
⑥ 状态管理
⑦ 其他


一、构建工具

Vue3推荐使用Vite作为构建工具,相对Webpack来说Vite超快的热更新速度能极大提高开发效率,项目越大效果越明显。

1. 安装

npm i vite -g
npm create vite@latest

更多详情可以看我之前写的一篇文章 → Vue3+Vite初体验

初始项目结构大致如下:


然后我们可以将Vue2项目的src目录下的内容直接复制粘贴到新创建项目的src目录下,然后再继续接下来的重构操作。

2. 修改配置文件

默认配置文件vite.config.js如下:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()]
})

我们可以根据项目需求来新增一些内容,例如:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  base: './',  // 开发或生产环境服务的公共基础路径
  plugins: [vue()],
  resolve: {
    alias: {  // 配置路径别名
      '@': resolve('src')
    },
  },
  css: {
    preprocessorOptions: {   // css预处理器
      less: {
        // 引入全局的Less库,有关lib.less请看 → https://www.jianshu.com/p/b13e2a2204b2
        additionalData: '@import "./src/assets/less/lib.less";'
      },
    },
  }
})

这里需要注意的是,在Vue2项目配置vue.config.js中,我们是使用CommonJs的require()语法来导入相关依赖,而在Vue3项目配置vite.config.js中我们使用的是原生ES6的import语法来导入的。

二、入口文件

1. index.html

Vite项目的HTML入口文件是放在项目根目录下的,而且需要手动引入main.js才行,而main.js就是JS的入口文件。

<script type="module" src="./src/main.js"></script>

2. main.js

① 创建并挂载根实例

我们需要在main.js创建Vue实例,而Vue3创建实例的方式与Vue2有所不同,它使用的是createApp()来创建,例如:

import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);

然后我们还需要将创建的实例挂载在页面上显示出来:

app.mount("#app");

需要注意的是,Vue3中的挂载方法不再是$mount()而是mount()

② 使用路由和状态管理

如果需要用到路由和状态管理,我们还需要用到vue-routervuex,使用use()方法来注册。

import router from "./router";
import store from "./store";
app.use(router)
   .use(store);

有关routerstore实例的创建,后面内容会讲到。

3. App.vue

App.vue通常是作为页面根组件,我们会在其中放置路由组件<router-view>,而页面路由切换时我们可能会给其加上一些动画效果,比如渐隐渐现,我们就可以用到内置的<transition>组件来实现,例如:

<router-view class="page" v-slot="{ Component }">
  <transition name="route" mode="out-in">
    <component :is="Component"></component>
  </transition>
</router-view>

更多<transition>相关内容请查看 → https://router.vuejs.org/zh/guide/advanced/transitions.html

另外<keep-alive>组件在与<router-view>搭配使用时也类似,需要用到v-slot指令,例如:

<router-view class="page" v-slot="{ Component }">
  <keep-alive>
    <component :is="Component" />
  </keep-alive>
</router-view>

三、插件

插件定义方式与Vue2差不多,就是参数有所不同,例如:

export default {
    install(app, options) {
        // 注入一个全局可用的$isMobile()方法,用户判断是否是移动设备
        app.config.globalProperties.$isMobile = () => 'ontouchstart' in window;
    }
}

install()方法的第一个参数是Vue实例,我们可以向app.config.globalProperties中添加一些全局实例属性或方法,类似于Vue2中的Vue.prototype

四、指令

我们知道v-model不仅可以用在表单组件上,还能用在自定义组件上,但是在Vue3中v-model与Vue2不同,它是modelValue属性和update:modelValue事件的组合语法糖,例如:

<CustomInput v-model="searchText" />

它相当于:

<CustomInput
  :modelValue="searchText"
  @update:modelValue="newValue => searchText = newValue"
/>

组件内部定义:

<!-- CustomInput.vue -->
<script>
export default {
  props: ['modelValue'],
  emits: ['update:modelValue']
}
</script>

<template>
  <input
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
  />
</template>

五、路由

Vue Router从v3到v4在迁移的过程中可能改动地方比较多,这里只是简单例举了几个常见的变化,详情可以参考官方文档 → https://router.vuejs.org/zh/guide/migration/index.html#%E7%A0%B4%E5%9D%8F%E6%80%A7%E5%8F%98%E5%8C%96

1. 安装

npm install vue-router@4

2. 创建Router实例

import { createRouter, createWebHashHistory } from "vue-router";
export default createRouter({   // 替代之前的 new Router()
  history: createWebHashHistory(),  // 替代之前的 mode,这里使用的是hash模式
  routes: [
    {
      path: '/',
      component: () => import("@/views/Home/index.vue")
    }
  ],
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition;
    } else {
      return { top: 0 };  // 以前的x改成left,y改成top
    }
  }
});

六、状态管理

1. 安装

npm install vuex@next

2. 创建Store实例

import { createStore } from 'vuex';

export default createStore({  // 替代之前的 new Vuex.Store()
  state: {
  },
  mutations: {
  },
  actions: {
  }
});

七、其他

在Vue2项目升级Vue3的过程中,除了以上列举的那些常见需要注意修改的点之外,还有一些其他需要注意的,比如Vue3中删除了filter过滤器,如果之前项目中有用到的话,需要使用computedmethods中的方法替代;删除了一些API属性和方法,如$on()$off()$once()$set()$delete()$destroy()Vue.exend()$children等。


总结

最后,用一张表对本文简单地做个总结:

Vue2升级Vue3对照表

有关如何实现Vue2项目升级Vue3?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  8. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  9. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  10. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

随机推荐