新奇玩法!在Vue3中使用class component、注解和TSX!

问题引入

可能你看到标题会很奇怪,Vue3 不是已经不推荐在 Vue 中使用类组件了吗?因为类组件其实和 export default 选项式的对象写法本质差不多,但是这样不利于复用。在 Vue3 中主张的一个思想就是组合函数复用,只要有 setup 的地方就可以使用组合函数。

第二个问题,为什么要使用注解?

哦哦,可能是 Java 里面叫习惯了,JavaScript 中对应的是叫“装饰器”。使用类组件的时候,需要搭配注解来实现 Vue 对象的属性的声明以及注入,因为你用类声明了一个组件就没法像对象写法那样使用 Vue 的 API,所以得用注解。

第三个问题,为什么要用 TSX?

TSX 其实是 TypeScript + JSX 的组合。这没有为什么,因为是团队要求的。老项目就是使用 TSX,目前的工作量不足以支撑使用组合式 API 重构,仅仅是拿过来做 Vue3 的升级。

让我们开始

快速初始化一个脚手架项目

image.png

安装一下依赖,试试能不能跑起来。

image.png

安装vue-facing-decorators

要使用注解开发 Vue 项目,那么必须得装一下 vue-facing-decorator 这个库,它是 vue-property-decorator 的 Vue3 版本平替库。基本上都能支持原有的一些类和注解。

shell pnpm install vue-facing-decorator

来试着编写一个HelloWorld

在项目根目录创建一个 App.tsx 文件,编写如下代码:

```tsx import { Component, Vue } from 'vue-facing-decorator' import type { VNode } from 'vue'

@Component({ name: 'App' }) export class App extends Vue {

render(): VNode { return ( <> HelloWorld > ) } } ```

咦?怎么有点 Spring 的味道了?哈哈哈哈。

在 main.ts 文件中导入 App 类,代码修改如下:

```ts import './assets/main.css'

import { createApp } from 'vue' import { createPinia } from 'pinia'

import { App } from './App' import router from './router'

const app = createApp(App)

app.use(createPinia()) app.use(router)

app.mount('#app') ```

App.vue 去掉后缀 .vue 即可。

最后回到浏览器看一下效果:

image.png

可恶,竟然报错了。从报错的原因上看,好像是不支持注解,缺少 babel 的插件支持。

解决问题

在 Google 上搜了一圈,最后在 StackOverflow 上面找到了一个好的解决方案。想使用装饰器需要安装一个库,命令如下:

shell pnpm install --save-dev @babel/plugin-proposal-decorators

修改一下 vite.config.ts,在 vueJsx 插件函数的括号里面加上如下配置项,表示支持注解,legacy 是遗产的意思,笔者揣测是老版本的意思:

```ts import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' import VueDevTools from 'vite-plugin-vue-devtools'

export default defineConfig({ plugins: [ vue(), vueJsx({ babelPlugins: [[ '@babel/plugin-proposal-decorators', { legacy: true }, ]]
}), VueDevTools() ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } } }) ```

再回到浏览器,奇迹出现啦:

image.png

假如你不使用JSX

可能你会问,假如我不使用 JSX 呢?就用普通的类组件呢?

别急,一切问题都是有解决方案的。你需要安装一个第三方插件,国外开源社区大神的开发的 vite 插件,叫作 vite-plugin-babel:

shell pnpm install -D vite-plugin-babel

再修改一下 vite.config.ts 的配置:

```ts import { defineConfig } from 'vite'; import babel from 'vite-plugin-babel';

export default defineConfig({ plugins: [ babel({ babelConfig: { babelrc: false, configFile: false, plugins: [ [ "@babel/plugin-proposal-decorators", { loose: true, version: "2022-03" }, ], ], }, }), ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } } }); ```

这里引入了一个 babel 插件函数,在内部进行配置。按照这个方法应该可以的。

总结

虽然 Vue 官方已经不推荐类组件的写法而且在 Vue 中写 JSX 也很不推荐,但是就当作是一次小小的尝试吧,学习的经历。因为在项目管理中,需要评估项目的各种的风险,在时间紧张的情况下,就必然使用非同寻常的策略,这也不失为一种好的解决方法。以后的优化放在以后做(工作量又来了,又有一段时间不用担心失业咯,哈哈哈。)。

怎么样,你学会了吗?

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值