欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JSX在render函数中的应用详解

程序员文章站 2022-07-06 18:22:42
一.jsx简介 const element =

hello, world!

; jsx 可以很好地描述 ui 应...

一.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>

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