How to use jsx syntax correctly in vue

How to use jsx syntax correctly in vue

Preface

It's time to slack off again. I think I can't waste it. I have been using vant for H5 pages. Out of curiosity about the source code, I pulled a copy of vant source code from git. It turned out that all the components were written in jsx, so I started to explore using jsx in vue.

Virtual DOM

What is Virtual DOM

Before that, let's first understand the virtual DOM. Both the Vue and React frameworks use virtual DOM internally. The reason for this is that the computational cost of operating the DOM through JS is very high. Although JS updates very quickly, the cost of finding and updating the DOM is very high. So what methods can be used to optimize it? Frameworks such as Vue use js objects, which are modified and batch processed to update the DOM at one time. Therefore, the virtual DOM is essentially a js object.

Advantages of Virtual DOM

  • From the original operation of real DOM to the operation of virtual DOM, reducing the search cost
  • Through diff comparison, we can locate data changes more quickly and update the DOM
  • Better UI update
  • Abstract rendering process, bringing cross-platform capabilities, such as createRenderer API in vue3

What is a render function?

The rendering function is used to generate the virtual DOM. We write template syntax in a single vue file, which will eventually be compiled into a rendering function in the underlying implementation

Vue recommends using templates to create your HTML in most cases. However, in some scenarios, you really need the full programming power of JavaScript. In this case you can use render functions, which are closer to the compiler than templates.

When the following scenario occurs, although the following writing method can achieve the desired effect, it is not only lengthy, but we also repeat it for each level title. When we add the anchor element, we have to repeat it again in each v-if/v-else-if branch

const { createApp } = Vue

const app = createApp({})

app.component('anchored-heading', {
  template: `
    <h1 v-if="level === 1">
      <slot></slot>
    </h1>
    <h2 v-else-if="level === 2">
      <slot></slot>
    </h2>
    <h3 v-else-if="level === 3">
      <slot></slot>
    </h3>
    <h4 v-else-if="level === 4">
      <slot></slot>
    </h4>
    <h5 v-else-if="level === 5">
      <slot></slot>
    </h5>
    <h6 v-else-if="level === 6">
      <slot></slot>
    </h6>
  `,
  props: {
    level:
      type: Number,
      required: true
    }
  }
})

While templates work great in most components, they are clearly not appropriate here. So, let's try to rewrite the above example using the render function:

const { createApp, h } = Vue

const app = createApp({})

app.component('anchored-heading', {
  render() {
    return h(
      'h' + this.level, // tag name
      {}, // props/attributes
      this.$slots.default() // array of children
    )
  },
  props: {
    level:
      type: Number,
      required: true
    }
  }
})

jsx

It's a bit painful to write rendering functions in this way. Is there a way to write it closer to the template? Vue provides a babel-plugin-jsx babel plug-in to make Vue support jsx writing

I use vuecli to create a vue3 + ts project. The scaffolding has integrated the related dependencies of jsx and ts.

Two ways to write jsx in vue3

Directly change the file suffix from vue to tsx or jsx

In vue3, you can directly use the render option to write

import { defineComponent } from "vue";
export default defineComponent({
  name: "Jsx",
  render() {
    return <div>I am a div</div>;
  },
});

You can also return in setup

import { defineComponent } from "vue";
export default defineComponent({
  name: "Jsx",
  setup() {
    return () => <div>I am div</div>;
  },
});

Both methods are acceptable, depending on your personal preference. You cannot access this in setup, but you can access the current Vue instance through this in render.

usage

Class binding is different from react's jsx binding. React uses className, while vue uses class.

 setup() {
   return () => <div class="test">I am div</div>;
 },

Style binding

  setup() {
    return () => <div style={{ color: "red" }}>I am div</div>;
  },

Props binding

// Parent component setup() {
    return () => (
      <div style={{ color: "red" }}>
        <span>I am the parent component</span>
        <Mycom msg={"I am the value passed by the parent component"} />
      </div>
 );
// Subcomponent, the first parameter of setup can get the value in props setup(props) {
    return () => <div>I am a child component {props.msg}</div>;
  },

Event Binding

