如何在 Vue 中使用 JSX


Posted in Vue.js onFebruary 14, 2021

JSX 是什么

JSX 是一种 Javascript 的语法扩展,JSX = Javascript + XML,即在 Javascript 里面写 XML,因为 JSX 的这个特性,所以他即具备了 Javascript 的灵活性,同时又兼具 html 的语义化和直观性

为什么要在 Vue 中使用 JSX

有时候,我们使用渲染函数(render function)来抽象组件,渲染函数不是很清楚的参见官方文档, 而渲染函数有时候写起来是非常痛苦的

createElement(
 'anchored-heading', {
 props: {
  level: 1
 }
 }, [
 createElement('span', 'Hello'),
 ' world!'
 ]
)

其对应的模板是下面:

<anchored-heading :level="1">
 <span>Hello</span> world!
</anchored-heading>

这显然是吃力不讨好的,这个时候就派上 JSX 上场了。在 Vue 中使用 JSX,需要使用 Babel 插件,它可以让我们回到更接近于模板的语法上,接下来就让我们一起开始在 Vue 中写 JSX 吧

开始

快读创建一个 Vue 项目,直接使用 vue-cli 创建一个项目:

# 直接回车即可
vue create vue-jsx

安装依赖:

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

配置 .babelrc :

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

基础内容

这里展示在 Vue 中书写一些基础内容,包括纯文本、动态内容、标签使用、自定义组件的使用,这些跟我们平时使用单文件组件类似,如下所示:

render() {
 return (
 <div>
  <h3>内容</h3>
  {/* 纯文本 */}
  <p>hello, I am Gopal</p>
  {/* 动态内容 */}
  <p>hello { this.msg }</p>
  {/* 输入框 */}
  <input />
  {/* 自定义组件 */}
  <myComponent></myComponent>
 </div>
 );
}

Attributes/Props

Attributes 的绑定跟普通的 HTML 结构一样

render() {
 return <div><input placeholder="111" /></div>
}

注意,如果动态属性,之前是 v-bind:placeholder="this.placeholderText" 变成了placeholder={this.placeholderText}

render() {
 return <input
   type="email"
   placeholder={this.placeholderText}
   />
}

我们也可以展开一个对象

render (createElement) {
 return (
  <button {...this.largeProps}></button>
 )
}

像 input 标签,就可以如下批量绑定属性

const inputAttrs = {
 type: 'email',
 placeholder: 'Enter your email'
};
render() {
 return <input {...{ attrs: inputAttrs }} /> 
}

插槽

我们来看下怎么实现具名插槽和作用域插槽

具名插槽:父组件的写法和单文件组件模板的类似,通过 slot="header" 这样方式指定要插入的位置。子组件通过 this.$slots.header 方式指定插槽的名称,其中 header 就是插槽的名称

父组件:

render() {
 {/* 具名插槽 */}
 <myComponent>
 <header slot="header">header</header>
 <header slot="content">content</header>
 <footer slot="footer">footer</footer>
 </myComponent>
}

子组件:

render() {
 return (
 <div>
  {/* 纯文本 */}
  <p>我是自定义组件</p>
  {this.$slots.header}
  {this.$slots.content}
  {this.$slots.footer}
 </div>
 );
}

作用域插槽:子组件中通过 {this.$scopedSlots.test({ user: this.user })} 指定插槽的名称是 test,并将 user 传递给父组件。父组件在书写子组件标签的时候,通过 scopedSlots 值指定插入的位置是 test,并在回调函数获取到子组件传入的 user 值

父组件:

