search
HomeWeb Front-endVue.jsLet's talk about how Vue dynamically renders components through JSX

How does Vue dynamically render components through JSX? The following article will introduce to you how Vue can efficiently render components dynamically through JSX. I hope it will be helpful to you!

Let's talk about how Vue dynamically renders components through JSX

1. Clear requirements

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 the tag rendering corresponding by looping arr components.

Lets talk about how Vue dynamically renders components through JSX

Let’s analyze how to write the best way.

2. Analysis

2.1 v-if goes around the world

We can write av-for Loop through the arr array, and then use v-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.

2.2 Dynamically rendering component tags

Can we render real tags based on the tags of tag.

The key is how to render the real component based on the traversed tags within the loop.

<van-cell  v-for="(cell, cellKey) in arr" :key="cellKey" >
      <!-- 动态渲染  -->
</van-cell>

I would like to invite today’s protagonist JSX to come on stage.

Lets talk about how Vue dynamically renders components through JSX

2.3 JSX dynamic rendering component

Parent component


  
  


const arr = [ 
  { tag: &#39;van-field&#39; },  // 输入框
  { tag: &#39;van-cell&#39; },   // 弹出层
  { tag: &#39;van-stepper&#39; } // 步进器
]

Child componentRendTag.vue

<script>
const AssemblyRend = {
  name: "assembly-rend",
  props: ["cell"],
  data() {
    return {
      input: "",
    };
  },
  methods: {
    onClick() {
      this.$emit("changeTag", this.input);
    },
  },
  computed:{
    itemVal:{
      get(){
        return this.cell.value
      },
      set(v){
        this.cell.value = v
      }
    }
  },
  render() {
    const { cell } = this; // 解构
    const assembly = cell.tag;  // 这里就是我们动态渲染组件的核心 

    return (
        <assembly
          v-model={this.itemVal}
          placeholder={cell.placeholder}
          min={cell.min}
          onClick={this.onClick}
        >
        </assembly>
      );
  },
};

export default {
  name: "RendTag",
  props: {
    cell: {
        type: Object,
        default:()=>{
            return {
                {
                    "title": "能否输入",
                    placeholder: &#39;请输入姓名&#39;,
                    "value": "name",
                    "tag": "van-switch",
                }
            }
        }
    },
  },
  methods: {
    changeTag(val) {},
  },
  render() {
    const { cell } = this; // 解构
    return (
      <div class="rendTag-content">
        <AssemblyRend
          cell={cell}
          onChangeTag={this.changeTag}
        ></AssemblyRend>
      </div>
    );
  },
};
</script>

We can use JSX's render 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

Lets talk about how Vue dynamically renders components through JSX

We use ordinary components, which cannot be rendered into what we want like JSX s component.

Herev-modelI 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.

3. How to use JSX in vue

Based on this requirement, we will make up for JSX.

3.1 What is it?

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.

3.2 Basic usage

3.2.1 Functional components

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 <button onClick={this.onClick}>数量:{this.count}</button>;
  }
};

export default {
  name: "HelloWorld",
  props: {
    msg: String
  },
  data() {
    return {
      count: 0
    };
  },
  methods: {
    // 改变button按钮数量
    changeNum(val) {
      this.count = val;
    }
  },
  render() {
    const { count } = this; // 解构
    return (
      <div class="hello-world-content">
        <ButtonCounter style={{ marginTop: "20px" }} count={count} onChangeNum={this.changeNum}></ButtonCounter>
      </div>
    );
  }
};

3.2.2 Common attributes, inline styles, dynamic classes and styles

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 in JSX only needs to write and 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 (
      <div class="hello-world-content">
        <p class={this.msg ? this.msgClass : ""}>动态绑定class</p>
        <p style={this.isGreen ? "color: green" : ""}>动态绑定style</p>
      </div>
    );
  }
};

Lets talk about how Vue dynamically renders components through JSX

3.2.3 Common instructions

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 the innerHTML of the DOM, you need to use domProps.

Component usage:

<HelloWorld 
   msg="<div class=&#39;custom-div&#39;>这是自定义的DOM</div>"> 
</HelloWorld>

Component code:

