您好,登錄后才能下訂單哦!
一.JSX簡介
const element = <h2>Hello, world!</h2>;
JSX 可以很好地描述 UI 應該呈現(xiàn)出它應有交互的本質(zhì)形式。JSX 可能會使人聯(lián)想到模版語言,但它具有 JavaScript 的全部功能。
Babel 會把 JSX 轉(zhuǎn)譯成一個名為 React.createElement() 函數(shù)調(diào)用。
以下兩種示例代碼完全等效:
const element = ( <h2 className="greeting"> Hello, world! </h2> );
const element = React.createElement( 'h2', {className: 'greeting'}, 'Hello, world!' );
React.createElement() 會預先執(zhí)行一些檢查,以幫助你編寫無錯代碼,但實際上它創(chuàng)建了一個這樣的對象:
const element = { type: 'h2', props: { className: 'greeting', children: 'Hello, world!' } };
二.模板缺陷
模板的最大特點是擴展難度大,不易擴展??赡軙斐蛇壿嬋哂啵?/p>
<Level :type="1">哈哈</Level> <Level :type="2">哈哈</Level> <Level :type="3">哈哈</Level>
Level組件需要對不同的type產(chǎn)生不同的標簽
<template> <h2 v-if="type==1"> <slot></slot> </h2> <h3 v-else-if="type==2"> <slot></slot> </h3> <h4 v-else-if="type==3"> <slot></slot> </h4> </template> <script> export default { props: { type: { type: Number } } }; </script>
三.函數(shù)式組件
函數(shù)式組件沒有模板,只允許提供render函數(shù)
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組件,可以根據(jù)用戶傳入的數(shù)據(jù)自動循環(huán)列表
<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方法,就會想到可以編寫個函數(shù)組件,將createElement方法傳遞出來
<template> <div class="list"> <div v-for="(item,index) in data" :key="index"> <li v-if="!render">{{item}}</li> <!-- 將render方法傳到函數(shù)組件中,將渲染項傳入到組件中,在內(nèi)部回調(diào)這個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調(diào)用最外層的render方法,將createElement和當前項傳遞出來
<script> export default { props: { render: { type: Function }, item: {} }, render(h) { return this.render(h, this.item); } }; </script>
六.scope-slot
使用v-slot 將內(nèi)部值傳入即可
<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>
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。