I. Template Defects
- The greatest feature of template is that it is difficult to expand and difficult to expand. May cause logical redundancy
<Level :type="1">Ha-ha</Level> <Level :type="2">Ha-ha</Level> <Level :type="3">Ha-ha</Level>
Level components need to generate different labels for different type s
<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>
2. Functional components
- Functional components have no templates and only render functions are allowed
export default { render(h) { return h("h" + this.type, {}, this.$slots.default); }, props: { type: { type: Number } } };
Complex logic becomes very simple
III. JSX Applications
- Using jsx makes the code look simpler and easier to read
export default { render(h) { const tag = "h" + this.type; return <tag>{this.$slots.default}</tag>; }, props: { type: { type: Number } } };
IV. render method custom component
- Writing List Components can automatically loop lists based on data passed in by users
<List :data="data"></List> <script> import List from "./components/List"; export default { data() { return { data: ["Apple", "Banana", "A mandarin orange"] }; }, components: { List } }; </script> <!-- List Component Rendering List --> <template> <div class="list"> <div v-for="(item,index) in data" :key="index"> <li>{{item}}</li> </div> </div> </template> <script> export default { props: { data: Array, default: () => [] } }; </script>
The render method is used to customize the component, and the render method is passed into the parent component.
<List :data="data" :render="render"></List> render(h, name) { return <span>{name}</span>; }
When we need the createElement method, we think we can write a function component and pass the createElement method out.
<template> <div class="list"> <div v-for="(item,index) in data" :key="index"> <li v-if="!render">{{item}}</li> <!-- take render Method is passed to the function component, rendering item is passed to the component, and this is called back internally render Method --> <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 calls the outermost render method to pass createElement and the current item out
<script> export default { props: { render: { type: Function }, item: {} }, render(h) { return this.render(h, this.item); } }; </script>
V. scope-slot
- Use v-slot to transfer internal values
<List :arr="arr"> <template v-slot="{item}"> {{item}} </template> </List> <div v-for="(item,key) in arr" :key="key"> <slot :item="item"></slot> </div>
VI. Writing Editable Forms
- Using jsx to extend to editable tables based on iview
<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>