setup() {
    function eventClick() {
      console.log("click");
    }
    return () => <button onClick={eventClick}>button</button>;
},

Component custom events

// Subcomponent import { defineComponent } from "vue";
export default defineComponent({
  name: "Mycom",
  emits: ["event"],
  setup(props, { emit }) {
    function sendData() {
      emit("event", "data passed by subcomponent");
    }
    return () => (
      <div>
        <span>Custom Events</span>
        <button onClick={sendData}>Send data</button>
      </div>
    );
  },
});
// Parent component // @ts-nocheck
// This is fine in jsx, but it will report a ts type error in tsx, so I ignored the current file ts monitoring @ts-nocheck above
import { defineComponent } from "vue";
import Mycom from "./mycom";
export default defineComponent({
  name: "Jsx",
  setup() {
    function getSon(msg: string) {
      console.log(msg);
    }
    return () => (
      <div>
        <Mycom onEvent={getSon} />
      </div>
    );
  },
});

You can also solve ts type errors in this way

  setup() {
    function getSon(msg: string) {
      console.log(msg);
    }
    return () => (
      <div>
        <Mycom {...{ onEvent: getSon }} />
      </div>
    );
  },

Slots

// Parent component setup() {
    const slots = {
      test: () => <div>Named slot</div>,
      default: () => <div>Default slot</div>,
    };
    return () => (
      <div>
        <Mycom v-slots={slots}></Mycom>
      </div>
    );
},
setup(props, { slots }) {
// Subcomponent return () => (
      <div>
        <span>Slot</span>
        {slots.default?.()}
        {slots.test?.()}
      </div>
    );
  },

Instructions, such as v-if, v-for, etc., cannot be used in jsx. jsx only supports v-model and v-show instructions.

  setup() {
    const inputData = ref("");
    return () => (
      <div>
        <span v-show={true}>Show</span>
        <span v-show={false}>Hide</span>
        <input type="text" v-model={inputData.value} />
        <span>{inputData.value}</span>
      </div>
    );
},

at last

Without further ado, I'll open the vant source code and prepare to open my first component source code reading src => button => button.tsx

This is the end of this article about the correct use of jsx in vue. For more relevant content about the use of jsx in vue, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

refer to

    vue render function
  • vuejsx documentation
  • issues
You may also be interested in:
  • Detailed explanation of incompatible changes in rendering functions in Vue3
  • Detailed explanation of the use of Vue rendering function render
  • Detailed explanation of Vue rendering function
  • Problems and solutions of using jsx syntax in React-vscode
  • Example of using JSX to build component Parser development
  • How to use JSX to implement Carousel components (front-end componentization)
  • Specific use of Vue component jsx syntax
  • Vue jsx usage guide and how to use jsx syntax in vue.js
  • Detailed explanation of how Vue supports JSX syntax
  • Rendering Function & JSX Details

<<:  Detailed configuration steps for installing Linux (CentOS) under VMware virtual machine

>>:  A graphic tutorial on how to install MySQL in Windows

Recommend

How to install MySQL 5.7.29 with one click using shell script

This article refers to the work of 51CTO blog aut...

Summary of Nginx location and proxy_pass path configuration issues

Table of contents 1. Basic configuration of Nginx...

How to import js configuration file on Vue server

Table of contents background accomplish Supplemen...

Detailed analysis of MySQL optimization of like and = performance

introduction Most people who have used databases ...

Detailed explanation of using echarts map in angular

Table of contents Initialization of echart app-ba...

7 Ways to Write a Vue v-for Loop

Table of contents 1. Always use key in v-for loop...

XHTML Basic 1.1, a mobile web markup language recommended by W3C

W3C recently released two standards, namely "...

Some conclusions on developing mobile websites

The mobile version of the website should at least...

Detailed explanation of Vue's keyboard events

Table of contents Common key aliases Key without ...

How to use Spark and Scala to analyze Apache access logs

Install First you need to install Java and Scala,...

Solve the problem that ifconfig and addr cannot see the IP address in Linux

1. Install the Linux system on the virtual machin...

Implementing a puzzle game with js

This article shares the specific code of js to im...

HTML css js implements Tab page sample code

Copy code The code is as follows: <html xmlns=...