JSX在render函数中的应用详解


Posted in Javascript onSeptember 04, 2019

一.JSX简介

const element = <h1>Hello, world!</h1>;

JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。JSX 可能会使人联想到模版语言,但它具有 JavaScript 的全部功能。

Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用。

以下两种示例代码完全等效:

const element = (
 <h1 className="greeting">
  Hello, world!
 </h1>
);
const element = React.createElement(
 'h1',
 {className: 'greeting'},
 'Hello, world!'
);

React.createElement() 会预先执行一些检查,以帮助你编写无错代码,但实际上它创建了一个这样的对象:

const element = {
 type: 'h1',
 props: {
  className: 'greeting',
  children: 'Hello, world!'
 }
};

二.模板缺陷

模板的最大特点是扩展难度大,不易扩展。可能会造成逻辑冗余:

<Level :type="1">哈哈</Level>
<Level :type="2">哈哈</Level>
<Level :type="3">哈哈</Level>

Level组件需要对不同的type产生不同的标签

<template>
 <h1 v-if="type==1">
 <slot></slot>
 </h1>
 <h2 v-else-if="type==2">
 <slot></slot>
 </h2>
 <h3 v-else-if="type==3">
 <slot></slot>
 </h3>
</template>
<script>
export default {
 props: {
 type: {
  type: Number
 }
 }
};
</script>

三.函数式组件

函数式组件没有模板,只允许提供render函数

export default {
 render(h) {
 return h("h" + this.type, {}, this.$slots.default);
 },
 props: {
 type: {
  type: Number
 }
 }
};

复杂的逻辑变得非常简单

四.JSX应用

使用jsx会让代码看起来更加简洁、易于读取

export default {
 render(h) {
 const tag = "h" + this.type;
 return <tag>{this.$slots.default}</tag>;
 },
 props: {
 type: {
  type: Number
 }
 }
};

五.render方法定制组件

编写List组件,可以根据用户传入的数据自动循环列表

<List :data="data"></List>
<script>
import List from "./components/List";
export default {
 data() {
 return { 
  data: ["苹果", "香蕉", "橘子"] 
 };
 },
 components: {
 List
 }
};
</script>

<!-- List组件渲染列表 -->
<template>
 <div class="list">
 <ul v-for="(item,index) in data" :key="index">
  <li>{{item}}</li>
 </ul>
 </div>
</template>
<script>
export default {
 props: {
 data: Array,
 default: () => []
 }
};
</script>

通过render方法来定制组件,在父组件中传入render方法

<List :data="data" :render="render"></List>
render(h, name) {
  return <span>{name}</span>;
}

我们需要createElement方法,就会想到可以编写个函数组件,将createElement方法传递出来

<template>
 <div class="list">
 <div v-for="(item,index) in data" :key="index">
  <li v-if="!render">{{item}}</li>
  <!-- 将render方法传到函数组件中,将渲染项传入到组件中,在内部回调这个render方法 -->
  <ListItem v-else :item="item" :render="render"></ListItem>
 </div>
 </div>
</template>
<script>
import ListItem from "./ListItem";
export default {
 components: {
 ListItem
 },
 props: {
 render: {
  type: Function
 },
 data: Array,
 default: () => []
 }
};
</script>

ListItem.vue调用最外层的render方法,将createElement和当前项传递出来

<script>
export default {
 props: {
 render: {
  type: Function
 },
 item: {}
 },
 render(h) {
 return this.render(h, this.item);
 }
};
</script>

六.scope-slot

使用v-slot 将内部值传入即可

<List :arr="arr">
  <template v-slot="{item}">
    {{item}}
  </template>
</List>

<div v-for="(item,key) in arr" :key="key">
  <slot :item="item"></slot>
</div>

七.编写可编辑表格

基于iview使用jsx扩展成可编辑的表格

<template>
<div>
 <Table :columns="columns" :data="data"></Table>
