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 相关文章推荐
javascript 新浪背投广告实现代码
Jul 07 Javascript
DWR实现模拟Google搜索效果实现原理及代码
Jan 30 Javascript
jQuery提示效果代码分享
Nov 20 Javascript
基于JavaScript的操作系统你听说过吗?
Jan 28 Javascript
纯js实现手风琴效果代码
Apr 17 Javascript
自己封装的一个简单的倒计时功能实例
Nov 23 Javascript
基于JavaScript实现移动端无限加载分页
Mar 27 Javascript
Vue实现百度下拉提示搜索功能
Jun 21 Javascript
详解如何实现一个简单的 vuex
Feb 10 Javascript
原生JS进行前后端同构
Apr 22 Javascript
JQuery实现折叠式菜单的详细代码
Jun 03 jQuery
JavaScript Array.flat()函数用法解析
Sep 02 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
德生PL450的电路分析和低放电路的改进办法
2021/03/02 无线电
JavaScript与HTML结合的基本使用方法整理
2015/10/12 PHP
php实现简单的上传进度条
2015/11/17 PHP
Javascript 读书笔记索引贴
2010/01/11 Javascript
基于jquery的地址栏射击游戏代码
2011/03/10 Javascript
extjs 04_grid 单击事件新发现
2012/11/27 Javascript
JavaScript中数组对象的那些自带方法介绍
2013/03/12 Javascript
js实现的复制兼容chrome和IE
2014/04/03 Javascript
jquery中EasyUI实现同步树
2015/03/01 Javascript
JS实现生成会变大变小的圆环实例
2015/08/05 Javascript
javascript实现别踩白块儿小游戏程序
2015/11/22 Javascript
基于jquery animate操作css样式属性小结
2015/11/27 Javascript
js实现有过渡渐变效果的图片轮播相册(兼容IE,ff)
2016/01/19 Javascript
Bootstrap布局组件应用实例讲解
2016/02/17 Javascript
微信小程序 图片等比例缩放(图片自适应屏幕)
2016/11/16 Javascript
详解vue-router 2.0 常用基础知识点之router-link
2017/05/10 Javascript
深入浅出理解JavaScript闭包的功能与用法
2018/08/01 Javascript
手挽手带你学React之React-router4.x的使用
2019/02/14 Javascript
Javascript之高级数组API的使用实例
2019/03/08 Javascript
微信小程序之onLaunch与onload异步问题详解
2019/03/28 Javascript
如何基于layui的laytpl实现数据绑定的示例代码
2020/04/10 Javascript
如何实现js拖拽效果及原理解析
2020/05/08 Javascript
Vue之封装公用变量以及实现方式
2020/07/31 Javascript
微信小程序实现首页弹出广告
2020/12/03 Javascript
Python的Flask开发框架简单上手笔记
2015/11/16 Python
Python3实现定时任务的四种方式
2019/06/03 Python
numpy np.newaxis 的实用分享
2019/11/30 Python
在pycharm中关掉ipython console/PyDev操作
2020/06/09 Python
HTML5 Video标签的属性、方法和事件汇总介绍
2015/04/24 HTML / CSS
GEOX鞋美国官方网站:意大利会呼吸的鞋
2017/07/12 全球购物
校园奶茶店创业计划书
2014/01/23 职场文书
小区门卫值班制度
2014/01/24 职场文书
幼儿园教师求职信
2015/03/20 职场文书
公司晚宴祝酒词
2015/08/11 职场文书
小学六年级班主任工作经验交流材料
2015/11/02 职场文书
css中z-index: 0和z-index: auto的区别
2021/08/23 HTML / CSS