对于此查询的长度,我们事先表示歉意。
在React中,我可以在任何返回JSX.Element的标准ES6类上使用render函数。这很出色,因为它允许我派生ES6类,其中每个派生类都实现自己的JSX呈现实现-请参见下面的(ts)示例:
export class Colour {
public name: string = "";
constructor(name) {
this.name = name;
}
public render(): JSX.Element {
return <span>Error, no colour specified</span>;
}
}
export class Red extends Colour {
constructor() {
super("red");
}
public render(): JSX.Element {
return <div style={{ color: this.name }}>Hi, I am {this.name}!</div>;
}
}
export class Blue extends Colour {
constructor() {
super("blue");
}
public render(): JSX.Element {
return <h2 style={{ color: this.name }}>Hi, I am {this.name}!</h2>;
}
}
然后,在React组件中,我可以创建一个可以轻松呈现的Color对象列表,如下所示:
function App() {
const list = [];
list.push(new Red());
list.push(new Blue());
list.push(new Red());
const listItems = list.map(item => <li key={item}>{item.render()}</li>);
return (
<div className="App">
<h1>React derived rendering </h1>
<ul>{listItems}</ul>
</div>
);
}
结果是这样的:
一切都很好...
现在我的问题是:在Vue.js中,有什么方法可以轻松地做到这一点吗?请注意-对我而言,在代码中创建许多派生实例并将其添加到要呈现的列表中很重要!
现在,我能做的最接近的工作是创建一个虚拟Vue组件,当它渲染时,我实际上调用派生的实现来交出渲染句柄“ h”。
Vue.component("fusion-toolbar", {
props: ["items"],
template: `
<div>
<div v-for="item in items"
v-bind:key="item.code" >
<f-dummy v-bind:item='item'></f-dummy>
</div>
</div>
`
});
Vue.component("f-dummy", {
props: ["item"],
render(h) {
return this.item.render(h);
}
});
export class Colour {
public colour: string = "";
constructor(colour: string) {
this.colour = colour;
}
render(h: any) {
return h("h1", "Hello, I am " + this.colour);
}
}
export class Red extends Colour {
constructor() {
super("red");
}
render(h: any) {
return h("h2", "Hello, I am " + this.colour);
}
}
export class Blue extends Colour {
private _isDisabled = true;
constructor(disabled: boolean) {
super("blue");
this._isDisabled = disabled;
}
render(h: any) {
return h('div',
[
h('h4', {
class: ['example-class', { 'conditional-class': this._isDisabled }],
style: { backgroundColor: this.colour }
}, "Hello, I am " + this.colour)
]
)
}
}
然后在我的父列表组件中,我有:
<template>
<div id="app"><fusion-toolbar v-bind:items="myitems"> </fusion-toolbar></div>
</template>
<script>
import { Red, Blue } from "./Colour";
export default {
name: "App",
data: function() {
return {
myitems: []
};
},
mounted() {
this.myitems.push(new Red());
this.myitems.push(new Blue(false));
this.myitems.push(new Blue(true));
}
};
</script>
这是最好的方法吗?欢迎任何反馈...
经过一段时间的思考,我不得不得出结论,我的烦恼来自必须引入“ f-dummy”中间组件,以便能够捕获Vue的render函数,然后将其传递给pojo。
我现在更改的是,我使用较低级别的“ render(createElement)”(或“ h”)句柄渲染列表本身,然后可以将其传递给子级,而不必求助于中间组件。
这是新代码,首先我定义ES6类(请注意,颜色,橙色,蓝色只是示例):
export class Colour {
public colour: string = "";
constructor(colour: string) {
this.colour = colour;
}
render(h: any) {
return h("h1", "Error - please provide your own implementation!");
}
}
export class Orange extends Colour {
constructor() {
super("orange");
}
public getStyle() {
return {
class: ['example-class'],
style: { backgroundColor: this.colour, border: '3px solid red' }
}
}
render(h: any) {
return h('h4', this.getStyle(), "This is my colour: " + this.colour)
}
}
export class Blue extends Colour {
private _isDisabled = true;
constructor(disabled: boolean) {
super("lightblue");
this._isDisabled = disabled;
}
render(h: any) {
return h('div',
[
h('h4', {
class: ['example-class', { 'is-disabled': this._isDisabled }],
style: { backgroundColor: this.colour }
}, "Hello, I am " + this.colour)
]
)
}
}
要渲染列表,我现在这样做:
Vue.component("fusion-toolbar", {
props: ["items"],
render(h: any) {
return h('div', this.items.map(function (item: any) {
return item.render(h);
}))
}
});
现在,我可以简单地将Orange或Blue'pojo'实例添加到列表中,它们将正确呈现。请参阅以下App.vue的内容:
<template>
<div id="app">
<fusion-toolbar v-bind:items="myitems"> </fusion-toolbar>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import { Colour, Orange, Blue } from "./components/DropDownItem";
export default Vue.extend({
name: "app",
data: function() {
return {
myitems: [] as Colour[]
}
},
mounted() {
this.myitems.push(new Orange());
this.myitems.push(new Blue(false));
this.myitems.push(new Blue(true));
}
});
</script>
<style lang="scss">
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
text-align: center;
}
.example-class {
width: 250px;
padding: 3px;
}
.is-disabled {
color: gray;
}
</style>
样本如下所示:
很整齐。我意识到我可以使用Babel插件来使用JSX来代替Vue的较低层渲染,但是我很享受它给我带来的力量!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句