export default {
  name: "HelloWorld",
  props: {
    msg: String
  },
  data() {
    return {};
  },
  methods: {},
  render() {
    return <div domPropsInnerHTML={this.msg}></div>;
  }
};

Rendering DOM result:

Lets talk about how Vue dynamically renders components through JSX

##v- for

Use

map to implement:

render() {
  const list = [1,2,3]
  return( 
    <div>
      { list.map(item => <button>按钮{item}</button>) }
    </div>
  )
}

v-if

Simple example: use ternary

render() {
    const bool = false;
    return <div>{bool ? <button>按钮1</button> : <button>按钮2</button>}</div>;
}

Complex example: Use JS directly

render() {
  let num = 3
  if(num === 1){ return( <button>按钮1</button> ) }
  if(num === 2){ return( <button>按钮2</button> ) }
  if(num === 3){ return( <button>按钮3</button> ) }
}

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 (
      <div>
        <input v-model={this.value} placeholder="普通文本" />
      </div>
    );
  }
};

3.2.4 Listening events and event modifiers

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 (
      <div>
        <button type="button" onClick={this.handleClick.bind(this, 11)}>
          方式一
        </button>
        <button type="button" onClick={() => this.handleClick(22)}>
          方式二
        </button>
      </div>
    );
  }
};

用监听事件来实现v-model:

methods: {
    input(e) {
      this.value = e.target.value;
    }
  },
  render() {
    return (
      <div>
        <input type="text" value={this.value} onInput={this.input} />
      </div>
    );
  }

也可以调整为:

<input 
  type="text" 
  value={this.value} 
  onInput={(e) => (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 (
      <div>
        <input type="text" value={this.value} {...{ on: { input: this.handleInput, focus: this.handleFocus } }} />
      </div>
    );
  }
};

nativeOn仅对于组件,用于监听原生事件,也可以使用对象的方式去监听事件:

{...{nativeOn:{click: this.handleClick}}}

事件修饰符

和指令一样,除了个别的之外,大部分的事件修饰符都无法在JSX中使用。

  • .stop : 阻止事件冒泡,在JSX中使用event.stopPropagation()来代替
  • .prevent:阻止默认行为,在JSX中使用event.preventDefault() 来代替
  • .self:只当事件是从侦听器绑定的元素本身触发时才触发回调,使用下面的条件判断进行代替
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 (
      <div
        {...{
          on: {
            // 相当于 :click.capture
            "!click": this.handleClick,
            // 相当于 :input.once
            "~input": this.handleInput,
            // 相当于 :mousedown.passive
            "&mousedown": this.handleMouseDown,
            // 相当于 :mouseup.capture.once
            "~!mouseup": this.handleMouseUp
          }
        }}
      >
        点击模块
      </div>
    );
  }
};

3.3 插槽

3.3.1 普通插槽与具名插槽

父传子。

示例:

<HelloWorld>
    <template slot="default">默认内容</template>
    <template slot="footer">
      <el-button type="primary">确定</el-button>
      <el-button>取消</el-button>
    </template>
</HelloWorld>

HelloWorld组件代码:this.$slots

export default {
  name: "HelloWorld",
  render() {
    return (
      <div>
        <div class="default">{this.$slots.default}</div>
        <div class="footer">{this.$slots.footer}</div>
      </div>
    );
  }
};

3.3.2 作用域插槽

子传父。

示例:

<HelloWorld>
    <template v-slot:content="{ name, age }">
      <div>姓名:{{ name }}</div>
      <div>年龄:{{ age }}</div>
    </template>
</HelloWorld>

HelloWorld组件代码:this.$scopedSlots

export default {
  name: "HelloWorld",
  render() {
    return (
      <div>
        <div class="content">{this.$scopedSlots.content({ name: "张三", age: 20 })}</div>
      </div>
    );
  }
};

子组件通过{this.$scopedSlots.content({ name: "张三", age: 20 })}指定插槽的名称为content,并将含有name,age属性的对象数据传递给父组件,父组件就可以在插槽内容中使用子组件传递来的数据。

看到v-html用innerHTML;v-for用map;.stop用event.stopPropagation()
你有什么感想?
这不就是我们JavaScript方法的操作吗。
所以JSX就是Javascript + XML。

Lets talk about how Vue dynamically renders components through JSX

后记

