如何在 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 相关文章推荐
springboot+vue实现文件上传下载
Nov 17 Vue.js
Vue3配置axios跨域实现过程解析
Nov 25 Vue.js
详解Vue 的异常处理机制
Nov 30 Vue.js
浅谈Vue使用Elementui修改默认的最快方法
Dec 05 Vue.js
vue 在单页面应用里使用二级套嵌路由
Dec 19 Vue.js
vue仿携程轮播图效果(滑动轮播,下方高度自适应)
Feb 11 Vue.js
详解Vue的options
May 15 Vue.js
解决Vue+SpringBoot+Shiro跨域问题
Jun 09 Vue.js
vue.js Router中嵌套路由的实用示例
Jun 27 Vue.js
Vue3.0中Ref与Reactive的区别示例详析
Jul 07 Vue.js
Vue的过滤器你真了解吗
Feb 24 Vue.js
Vue中Object.assign清空数据报错的解决方案
Mar 03 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
支持php4、php5的mysql数据库操作类
2008/01/10 PHP
用PHP读取和编写XML DOM的实现代码
2011/02/03 PHP
PHP分多步骤填写发布信息的简单方法实例代码
2012/09/23 PHP
fckeditor上传文件按日期存放及重命名方法
2015/05/22 PHP
PHP中用Trait封装单例模式的实现
2019/12/18 PHP
浅析JavaScript原型继承的陷阱
2013/12/03 Javascript
让jQuery与其他JavaScript库并存避免冲突的方法
2013/12/23 Javascript
用jquery写的菜单从左往右滑动出现
2014/04/11 Javascript
浅谈javascript属性onresize
2015/04/20 Javascript
javascript常用的方法整理
2015/08/20 Javascript
jquery插件jquery.dragscale.js实现拖拽改变元素大小的方法(附demo源码下载)
2016/02/25 Javascript
如何判断Javascript对象是否存在的简单实例
2016/05/18 Javascript
浅谈js中test()函数在正则中的使用
2016/08/19 Javascript
bootstrap基本配置_动力节点Java学院整理
2017/07/14 Javascript
Vue的Flux框架之Vuex状态管理器
2017/07/30 Javascript
vue实现图片滚动的示例代码(类似走马灯效果)
2018/03/03 Javascript
详解vue指令与$nextTick 操作DOM的不同之处
2018/08/02 Javascript
JQuery Ajax跨域调用和非跨域调用问题实例分析
2019/04/16 jQuery
在Layui中操作数据表格,给指定单元格添加事件示例
2019/10/26 Javascript
js瀑布流布局的实现
2020/06/28 Javascript
详解三种方式在React中解决绑定this的作用域问题并传参
2020/08/18 Javascript
[58:32]EG vs Liquid 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
[43:18]NB vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.22
2019/09/05 DOTA
python中关于时间和日期函数的常用计算总结(time和datatime)
2013/03/08 Python
python实现人人网登录示例分享
2014/01/19 Python
python itchat实现调用微信接口的第三方模块方法
2019/06/11 Python
python求最大值,不使用内置函数的实现方法
2019/07/09 Python
Django ModelForm操作及验证方式
2020/03/30 Python
keras在构建LSTM模型时对变长序列的处理操作
2020/06/29 Python
Python 连接 MySQL 的几种方法
2020/09/09 Python
最新Python idle下载、安装与使用教程图文详解
2020/11/28 Python
html5简介及新增功能介绍
2020/05/18 HTML / CSS
瑞贝卡·明可弗包包官网:Rebecca Minkoff
2016/07/21 全球购物
信息专业毕业生五年职业规划参考
2014/02/06 职场文书
MongoDB balancer的使用详解
2021/04/30 MongoDB
golang实现一个简单的websocket聊天室功能
2021/10/05 Golang