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 相关文章推荐
Prototype Function对象 学习
Jul 12 Javascript
javascript-表格排序(降序/反序)实现介绍(附图)
May 30 Javascript
JS小游戏之宇宙战机源码详解
Sep 25 Javascript
值得分享的Bootstrap Ace模板实现菜单和Tab页效果
Dec 30 Javascript
jQuery遍历json的方法分析
Apr 16 Javascript
微信小程序之仿微信漂流瓶实例
Dec 09 Javascript
使用jquery的cookie实现登录页记住用户名和密码的方法
Mar 13 jQuery
深入了解js原型模式
May 30 Javascript
jQuery属性选择器用法实例分析
Jun 28 jQuery
vue-dplayer 视频播放器实例代码
Nov 08 Javascript
JavaScript实现滑动门效果
Jan 18 Javascript
vue跳转页面的几种方法(推荐)
Mar 26 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
ThinkPHP实现附件上传功能
2017/04/27 PHP
PHP安全之register_globals的on和off的区别
2020/07/23 PHP
不间断滚动JS打包类,基本可以实现所有的滚动效果,太强了
2007/12/08 Javascript
javascript Keycode对照表
2009/10/24 Javascript
jQuery判断div随滚动条滚动到一定位置后停止
2014/04/02 Javascript
通过js来制作复选框的全选和不选效果
2014/05/22 Javascript
浅谈$(document)和$(window)的区别
2015/07/15 Javascript
js实现仿网易点击弹出提示同时背景变暗效果
2015/08/13 Javascript
js实现Select列表各项上移和下移的方法
2015/08/14 Javascript
Javascript使用function创建类的两种方法(推荐)
2016/11/19 Javascript
vue点击页面空白处实现保存功能
2019/11/06 Javascript
微信小程序 flexbox layout快速实现基本布局的解决方案
2020/03/24 Javascript
Vue 请求传公共参数的操作
2020/07/31 Javascript
[49:11]完美世界DOTA2联赛PWL S3 INK ICE vs DLG 第二场 12.20
2020/12/23 DOTA
使用Python &amp; Flask 实现RESTful Web API的实例
2017/09/19 Python
对Python中Iterator和Iterable的区别详解
2018/10/18 Python
解决pyinstaller打包pyqt5的问题
2019/01/08 Python
我用Python抓取了7000 多本电子书案例详解
2019/03/25 Python
python修改linux中文件(文件夹)的权限属性操作
2020/03/05 Python
如何把python项目部署到linux服务器
2020/08/26 Python
Numpy(Pandas)删除全为零的列的方法
2020/09/11 Python
Django跨域请求原理及实现代码
2020/11/14 Python
CSS实现半透明边框与多重边框的场景分析
2019/11/13 HTML / CSS
浅谈html5与APP混合开发遇到的问题总结
2018/03/20 HTML / CSS
捷克电器和DJ设备网上商店:Electronic-star
2017/07/18 全球购物
马来西亚在线购物市场:PGMall.my
2019/10/13 全球购物
挂牌仪式主持词
2014/03/20 职场文书
党的群众路线教育实践活动公开承诺书
2014/03/28 职场文书
安全责任书范文
2014/08/25 职场文书
2014年部门工作总结
2014/11/12 职场文书
世界文化遗产导游词
2015/02/13 职场文书
小学少先队活动总结
2015/05/08 职场文书
小平您好观后感
2015/06/09 职场文书
Python基础之元组与文件知识总结
2021/05/19 Python
Java 通过手写分布式雪花SnowFlake生成ID方法详解
2022/04/07 Java/Android
科学家测试在太空中培育人造肉,用于未来太空旅行
2022/04/29 数码科技