我以前一直觉得Vue中没必要用JSX吧,用模板Template足以了。

但经过这个需求,我想JSX在处理动态渲染组件还是蛮占有优势的?。

日后面试官问我JSX在Vue的有什么应用场景,我想我可以把这个需求说一说。

(学习视频分享:web前端开发编程基础视频

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!

Statement
This article is reproduced at:掘金社区. If there is any infringement, please contact admin@php.cn delete
React and Netflix: Exploring the RelationshipReact and Netflix: Exploring the RelationshipApr 26, 2025 am 12:11 AM

Netflix uses React to enhance user experience. 1) React's componentized features help Netflix split complex UI into manageable modules. 2) Virtual DOM optimizes UI updates and improves performance. 3) Combining Redux and GraphQL, Netflix efficiently manages application status and data flow.

Vue.js vs. Backend Frameworks: Clarifying the DistinctionVue.js vs. Backend Frameworks: Clarifying the DistinctionApr 25, 2025 am 12:05 AM

Vue.js is a front-end framework, and the back-end framework is used to handle server-side logic. 1) Vue.js focuses on building user interfaces and simplifies development through componentized and responsive data binding. 2) Back-end frameworks such as Express and Django handle HTTP requests, database operations and business logic, and run on the server.

Vue.js and the Frontend Stack: Understanding the ConnectionsVue.js and the Frontend Stack: Understanding the ConnectionsApr 24, 2025 am 12:19 AM

Vue.js is closely integrated with the front-end technology stack to improve development efficiency and user experience. 1) Construction tools: Integrate with Webpack and Rollup to achieve modular development. 2) State management: Integrate with Vuex to manage complex application status. 3) Routing: Integrate with VueRouter to realize single-page application routing. 4) CSS preprocessor: supports Sass and Less to improve style development efficiency.

Netflix: Exploring the Use of React (or Other Frameworks)Netflix: Exploring the Use of React (or Other Frameworks)Apr 23, 2025 am 12:02 AM

Netflix chose React to build its user interface because React's component design and virtual DOM mechanism can efficiently handle complex interfaces and frequent updates. 1) Component-based design allows Netflix to break down the interface into manageable widgets, improving development efficiency and code maintainability. 2) The virtual DOM mechanism ensures the smoothness and high performance of the Netflix user interface by minimizing DOM operations.

Vue.js and the Frontend: A Deep Dive into the FrameworkVue.js and the Frontend: A Deep Dive into the FrameworkApr 22, 2025 am 12:04 AM

Vue.js is loved by developers because it is easy to use and powerful. 1) Its responsive data binding system automatically updates the view. 2) The component system improves the reusability and maintainability of the code. 3) Computing properties and listeners enhance the readability and performance of the code. 4) Using VueDevtools and checking for console errors are common debugging techniques. 5) Performance optimization includes the use of key attributes, computed attributes and keep-alive components. 6) Best practices include clear component naming, the use of single-file components and the rational use of life cycle hooks.

The Power of Vue.js on the Frontend: Key Features and BenefitsThe Power of Vue.js on the Frontend: Key Features and BenefitsApr 21, 2025 am 12:07 AM

Vue.js is a progressive JavaScript framework suitable for building efficient and maintainable front-end applications. Its key features include: 1. Responsive data binding, 2. Component development, 3. Virtual DOM. Through these features, Vue.js simplifies the development process, improves application performance and maintainability, making it very popular in modern web development.

Is vue.js better than React?Is vue.js better than React?Apr 20, 2025 am 12:05 AM

Vue.js and React each have their own advantages and disadvantages, and the choice depends on project requirements and team conditions. 1) Vue.js is suitable for small projects and beginners because of its simplicity and easy to use; 2) React is suitable for large projects and complex UIs because of its rich ecosystem and component design.

Vue.js's Function: Enhancing User Experience on the FrontendVue.js's Function: Enhancing User Experience on the FrontendApr 19, 2025 am 12:13 AM

Vue.js improves user experience through multiple functions: 1. Responsive system realizes real-time data feedback; 2. Component development improves code reusability; 3. VueRouter provides smooth navigation; 4. Dynamic data binding and transition animation enhance interaction effect; 5. Error processing mechanism ensures user feedback; 6. Performance optimization and best practices improve application performance.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)