惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The Cloudflare Blog
U
Unit 42
D
Docker
Hugging Face - Blog
Hugging Face - Blog
博客园 - 聂微东
Recent Announcements
Recent Announcements
GbyAI
GbyAI
T
The Blog of Author Tim Ferriss
Last Week in AI
Last Week in AI
V
Visual Studio Blog
I
InfoQ
Google DeepMind News
Google DeepMind News
小众软件
小众软件
L
LangChain Blog
C
Check Point Blog
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 【当耐特】
J
Java Code Geeks
罗磊的独立博客

三省吾身丶丶

从一个简单功能的实现,谈谈 react 中的逻辑复用进化过程 使用 generic-pool 优化 puppeteer 并发问题 再谈中文字体的子集化与动态创建字体 《张乌梅的日记》摘录 一个使用 react 的思想去使用 vue 的方式 React 项目构建 从一个简单的实例看 JavaScript 的异步编程进化历 webpack入坑之旅(零)简介与升级 中文播客推荐 学习 Promise,掌握未来世界 JS 异步编程基础 2017 杭州 nodeParty 记录 一次canvas中文字转化成图片后清晰度丢失的探索 从零学习 canvas (一) 浅谈 electron 中的 session 管理(隔离) FlexBox 布局详解 HTML5常用标签分类 ES6 简单特性学习记录 一张图学习 ES6 中的 React 生命周期与流程 2017,一切才刚刚开始。
在 vue 中使用 jsx 与 class component 的各种姿势
guowenfh · 2019-09-17 · via 三省吾身丶丶

在之前我们分享过一次 一个使用 react 的思想去使用 vue 的方式
随着组内很多时候为了让 view 层更加清晰,和一些复杂的逻辑处理,导致现在 vue 代码中 jsx 的代码越来越多,这里进行一个整理说明

如何使用

先参看腾讯 alloyTeam 这篇文章:

里面有提到使用 babel-plugin-transform-vue-jsx babel 6 插件来处理 jsx 的编译。

当然可能是官方也知道在一定的场景下 jsx 相对模板是有优势的,于是单独有了这个仓库 对于上面的插件进行了增强。https://github.com/vuejs/jsx 在 babel 7+ 情况下可以参考使用

1
2
3
4
5
npm install @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props
<!--.babelrc-->
{
"presets": ["@vue/babel-preset-jsx"]
}

你可以在 jsx 中使用 v-model 进行双向绑定了!当然这只是一个语法糖。你也可以使用 babel 实现 v-for 。

对于一些简单的情况我们直接使用 jsx 替换 template 都不会有什么问题,但是当我们深入下去,比如要看一些 react 的 特殊模式 比如:render props 在 vue 中的使用。那么我们就要对 vue 实例的属性差异进行深入的对比和理解了。(render props 在vue中对应的就是 slotProps.default )

与组件库结合的问题

对于 antd-vue 来说,由于 实现的api基本和 react 版本一致,所以调用方式基本和react版本的文档也一致。

1
2
3
4
5
6
import {Input} form 'ant-design-vue'
<Input value={xx} onChange={(e)=>{}}>



const HelloWorld = ({ props }) => <p>hello {props.message}</p>

但是也有一些没有那么友好的组件库, 比如 iview ,由于 内部大部分api都使用了 this.$emit('on-xxEvent') 的形式,在 template 语法下 @on-xxEvent="xx"觉得还好,但是在 jsx 语法下就显得很奇怪了。如下:

1
<Input value={xx} on-on-Change={(e)=>{}}>

在上面我们处理完了直接使用 jsx 的问题。那么我们能不能更像 react 一点呢?

单文件组件

这个时候我们可能写的一个 vue 单文件组件是这样的:

VueForm.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script>
export default {
name: 'VueForm',
props: {},
data() {
return {}
},
render(){
return (
<div>
<input />
</div>
)
}
}
</script>
<style ></style>

如何直接使用 .js 或者 jsx 文件?

VueForm.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const VueForm = {
name: 'VueForm',
props: {},
data() {
return {}
},
methods:{

},
render(){
return (
<div>
<input />
</div>
)
}
}
VueForm.install = function(Vue) {
Vue.component(VueForm.name, VueForm);
};

export default VueForm;

还是好麻烦啊,每一个组件都的去定义 install 方法,也得去写 methods 啥的,那么如何 再像一些呢?或者说更简单一些呢?

vue 官方提供了 vue-class-component 模块 结合我们上面聊的,我们可以写出来这样的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import Vue from 'vue'
import Component from 'vue-class-component'

@Component({
props: {
propMessage: String
}
})
export default class App extends Vue {

msg = 123

helloMsg = 'Hello, ' + this.propMessage

mounted () {
this.greet()
}

get computedMsg () {
return 'computed ' + this.msg
}

greet () {
alert('greeting: ' + this.msg)
}
render(){
return (
<input vModel={this.msg}>
<p>prop: {this.propMessage}</p>
<p>msg: {this.msg}</p>
<p>helloMsg: {this.helloMsg}</p>
<p>computed msg: {this.computedMsg}</p>
<button onClick={this.greet}>Greet</button>
)
}
}

当然仅仅是这样可能还是不够的 。你需要再来一个模块 vue-property-decorator 甚至是 vuex-class

哈? 这不是 React + Mobx ?

我们可以看到 vue 的可扩展性是非常强的。恭喜你已经成功进入邪教。23333