仲灏小栈 仲灏小栈
首页
大前端
后端&运维
其他技术
生活
关于我
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

仲灏

诚意, 正心, 格物, 致知
首页
大前端
后端&运维
其他技术
生活
关于我
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 《前端项目基础建设》
  • HTML&CSS

  • JavaScript&TypeScript

  • Node

  • 构建

  • Vue

  • React

    • Vue 放弃繁琐的render函数,拥抱JSX
      • 背景
      • 安装配置
        • babel7 (vue cli 默认是使用了babel7的)
        • 安装babel插件
        • babel 6
      • 使用
        • slot
        • Table-column Scoped Slot
    • Awesome React
    • React 文档(vue版)
    • react 项目开发注意事项
    • 常见功能实现
    • react 常见坑集合
    • ant design pro 学习
    • ProComponents设计思路
    • 万条数据渲染优化
    • react hook 与 闭包
    • JSX
    • React生命周期
    • React 基本使用 setState
    • React 基本使用 组件生命周期
    • React 高级使用 性能优化
    • React 高级使用 高阶组件
    • React Redux使用
    • react-router 使用
    • React 原理
    • React 面试题1
    • React 面试题2
    • React 面试题3
    • React 面试题5
    • 仿jira项目笔记 项目起航:项目初始化与配置
    • 第6章 CSS 其实很简单 - 用 CSS-in-JS 添加样式
    • 第8章 Hook,路由,与 URL 状态管理
    • pro-components 源码学习
    • ant-design Spin组件封装
    • React 生命周期
  • 小程序

  • 跨端

  • Electron

  • WebGL&GIS

  • 浏览器

  • 面经

  • 其他

  • 大前端
  • React
仲灏
2021-11-29
目录

Vue 放弃繁琐的render函数,拥抱JSX

# 背景

如果你写了很多 render 函数,可能会觉得下面这样的代码写起来很痛苦:

createElement(
  'anchored-heading', {
    props: {
      level: 1
    }
  }, [
    createElement('span', 'Hello'),
    ' world!'
  ]
)
1
2
3
4
5
6
7
8
9
10
[
	{ label: '最近更新时间', prop: 'update_time', align: 'center', visible: false },
  {
    label: '操作', align: 'center', 'min-width': '180px', render: (h, { row }) => {
      return h('div',
        [h('el-popconfirm', {
          props: { title: '确定删除吗?', 'confirm-button-type': 'danger' },
          class: 'mr-10',
          on: {
            confirm: () => { this.delItem(row) }
          }
        },
        [h('el-button', { slot: 'reference', props: { size: 'mini', type: 'danger' }}, '删除')]),
        h('el-button', { props: { size: 'mini', type: 'primary' }, nativeOn: { click: () => { this.editItem(row) } }}, '编辑')]
      )
    }
  }
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

特别是对应的模板如此简单的情况下:

<anchored-heading :level='1'>
  <span>Hello</span> world!
</anchored-heading>
1
2
3
<el-popconfirm
	title='确定删除吗?'
	'confirm-button-type'='danger'  
  onConfirm='() => this.delItem(row)'
>
   <el-button slot='reference' size='mini' type='danger'>删除</el-button>
</el-popconfirm>

<el-button size='mini' type='danger' onClick={() => this.editItem(row)}>编辑</el-button>

1
2
3
4
5
6
7
8
9
10

# 安装配置

# babel7 (vue cli 默认是使用了babel7的)

# 安装babel插件

npm install @vue/babel-preset-jsx @vue/babel-helper-vue-jsx-merge-props

  • 配置babel.config.js
module.exports = {
  presets: ['@vue/babel-preset-jsx'],
}
1
2
3

如果你出现这个错误: https://github.com/vuejs/jsx/issues/34 (opens new window)

Duplicate declaration "h" (This is an error on an internal node. Probably an internal error.) 试试这个(需要说明H函数传递)

module.exports = {
  presets: [
    [
      '@vue/babel-preset-jsx',
      {
        injectH: false
      }
    ]
  ]
}

1
2
3
4
5
6
7
8
9
10
11

# babel 6

npm install babel-plugin-syntax-jsx babel-plugin-transform-vue-jsx babel-helper-vue-jsx-merge-props babel-preset-env --save-dev

  • 配置.babelrc
{
  "presets": ["env"],
  "plugins": ["transform-vue-jsx"]
}
1
2
3
4

# 使用

我这里举例比较复杂的例子 也是我遇到的

# slot

正常的code是这样的, element-ui举例

<el-table-column
  label="姓名"
  width="180">
  <template slot-scope="scope">
    <el-popover trigger="hover" placement="top">
      <p>姓名: {{ scope.row.name }}</p>
      <p>住址: {{ scope.row.address }}</p>
      <div slot="reference" class="name-wrapper">
        <el-tag size="medium">{{ scope.row.name }}</el-tag>
      </div>
    </el-popover>
  </template>
</el-table-column>
1
2
3
4
5
6
7
8
9
10
11
12
13

# Table-column Scoped Slot

name 说明
— 自定义列的内容,参数为 { row, column, $index }
header 自定义表头的内容. 参数为 { column, $index }

🍖转换成jsx就是

<el-table-column
  label='姓名'
  width='180' {
    ...{
      scopedSlots: {
        default: scope => {
          return <el-popover trigger='hover' placement='top'>
            <p>姓名: { scope.row.name }</p>
            <p>住址: { scope.row.address }</p>
            <div slot='reference' class='name-wrapper'>
              <el-tag size='medium'>{ scope.row.name }</el-tag>
            </div>
          </el-popover>
        }
      }
    }
  }>
</el-table-column>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
上次更新: 2022/05/04, 15:35:13
Vue3 原理 Proxy实现响应式
Awesome React

← Vue3 原理 Proxy实现响应式 Awesome React→

最近更新
01
vim日常使用记录
04-02
02
滑动窗口最大值
04-02
03
有效的字母异位词
04-02
更多文章>
Theme by Vdoing | Copyright © 2021-2025 izhaong | github | 蜀ICP备2021031194号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式