教練,怎么在vue項目里寫react?
1.前言
我承認了我是標題黨,本篇文章是在vue項目里寫tsx的一篇介紹。作為一個reacter,目前的業(yè)務天天使用vue2+ts讓我十分的不舒服。我對于vue也不是很熟悉,想回到我的react時代。于是在查詢官網(wǎng)之后發(fā)現(xiàn)在vue里面寫jsx也挺有意思的,遂記錄。
2.正文
vue2+ts的項目配置這里就不展開了,網(wǎng)上一搜一大推。
index.vue是頁面路由,存放各個組件和公用邏輯。components文件夾中存放我的tsx組件。
接下來就開始寫tsx。
你可以直接創(chuàng)建jsx/tsx文件
這次的項目結構是這樣的:
在vue文件里這么使用
- // 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這么寫
- 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>
- }
- }
在來看一下頁面
這該死的react既視感,竟是如此的誘人
可能有心者注意到了 我還引用了一個 CreateElement
,這是干嘛的呢。這玩意叫 渲染函數(shù)
。不喜歡讀vue那么大串的文檔的兄弟看這里。簡單解釋:這個東西可以渲染一個vnode節(jié)點。 它比模板更接近編譯器。
什么意思呢?意思就是模板語法也會編譯成渲染函數(shù)。所以我們直接用渲染函數(shù)不就相當于節(jié)省了模板語法到渲染函數(shù)的過程。四舍五入項目性能又是一個大的提升!
簡單介紹一下傳參:
第一個參數(shù)
: {String | Object | Function} 一個 HTML 標簽名、組件選項對象,或者 resolve 了上述任何一種的一個 async 函數(shù)。必填項。
第二個參數(shù)
: Object 一個與模板中 attribute 對應的數(shù)據(jù)對象。
第三個參數(shù)
: {String | Array} 文本節(jié)點或子級虛擬節(jié)點 (VNodes)。
渲染函數(shù)給vue帶來了很多的靈活性,以前你想自定義在子組件里插入東西,得寫一大堆的插槽。 <slot>
。有了渲染函數(shù)我們可以這么玩。
- // 改造一下上面的index.vue的data
- private list = [
- { render: () => ["a", { style: { color: "red" } }, "我要去淘寶"] },
- { render: () => ["a", { style: { color: "green" } }, "我要去京東"] },
- { render: () => ["a", { style: { color: "pink" } }, "我要去百度"] },
- ];
tsx中這么寫:
- {
- this.opt.map((it) => {
- return h(...it.render())
- })
- }
就可以渲染出花里胡哨的頁面了
我們還可以這么玩:
- // 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" } }, "我要去百度"),
- },
- ];
結果也是同樣的花哨
我們同樣可以渲染亂七八糟的標簽!
- // index.vue改造
- {
- render: (h: CreateElement) =>
- h(
- "h1",
- {
- style: { color: "green", marginRight: "5px" },
- },
- "我要去京東"
- ),
- },
我們可以隨心所欲的在渲染函數(shù)中定義事件:
- // 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]();
- }
這樣就可以啦!
結尾
本次文章是對vue靈活性使用的入門。請各位vue大佬不要噴我~