如何在 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中如何自定义右键菜单详解
Dec 08 Vue.js
vue+element实现动态加载表单
Dec 13 Vue.js
Vue实现点击当前行变色
Dec 14 Vue.js
Vue 简单实现前端权限控制的示例
Dec 25 Vue.js
vue自定义组件实现双向绑定
Jan 13 Vue.js
Vue实现图书管理案例
Jan 20 Vue.js
vue实现轮播图帧率播放
Jan 26 Vue.js
Vue如何实现变量表达式选择器
Feb 18 Vue.js
Vue SPA 首屏优化方案
Feb 26 Vue.js
vue.js Router中嵌套路由的实用示例
Jun 27 Vue.js
vue实现Toast组件轻提示
Apr 10 Vue.js
关于vue-router-link选择样式设置
Apr 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
一些星际专用术语解释
2020/03/04 星际争霸
apache2.2.4+mysql5.0.77+php5.2.8安装精简
2009/04/29 PHP
PHP高级对象构建 多个构造函数的使用
2012/02/05 PHP
深入解析PHP中逗号与点号的区别
2013/08/05 PHP
php遍历文件夹下的所有文件和子文件夹示例
2014/03/20 PHP
PHP数组遍历的几种常见方式总结
2019/02/15 PHP
PHP中常用的三种设计模式详解【单例模式、工厂模式、观察者模式】
2019/06/14 PHP
JQuery 引发两次$(document.ready)事件
2010/01/15 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(五)可移动地图的实现
2013/01/23 Javascript
javascript实现可改变滚动方向的无缝滚动实例
2013/06/17 Javascript
js比较日期大小的方法
2015/05/12 Javascript
JS简单封装的图片无缝滚动效果示例【测试可用】
2017/03/22 Javascript
javascript 中null和undefined区分和比较
2017/04/19 Javascript
JS仿QQ好友列表展开、收缩功能(第二篇)
2017/07/07 Javascript
深入理解jquery的$.extend()、$.fn和$.fn.extend()
2017/07/08 jQuery
js图片上传的封装代码
2017/08/01 Javascript
vue组件之Alert的实现代码
2017/10/17 Javascript
解决vue项目报错webpackJsonp is not defined问题
2018/03/14 Javascript
微信小程序实现获取用户信息并存入数据库操作示例
2019/05/07 Javascript
js实现继承的方法及优缺点总结
2019/05/08 Javascript
javascript for循环性能测试示例
2019/08/07 Javascript
javascript的惯性运动实现代码实例
2019/09/07 Javascript
[01:10:48]完美世界DOTA2联赛PWL S2 GXR vs PXG 第一场 11.18
2020/11/18 DOTA
python进阶教程之动态类型详解
2014/08/30 Python
介绍Python中的一些高级编程技巧
2015/04/02 Python
python实现校园网自动登录的示例讲解
2018/04/22 Python
python使用正则表达式来获取文件名的前缀方法
2018/10/21 Python
windows系统中Python多版本与jupyter notebook使用虚拟环境的过程
2019/05/15 Python
python3使用腾讯企业邮箱发送邮件的实例
2019/06/28 Python
基于python2.7实现图形密码生成器的实例代码
2019/11/05 Python
Pop In A Box英国:Funko POP搪胶公仔
2019/05/27 全球购物
俄罗斯香水在线商店:AromaCode
2019/12/04 全球购物
学校消防安全制度
2014/01/30 职场文书
采购助理岗位职责
2014/02/16 职场文书
趣味运动会通讯稿
2015/07/18 职场文书
动画「半妖的夜叉姬」新BD特典图公开
2022/03/22 日漫