劳动节就好好在家写代码了,毕竟我们现在居家就是在为国家做贡献,而且劳动节不劳动和咸鱼有什么区别,手动🐶保命。
前言
vue 3 刚出几个月,现在是一步一个坑,但是坑还是要填的,毕竟生活还是要继续的么。
目前 vue 3.x 基本上是已经可以工作了,刚出不久的那段时间还看👀到掘金上有人说生产上有 3.x ,对这种大佬只能佩服,毕竟新东西出来,光是想想出了问题,这么解决就是非常头疼的事情
比如我现在搭个脚手架基本就是一路爬过来的,还好目前还没开始深入开发,出的都是周边配套和类型这些小问题。
另外说和 react
很像的,我只能说,这不光是像,你们的代码估计都可以拷过来改改就能用了呢,看下完整的函数式组件的代码
不过 vue 的双向数据绑定用的很舒服,这个才是最主要的,毕竟手写 set 真的麻烦。
读书人的事情这么能叫抄呢?这叫借鉴,这叫共同进步 --- by 鲁迅
不过这种事情其实说多了也没意义,比如 python 和 js 或其他语言之间,你敢说没有互相借鉴。
而且前端的口号不就是:“走别人的路,让别人无路可走”,我们要团结一致,毕竟前端这个岗位真的很容易被替代掉,我们求发展,求稳定,技术人用实力说话,才能让这个岗位越走越远。
目前的脚手架的开发进度
基本上已经可以支持你跑,但是打包工具还在纠结,我喜欢 rollupjs,但是项目已经引入了 webpack,到底要不要再引一个新的,还在思考中
- 支持 [typescript][typescript] 语法开发
- 支持 [storybook][storybook] 构建 UI 组件
- 支持 [lerna][lerna] 管理工程
- 支持 [prettier][prettier] 格式化代码
- 支持 [typedoc][typedoc] 自动生成 api 文档
- 支持主题与组件分离
- 支持使用 sass,采用 bem 的方式编写样式
- 支持 rollup 或 webpack 构建工具打包
问题列表
问题一:选择 vue 包
这个不算问题,主要是第一次为了这么选择包而头疼,以前写 vue 组件,基本就是直接引入 vue 就行了,其他交给构建工具处理。
但是看到 vue 3 支持模块化了,就想着把 @vue/compiler-dom
作为框架依赖引入,项目中引入 vue
,结果坑到了自己。
中间出现了一些很诡异的事情,所以我现在不管是项目还是组件库都直接引入的 vue@next
,还有和 vue2
选择主文件的问题,不过这个目前应该都明白应该这么选择了
问题二:初期使用障碍,类型定义的问题
这个目前比较头大的时候,要么变成 AnyScript,要么别名一堆,虽然还有 js 可选,但是都有火了,为什么还要吃生的,不知道 0202 年开始禁野味了么。
我们在这里举个🌰,比如你的组件库是这样导出的
import type { App, Component, Plugin } from 'vue'
// Component 是一个复合类型,里面已经有 函数组件的定义了, 照理说应该没问题的
const Components: Component[] = [
// Button 是一个纯函数组件,但是在这里就会出现签名不一致的情况
Button as Component
]
// app 不是以前的 Vue 类了
function install(app: App<any>) {
Components.forEach(Component => {
app.component(Component.name as string, Component)
})
}
export default {
version: process.env.VERSION || 'dev',
install: install
// vue 没有暴露 PluginInstallFunction 类型
// 只有 Plugin 类型,在定义类型的的时候就只能进行联合声明了
} as { version: string } & Plugin
复制代码
看着没有报错,信心满满,然后代码里面你就很放心的开始用了
import VueUI from 'vue-next-ui'
const app = createApp(App)
app.use(VueUI)
复制代码
然而实际是会告诉你类型有问题,就算你改成这样导出也没用
export default {
install(app: App<any>): void {
Components.forEach(Component => {
app.component(Component.name as string, Component)
})
}
} as Plugin
复制代码
就算你直接改 d.ts
也没用,但是 vue-router@next
就可以,不明觉厉。
这里想说的是,后面这样不兼容的问题还有很多,可能是多方原因,但情况就是这样,所以后面有的忙了。
类型问题可以参考下我的处理:
方式一:@ts-ignore 一把梭
@ts-ignore 一把梭只有对你的代码非常自信才应该这样做,一般推荐已经进行判断之后,还存在类型签名问题时使用。
方式二:显示转换
其实还可以使用 any
,any
大法是真好用,就和 eval
一样,谁用谁知道
问题三:尤大大已经说过,vue 3 已经没有任何类了
这个问题这么说呢,你们看下这段代码和 vue 2.x
比比
import { createApp, reactive, h } from 'vue'
import App from './App.vue'
import router from './router'
const store = reactive({
// global state
})
const app = createApp({
render() {
// h 已经是全局函数了
return h(App)
}
})
// 现在 config 在 app 上,意不意外
app.config.errorHandler = () => {}
// 经常往 Vue.prototype 挂东西的行为可以停停了
// 现在应该推荐这样玩
app.provide('state', store)
// 全局组件注册也在这里
app.component('page', Page)
// 现在 router 是这样用的
// 而且不需要再把 router 作为参数丢进 app 中了
app.use(router)
// 以前所有带 $ 符号的大部分都已经去除前缀了
app.mount('#app')
复制代码
写法本身没大问题,但是想当于以前的 hack 手段,大家可以停下了,因为没有原型可以给大家玩了,主要是习惯问题
基本上适应下就好了,唯一比较麻烦的是组件那块。
问题三:jsx 和 render 的问题
ps: 模板不算哈,那个编译支持的,我说的是手动写的情况下
1. 现在更新需要 flag 支持
在 babel 插件没有跟上的情况,写的特别难受,因为 vue3 的响应式数据是需要 flag 支持的,也就是如果没有 flag,那你的数据就是个纯数据,没有任何响应式变化。
要下面这样写,带 flag 才行,这个值的说明,看直播的应该都了解过了。
之所以拿这个说明是因为写通用组件的时候,这种手写 render
的情况其实挺多的,这样对于开发者来说,不借助官方的插件,可能是一个不小的挑战
2. 子元素不支持数组了
另外不知道为什么不支持直接传递数组了,你如果传递就会给你提示
这个其实挺麻烦的,因为你需要包一层,下面的写法才可以
或者无聊翻人家 api,找一可能的挂上去,我就找到了 createSlots
的,但其实不用也可以的,你们等官方出文档再说吧。
不过比较好的是,终于有了 renderSlot
方法,不用再每次手动写判断了,👏👏🎉🎉
结束
其实还有周边的问题,比如你们看到的 storybook 其实是我把官方的下过来,直接改上去的,还好人家写的比较好,不然又要头疼了
另外类型其实还有包本身的问题,我已经提了一个了,但是还是有好多,不过毕竟刚出,还是可以理解的,希望 vue 能越走越远吧,毕竟不是所有人都能认同同一个框架的,只有适合的才是好的。
最后献上我未完成的脚手架地址:✈️飞机
来源:oschina
链接:https://my.oschina.net/u/4357160/blog/4263705