</div>
</template>
<script>
import Vue from 'vue';
export default {
 methods:{
  render(h,{column,index,row}){
   let value = row[column.key];
   return <div on-click={(e)=>this.changeIndex(e,index)} >
    {this.index === index ? 
     <i-input type="text" value={value} on-input={(value)=>{
      this.handleChange(value,column,row)
     }} onOn-enter={()=>this.enter(row,index)}/>:
     <span>{value}</span>
    }
   </div>
  },
  enter(row,index){
   this.data.splice(index,1,row);
   this.index = -1;
  },
  handleChange(value,column,row){
   row[column['key']]= value;
  },
  changeIndex(e,index){
   this.index = index;
   this.$nextTick(()=>{
    e.currentTarget.getElementsByTagName("input")[0].focus();
   })
  }
 },
 data() {
  return {
   index:-1,
   columns: [
    {
     title: 'Name',
     key: 'name',
     render:this.render
    },
    {
     title: 'Age',
     key: 'age',
    },
    {
     title: 'Address',
     key: 'address',
    },
   ],
   data: [
    {
     name: 'John Brown',
     age: 18,
     address: 'New York No. 1 Lake Park',
     date: '2016-10-03',
    },
    {
     name: 'Jim Green',
     age: 24,
     address: 'London No. 1 Lake Park',
     date: '2016-10-01',
    },
    {
     name: 'Joe Black',
     age: 30,
     address: 'Sydney No. 1 Lake Park',
     date: '2016-10-02',
    },
    {
     name: 'Jon Snow',
     age: 26,
     address: 'Ottawa No. 2 Lake Park',
     date: '2016-10-04',
    },
   ],
  };
 },
};
</script>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
基于jquery用于查询操作的实现代码
May 10 Javascript
artDialog双击会关闭对话框的修改过程分享
Aug 05 Javascript
JavaScript中Function()函数的使用教程
Jun 04 Javascript
JQuery插入DOM节点的方法
Jun 11 Javascript
JQuery中DOM事件合成用法实例分析
Jun 13 Javascript
Function.prototype.apply()与Function.prototype.call()小结
Apr 27 Javascript
深入浅析JavaScript函数前面的加号和叹号
Jul 09 Javascript
angularJS Provider、factory、service详解及实例代码
Sep 21 Javascript
laravel5.4+vue+element简单搭建的示例代码
Aug 29 Javascript
webpack多入口文件页面打包配置详解
Jan 09 Javascript
React从react-router路由上做登陆验证控制的方法
May 10 Javascript
原生JavaScript实现日历功能代码实例(无引用Jq)
Sep 23 Javascript
关于layui的动态图标不显示的解决方法
Sep 04 #Javascript
vue本地打开build后生成的dist文件夹index.html问题
Sep 04 #Javascript
简单谈谈javascript高级特性
Sep 04 #Javascript
在layui中使用form表单监听ajax异步验证注册的实例
Sep 03 #Javascript
解决mui框架中switch开关通过js控制开或者关状态时小圆点不动的问题
Sep 03 #Javascript
mui js控制开关状态、修改switch开关的值方法
Sep 03 #Javascript
Layui给switch添加响应事件的例子
Sep 03 #Javascript
You might like
PHP strtr() 函数使用说明
2008/11/21 PHP
Yii中Model(模型)的创建及使用方法
2015/12/28 PHP
探究Laravel使用env函数读取环境变量为null的问题
2016/12/06 PHP
从零开始学习jQuery (八) 插播:jQuery实施方案
2011/02/23 Javascript
浅谈Javascript事件模拟
2012/06/27 Javascript
js模拟select下拉菜单控件的代码
2013/05/08 Javascript
jQuery点击其他地方时菜单消失的实现方法
2016/04/22 Javascript
jquery中each循环的简单回滚操作
2017/05/05 jQuery
React Js 微信禁止复制链接分享禁止隐藏右上角菜单功能
2017/05/26 Javascript
vue.js使用代理和使用Nginx来解决跨域的问题
2018/02/03 Javascript
AngularJS实现的base64编码与解码功能示例
2018/05/17 Javascript
vue: WebStorm设置快速编译运行的方法
2018/10/18 Javascript
layui 弹出层值回传解决方式
2019/11/14 Javascript
微信小程序自定义菜单切换栏tabbar组件代码实例
2019/12/30 Javascript
JS+DIV实现拖动效果
2020/02/11 Javascript
javascript设计模式 ? 工厂模式原理与应用实例分析
2020/04/09 Javascript
vue form表单post请求结合Servlet实现文件上传功能
2021/01/22 Vue.js
Python+微信接口实现运维报警
2016/08/27 Python
对Python中实现两个数的值交换的集中方法详解
2019/01/11 Python
Django+RestFramework API接口及接口文档并返回json数据操作
2020/07/12 Python
Python中Yield的基本用法
2020/10/18 Python
pycharm 实现调试窗口恢复
2021/02/05 Python
通过HTML5 Canvas API绘制弧线和圆形的教程
2016/03/14 HTML / CSS
html5教你做炫酷的碎片式图片切换 (canvas)
2017/07/28 HTML / CSS
英国顶尖手表珠宝品牌独家授权经销商:HS Johnson
2020/10/28 全球购物
应届大学生的推荐信
2013/11/20 职场文书
七年级音乐教学反思
2014/01/26 职场文书
幼儿教师寄语集锦
2014/04/03 职场文书
企业指导教师评语
2014/04/28 职场文书
创先争优公开承诺书
2014/08/30 职场文书
美术教师个人总结
2015/02/06 职场文书
试用期自我评价怎么写
2015/03/10 职场文书
欠条格式范本
2015/07/03 职场文书
python 中的@运算符使用
2021/05/26 Python
关于JavaScript 中 if包含逗号表达式
2021/11/27 Javascript
Python捕获、播放和保存摄像头视频并提高视频清晰度和对比度
2022/04/14 Python