render() {
 {/* 具名插槽 作用域插槽 */}
 <myComponent {
 ...{
  scopedSlots: {
  test: ({user}) => (
   <div>{user.name}</div>
  )
  }
 }
 }>
 </myComponent>

子组件:

render() {
 return (
 <div>
  {this.$scopedSlots.test({
  user: this.user
  })}
 </div>
 );
}

指令

常见的指令如下所示:

render() {
 {/* 指令 */}
 {/* v-model */}
 <div><input vModel={this.newTodoText} /></div>
 {/* v-model 以及修饰符 */}
 <div><input vModel_trim={this.tirmData} /></div>
 {/* v-on 监听事件 */}
 <div><input vOn:input={this.inputText} /></div>
 {/* v-on 监听事件以及修饰符 */}
 <div><input vOn:click_stop_prevent={this.inputText} /></div>
 {/* v-html */}
 <p domPropsInnerHTML={html} />
}

函数式组件

函数式组件是一个无状态、无实例的组件,详见官网说明,新建一个 FunctionalComponent.js 文件,内容如下:

export default ({ props }) => <p>hello {props.message}</p>

父组件中调用如下:

import funComponent from './FunctionalComponent'

...

render() {
 return {/* 函数式组件 */}
  <funComponent message="Gopal"></funComponent>
}

以上就是如何在 Vue 中使用 JSX的详细内容,更多关于Vue 中使用 JSX的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
vue自定义插件封装,实现简易的elementUi的Message和MessageBox的示例
Nov 20 Vue.js
vue实现两个区域滚动条同步滚动
Dec 13 Vue.js
Vue 组件注册全解析
Dec 17 Vue.js
Vue仿百度搜索功能
Dec 28 Vue.js
Vue 修改网站图标的方法
Dec 31 Vue.js
vue使用过滤器格式化日期
Jan 20 Vue.js
如何在Vue项目中添加接口监听遮罩
Jan 25 Vue.js
vue.js实现点击图标放大离开时缩小的代码
Jan 27 Vue.js
vue项目实现分页效果
Mar 24 Vue.js
Vue详细的入门笔记
May 10 Vue.js
vue配置型表格基于el-table拓展之table-plus组件
Apr 12 Vue.js
vue实现登陆页面开发实践
May 30 Vue.js
Vue单页面应用中实现Markdown渲染
Feb 14 #Vue.js
vue仿携程轮播图效果(滑动轮播,下方高度自适应)
Feb 11 #Vue.js
Vue+Bootstrap实现简易学生管理系统
Feb 09 #Vue.js
详解Vue的七种传值方式
Feb 08 #Vue.js
Vue中使用wangeditor富文本编辑的问题
Feb 07 #Vue.js
vue使用lodop打印控件实现浏览器兼容打印的方法
Feb 07 #Vue.js
vue如何使用rem适配
Feb 06 #Vue.js
You might like
php和js交互一例-PHP教程,PHP应用
2007/01/03 PHP
php5.3 废弃函数小结
2010/05/16 PHP
php分页思路以及在ZF中的使用
2012/05/30 PHP
PHP中feof()函数实例测试
2014/08/23 PHP
Laravel中获取路由参数Route Parameters的五种方法示例
2017/09/29 PHP
分享十五个最佳jQuery 幻灯插件和教程
2010/03/27 Javascript
javascript创建数组之联合数组的使用方法示例
2013/12/26 Javascript
javascript运动详解
2015/07/06 Javascript
Javascript原型链的原理详解
2016/01/05 Javascript
基于JS代码实现实时显示系统时间
2016/06/16 Javascript
jQuery操作dom实现弹出页面遮罩层(web端和移动端阻止遮罩层的滑动)
2016/08/25 Javascript
jQuery查找节点方法完整实例
2016/09/13 Javascript
[原创]SyntaxHighlighter自动识别并加载脚本语言
2017/02/07 Javascript
JS及JQuery对Html内容编码,Html转义
2017/02/17 Javascript
vue webpack开发访问后台接口全局配置的方法
2018/09/18 Javascript
vue动态子组件的两种实现方式
2019/09/01 Javascript
Vue Components 数字键盘的实现
2019/09/18 Javascript
js判断非127开头的IP地址的实例代码
2020/01/05 Javascript
vue+ESLint 配置保存 自动格式化代码
2020/03/17 Javascript
[47:10]完美世界DOTA2联赛PWL S3 LBZS vs Rebirth 第二场 12.16
2020/12/18 DOTA
Django在Win7下的安装及创建项目hello word简明教程
2014/07/14 Python
python发送HTTP请求的方法小结
2015/07/08 Python
python操作excel文件并输出txt文件的实例
2018/07/10 Python
PyCharm无法识别PyQt5的2种解决方法,ModuleNotFoundError: No module named 'pyqt5'
2020/02/17 Python
使用pth文件添加Python环境变量方式
2020/05/26 Python
什么是python类属性
2020/06/10 Python
Keras设置以及获取权重的实现
2020/06/19 Python
python代码实现图书管理系统
2020/11/30 Python
小学新学期寄语
2014/04/02 职场文书
企业公益活动策划方案
2014/08/24 职场文书
学习雷锋精神活动总结
2015/02/06 职场文书
表扬信格式模板
2015/05/05 职场文书
幼儿园新生开学寄语
2015/05/27 职场文书
辛德勒的名单观后感
2015/06/03 职场文书
选择比努力更重要?这是长期以来对“努力”的最大误解
2019/07/12 职场文书
Windows Server 修改远程桌面端口的实现
2022/06/25 Servers