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 打地鼠游戏代码说明
Oct 12 Javascript
jQuery中fadeIn、fadeOut、fadeTo的使用方法(图片显示与隐藏)
May 08 Javascript
前台js调用后台方法示例
Dec 02 Javascript
Bootstrap每天必学之警告框插件
Apr 26 Javascript
jQuery通过ajax快速批量提交表单数据
Oct 25 Javascript
基于javascript 显式转换与隐式转换(详解)
Dec 15 Javascript
JS实现数组深拷贝的方法分析
Mar 06 Javascript
vue防止花括号{{}}闪烁v-text和v-html、v-cloak用法示例
Mar 13 Javascript
angular 服务随记小结
May 06 Javascript
vue+vant使用图片预览功能ImagePreview的问题解决
Apr 10 Javascript
vue 递归组件的简单使用示例
Jan 14 Vue.js
浅谈Vue的computed计算属性
Mar 21 Vue.js
关于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
SMARTY学习手记
2007/01/04 PHP
PHP+Mysql基于事务处理实现转账功能的方法
2015/07/08 PHP
PHP输入流php://input实例讲解
2015/12/22 PHP
thinkphp框架下实现登录、注册、找回密码功能
2016/04/06 PHP
PHP实现json_decode不转义中文的方法
2017/05/20 PHP
PHP实现生成数据字典功能示例
2018/05/24 PHP
自己的js工具_Form 封装
2009/08/21 Javascript
跨浏览器开发经验总结(三)   警惕“IE依赖综合症”
2010/05/13 Javascript
jQuery输入城市查看地图使用介绍
2013/05/08 Javascript
JavaScript对IE操作的经典代码(推荐)
2014/03/10 Javascript
关闭页面window.location事件未执行的原因及解决方法
2014/09/01 Javascript
JS中字符串trim()使用示例
2015/05/26 Javascript
jQuery实用技巧必备(上)
2015/11/02 Javascript
实例讲解避免javascript冲突的方法
2016/01/03 Javascript
JavaScript的函数式编程基础指南
2016/03/19 Javascript
javascript HTML5文件上传FileReader API
2020/03/27 Javascript
vue-router重定向和路由别名的使用讲解
2019/01/19 Javascript
JQuery Ajax跨域调用和非跨域调用问题实例分析
2019/04/16 jQuery
JavaScript实现网页动态生成表格
2020/11/25 Javascript
浅谈编码,解码,乱码的问题
2016/12/30 Python
python测试mysql写入性能完整实例
2018/01/18 Python
一道python走迷宫算法题
2018/01/22 Python
详解python中__name__的意义以及作用
2019/08/07 Python
python NumPy ndarray二维数组 按照行列求平均实例
2019/11/26 Python
python调用HEG工具批量处理MODIS数据的方法及注意事项
2020/02/18 Python
TensorFlow的reshape操作 tf.reshape的实现
2020/04/19 Python
详解python对象之间的交互
2020/09/29 Python
详解移动端HTML5音频与视频问题及解决方案
2018/08/22 HTML / CSS
NFL加拿大官方网上商店:NHLShop.ca
2019/03/12 全球购物
文员自我评价怎么写
2013/09/19 职场文书
高中生毕业自我鉴定范文
2013/12/22 职场文书
银行批评与自我批评
2014/02/10 职场文书
村级环境卫生整治方案
2014/05/04 职场文书
员工廉洁自律承诺书
2014/05/26 职场文书
交通事故委托书范本(2篇)
2014/09/21 职场文书
毕业生银行实习自我鉴定
2014/10/14 职场文书