vue的render函数使用方法
用render函数的好处是复杂的逻辑不利于template的维护,此时可以用到render函数。
·
render函数demo
用render函数的好处是复杂的逻辑不利于template的维护,此时可以用到render函数。
render函数demo渲染的效果图
demo目录结构
App.vue
<template>
<div id="app">
<keep-alive :include="cached" exclude="ACompoment" :max="99">
<LifeCycle v-if="isExist" v-model="isExist" @close="doClose" ></LifeCycle>
</keep-alive>
<component :is="dynamicName" />
<div>名字切换</div>
<!-- <select v-model="dynamicName" name="" id="">-->
<!-- <option v-for="(name,index) in compsName" :key="index" :value="name">{{ name }}</option>-->
<!-- </select>-->
<hr>
组件切换
<select @change="toggleName" name="" id="">
<option v-for="(name,index) in compsName" :key="index" :value="name">{{ name }}</option>
</select>
<render-box/>
<jsx-box/>
<hr>
<LowCode/>
</div>
</template>
<script>
import LifeCycle from './components/LifeCycle.vue'
import BComp from "./components/BCompoment";
import AComp from "./components/ACompoment";
import CComp from "./components/CCompoment";
import RenderBox from './components/RenderBox';
import JsxBox from './components/JsxBox';
import LowCode from './components/LowCode.vue'
export default {
name: 'App',
components: { LifeCycle, BComp, AComp, CComp,RenderBox,JsxBox,LowCode},
data(){
return{
compsName:['AComp','BComp','CComp'],
isExist:true,
cached: [
'MyLifeCycle'
],
dynamicName: 'BComp',
}
},
methods:{
doClose(url){
this.cached.splice(this.cached.indexOf(url), 1);
},
toggleName(e){
console.log('切换到了,', e.target.value);
switch(e.target.value){
case 'AComp':
return this.dynamicName=AComp;
case 'BComp':
return this.dynamicName = {
name:'BComp',
...BComp,
}
case 'CComp':
return this.dynamicName={
name:'CComp',
render:CComp.render
}
}
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
初级版
RenderBox.vue
直接用render函数渲染
<script>
export default {
methods:{
getDomAttr(){
return { style: { background: 'pink' ,border:'1px solid #555'}, attrs: { mytest: 'abc' }, on: { click: function () { alert(1) } } };
}
},
render(h){
// 组件或者标签名
return h('div', this.getDomAttr(), [
h('h2', {}, '1'),
h('h2', {}, '2'),
h('h2', {}, '3'),
]);
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
中级版
JsxBox.vue
用jsx的语法,可以用html标签,也可以用纯函数做复杂的逻辑判断。
<script>
// 纯函数, 不依赖于函数上下文
// 纯函数: 不依赖this相关的属性,通过形参的传递,来实现功能
function renderDemo1(h,num1) {
return num1 === 1 && <div>111</div>
}
function renderDemo(h,num, num1) {
switch (num) {
case 1:
return <div>一的内容 {renderDemo1(h,num1)} </div>;
case 2:
return <div>二的内容</div>
}
}
// function renderForm(h,form){
// // 使用v-model需要组件this支撑
// return <input v-model={ form.username } />
// }
// function renderForm(h,form){
// // 使用v-model需要组件this支撑
// return <input value={ form.username } onInput={ val => form.username = val.target.value } />
// }
export default {
methods:{
doClick() {
console.log('开始点击了...')
},
// renderTest() {
// return (
// <div style={{ background: 'yellow' }} test={'abc'} onClick={this.doClick} >
// <h2>11</h2>
// <h2>22</h2>
// <h2>33</h2>
// </div>
// )
// },
// renderDemo(h, num1) {
// return this.num === 1 ? <div>一的内容 {renderDemo1(h, num1)} </div> : this.num === 2 ? <div>二的内容</div> : null
// },
},
data() {
return {
num: 1,
num1: 1,
form:{ username:'哈哈' }
}
},
render(h){
const { num1 } = this;
return renderDemo(h, num1);
// return this.renderDemo(h, num1);
// return renderForm.call(this,h,form);
// return renderForm(h,form)
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
高级版
LowCode.vue
低代码demo 应用render函数
把左边的a,b,c 组件拖入右边的灰色框里面;
<template>
<div class="box">
<div class="aside">
<!-- vue-draggable -->
<button compName="AComp" draggable="true" @dragstart="recordData">A组件</button>
<button compName="BComp" draggable="true" @dragstart="recordData">B组件</button>
<button compName="CComp" draggable="true" @dragstart="recordData">C组件</button>
</div>
<div class="viewport" @dragover.prevent @drop="addComp">
<div :id="item.id" v-for="(item,index) in comps" :key="index"></div>
</div>
</div>
</template>
<script>
import BComp from "./BCompoment";
import AComp from "./ACompoment";
import CComp from "./CCompoment";
import Vue from 'vue';
export default {
components:{
BComp,AComp,CComp
},
data(){
return {
comps: []
}
},
methods:{
addComp(e){
let compName = e.dataTransfer.getData('compName');
console.log('组件名称:', compName);
const Comp = this.$options.components[compName];
//添加一个坑
this.comps.push({
id: compName
})
this.$nextTick(()=>{
//2.触发渲染 render
new Vue({
render:Comp.render,
}).$mount('#'+compName)
})
},
recordData(e) {
console.log('开始拖动了',e)
let compName = e.target.getAttribute('compName');
e.dataTransfer.setData('compName', compName);
}
}
}
</script>
<style scoped>
.box {
width: 1000px;
display: flex;
}
.box,
.aside,
.viewport {
height: 800px;
}
.aside {
width: 300px;
background: yellowgreen;
}
.viewport {
flex: 1;
background: grey;
}
</style>
A 组件
B 组件
C 组件
<template>
<div>
我是A组件
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
更多推荐
已为社区贡献1条内容
所有评论(0)