How does Vue dynamically render components through JSX? The following article will introduce to you howVuecan efficiently render components dynamically through JSX. I hope it will be helpful to you!
How to render dynamic components? [Related recommendations:vuejs video tutorial]
There is a set of array structures as follows:
const arr = [ { tag: 'van-field' }, // 输入框 { tag: 'van-cell' }, // 弹出层 { tag: 'van-stepper' } // 步进器 ]
I want to get thetag
rendering corresponding by looping arr components.
Let’s analyze how to write the best way.
We can write av-for
Loop through the arr array, and then usev-if
to determine the tag and render the corresponding component type.
It is not impossible to write like this, but the scalability is not good. Every time a tag is added, a v-if must be added to the template.
I believe many people wrote like this at first.
But this is not the code that we elegant people should write.
Can we render real tags based on the tags oftag
.
The key is how to render the real component based on the traversed tags within the loop.
I would like to invite today’s protagonist JSX to come on stage.
Parent component
const arr = [ { tag: 'van-field' }, // 输入框 { tag: 'van-cell' }, // 弹出层 { tag: 'van-stepper' } // 步进器 ]
Child componentRendTag.vue
We can use JSX'srender
to write JavaScript return components to achieve our dynamic rendering of tags.
render
is equivalent to the template in our vue.
So the rendering effect is as follows: render into a real component according to the tag
We use ordinary components, which cannot be rendered into what we want like JSX s component.
Herev-model
I recommend reading the pitfalls of using calculated attributes:How to bind multi-loop expressions in actual v-model (including principles)
In fact, these two articles are related to a certain extent, but I have separated the requirements here.
Mainly to facilitate friends’ reading and understanding.
Based on this requirement, we will make up for JSX.
JSX is a syntax extension of Javascript,JSX = Javascript XML
, which means writing XML in Javascript. Because of this feature of JSX, it has the flexibility of Javascript sex, and at the same time has the semantics and intuitiveness of html.
Some components with strong activity can be replaced by JSX (such as the above requirements);
It is not necessary to use JSX for the entire project.
We can also embed in components ButtonCounter component.
const ButtonCounter = { name: "button-counter", props: ["count"], methods: { onClick() { this.$emit("changeNum", this.count + 1); } }, render() { return ; } }; export default { name: "HelloWorld", props: { msg: String }, data() { return { count: 0 }; }, methods: { // 改变button按钮数量 changeNum(val) { this.count = val; } }, render() { const { count } = this; // 解构 return (); } };
As you can see, it is basically the same as the template writing method of vue, but you need to pay attention to it. It is curly braces;
requires two pairs of curly braces in the vue template, while inJSX
only needs to writeand a pair of.
export default { name: "HelloWorld", props: { msg: String }, data() { return { count: 0, text: "Hello World!", msgClass: "msg-class", isGreen: true }; }, render() { const { count, text } = this; // 解构 return (); } };动态绑定class
动态绑定style
Common instructions for v-html, v-if, v-for, v-model It cannot be used in JSX and needs to be implemented in other ways.
v-html
In JSX, if you want to set theinnerHTML
of the DOM, you need to usedomProps
.
Component usage:
Component code:
export default { name: "HelloWorld", props: { msg: String }, data() { return {}; }, methods: {}, render() { return ; } };
Rendering DOM result:
##v- for
Usemapto implement:
render() { const list = [1,2,3] return({ list.map(item => ) }) }
v-if
Simple example: use ternaryrender() { const bool = false; return{bool ? : }; }
render() { let num = 3 if(num === 1){ return( ) } if(num === 2){ return( ) } if(num === 3){ return( ) } }
v-model
Use directly:export default { name: "HelloWorld", props: { msg: String }, data() { return { value: "abc" }; }, watch: { value(val) { console.log("this.model内容:" + val); } }, methods: {}, render() { return (); } };
Listening events
Listening Events like onChange, onClick, etc. can be used.需要注意的是,传参数不能使用onClick={this.handleClick(params)}
,这样子会每次render
的时候都会自动执行一次方法。
应该使用bind
,或者箭头函数
来传参。
组件示例代码:
export default { name: "HelloWorld", props: { msg: String }, data() { return {}; }, methods: { handleClick(val) { alert(val); } }, render() { return (); } };
用监听事件来实现v-model
:
methods: { input(e) { this.value = e.target.value; } }, render() { return (); }
也可以调整为:
(this.vaue = e.target.value)} />
还可以使用对象的方式去监听事件:解构事件
export default { name: "HelloWorld", props: { msg: String }, data() { return { value: "" }; }, watch: { value(val) { console.log("this.model的内容:" + val); } }, methods: { handleInput(e) { this.value = e.target.value; }, handleFocus(e) { console.log(e.target); } }, render() { return (); } };
nativeOn
仅对于组件,用于监听原生事件,也可以使用对象的方式去监听事件:
{...{nativeOn:{click: this.handleClick}}}
事件修饰符
和指令一样,除了个别的之外,大部分的事件修饰符都无法在JSX中使用。
event.stopPropagation()
来代替event.preventDefault()
来代替if (event.target !== event.currentTarget){ return }
.enter与keyCode
: 在特定键触发时才触发回调
if(event.keyCode === 13) { // 执行逻辑 }
除了上面这些修饰符之外,尤大大对于.once,.capture,.passive,.capture.once做了优化,简化代码:
export default { name: "HelloWorld", props: { msg: String }, methods: { handleClick(e) { console.log("click事件:" + e.target); }, handleInput(e) { console.log("input事件:" + e.target); }, handleMouseDown(e) { console.log("mousedown事件:" + e.target); }, handleMouseUp(e) { console.log("mouseup事件" + e.target); } }, render() { return (点击模块); } };
父传子。
示例:
默认内容 确定 取消
HelloWorld组件代码:this.$slots
export default { name: "HelloWorld", render() { return (); } };{this.$slots.default}
子传父。
示例:
姓名:{{ name }}年龄:{{ age }}
HelloWorld组件代码:this.$scopedSlots
export default { name: "HelloWorld", render() { return (); } };{this.$scopedSlots.content({ name: "张三", age: 20 })}
子组件通过{this.$scopedSlots.content({ name: "张三", age: 20 })}
指定插槽的名称为content
,并将含有name,age属性的对象数据传递给父组件,父组件就可以在插槽内容中使用子组件传递来的数据。
看到v-html用innerHTML;v-for用map;.stop用
event.stopPropagation()
。
你有什么感想?
这不就是我们JavaScript方法的操作吗。
所以JSX就是Javascript + XML。
我以前一直觉得Vue中没必要用JSX吧,用模板Template足以了。
但经过这个需求,我想JSX在处理动态渲染组件还是蛮占有优势的?。
日后面试官问我JSX在Vue的有什么应用场景,我想我可以把这个需求说一说。
The above is the detailed content of Let's talk about how Vue dynamically renders components through JSX. For more information, please follow other related articles on the PHP Chinese website!