1 Introduction

I admit that I am the title party, and this article is an introduction to tsx in the vue project. As a reacter, using vue2+ts every day in the current business makes me very uncomfortable. I am not very familiar with vue, and want to go back to my react era. So after querying the official website, I found that writing jsx in vue is also quite interesting, so I recorded it.

2. Body

The project configuration of vue2+ts will not be expanded here.

index.vue is the page routing, storing various components and common logic. My tsx components are stored in the components folder.

Then start writing tsx.

/tsx files directly 16141a10a4347b

The project structure this time is like this:

image.png

Use this in the vue file

// index.vue
<template>
  <div class="wrapper">
    <Common :opt="list" />
  </div>
</template>
 
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import Common from "./components/Common";

@Component({
  name: "App",
  components: {
    Common,
  },
})
export default class App extends Vue {
  private list = ["我要去淘宝", "我要去百度", "我要去京东"];
}
</script>

tsx writes like this

import { CreateElement } from 'vue';
import { Component, Vue, Prop } from 'vue-property-decorator';

@Component({
    name: 'Common'
})
export default class Common extends Vue {
    @Prop(Object) opt!: any[]

    render(h: CreateElement) {
        return <span>
            {
                this.opt.map((it) => {
                    return <span style="marginRight:10px">{it}</span>
                })
            }
        </span>
    }
}

Take a look at the page

image.png

This damn react has a sense of sight, it is so tempting

image.png

CreateElement may have noticed that I also quoted a 06141a10a4356a. What is this for? This thing is called the rendering function. Brothers who don't like to read such a large number of documents in vue read here. Simple explanation: This thing can render a vnode node. It is closer to the compiler than the template. What does that mean? This means that the template syntax will also be compiled into a rendering function. Therefore, if we directly use the rendering function, it is not equivalent to saving the process of template syntax to the rendering function. The rounding project performance is another big improvement!

Briefly introduce the transfer parameters:

first parameter: {String | Object | Function} An HTML tag name, component option object, or an async function that resolves any of the above. Required field.

second parameter: Object A data object corresponding to the attribute in the template.

third parameter: {String | Array} text nodes or child virtual nodes (VNodes).

The rendering function brings a lot of flexibility to vue. In the past, you had to write a lot of slots if you wanted to customize the insertion of things in the sub-components. <slot> . With the rendering function we can play like this.

// 改造一下上面的index.vue的data

  private list = [
    { render: () => ["a", { style: { color: "red" } }, "我要去淘宝"] },
    { render: () => ["a", { style: { color: "green" } }, "我要去京东"] },
    { render: () => ["a", { style: { color: "pink" } }, "我要去百度"] },
  ];

Write like this in tsx:

  {
                this.opt.map((it) => {
                    return h(...it.render())
                })
            }

You can render a fancy page

image.png

We can also play like this:

// tsx改造
<span>
            {
                this.opt.map((it) => {
                    return it.render(h)
                })
            }
</span>


在index.vue页面我们就可以这么玩:
// index.vue
private list = [
    {
      render: (h: CreateElement) =>
        h("a", { style: { color: "red", marginRight: "5px" } }, "我要去淘宝"),
    },
    {
      render: (h: CreateElement) =>
        h("a", { style: { color: "green", marginRight: "5px" } }, "我要去京东"),
    },
    {
      render: (h: CreateElement) =>
        h("a", { style: { color: "pink", marginRight: "5px" } }, "我要去百度"),
    },
  ];

The result is the same fancy

image.png

We can also render messy tags!

// index.vue改造
 {
      render: (h: CreateElement) =>
        h(
          "h1",
          {
            style: { color: "green", marginRight: "5px" },
          },
          "我要去京东"
        ),
    },

We can define events in the rendering function as we want:

// index.vue
private list = [
   {
      render: (h: CreateElement) =>
        h(
          "a",
          {
            style: { color: "red", marginRight: "5px" },
            on: {
              click: () => this.iWillGoWhere("TB"),
            },
          },
          "我要去淘宝"
        ),
   }]
   
 iWillGoWhere(type: string) {
    const goWhere: any = {
      TB: () => {
        alert("我要去淘宝!");
      },
      JD: () => {
        alert("我要去京东!");
      },
      BD: () => {
        alert("我要去百度!");
      },
    };
    goWhere[type]();
  }

That's it!

image.png

end

This article is an introduction to the flexible use of vue. Please don't spray me~


greet_eason
482 声望1.4k 粉丝

技术性问题欢迎加我一起探讨:zhi794855679