快速入门:在vue中使用tsx

发布时间:2023-07-06 15:30

如何在tsx文件中定义组件

在TSX文件中定义组件有几种常用方式:

  • 函数式组件:最简单的方式,你可以把它理解为setup函数,但是不同之处它可以直接返回JSX
export default (props, ctx) => <div>tree</div>
  • defineComponent:传递render选项,也就是Options API,这种缺点是要访问this
export default defineComponent({
  render() {
    return <div>tree</div>
  }
})
  • defineComponent:传递setup选项,利用Composition API,避免this,是推荐的形式
export default defineComponent({
  setup(props, ctx) {
    return () => <div>tree</div>
  }
})

Vue3中JSX语法

Vue3中使用tsx,借助了babel-plugin-jsx,大部分语法和react-jsx相同,除了几个Vue独有的概念:修饰符、slotdirectiveemit,因此这里仅关注这些特殊部分:

修饰符

import { withModifiers, defineComponent } from "vue";

const App = defineComponent({
  setup() {
    const count = ref(0);

    const inc = () => {
      count.value++;
    };

    return () => (
      <div onClick={withModifiers(inc, ["self"])}>{count.value}</div>
    );
  },
});

指令

指令使用需要我们转换思维,有几种不同情况:

  • 常用指令v-model,v-show跟以前用法类似,但也要注意后面是{},不是""
<input type="text" v-model={this.counter} />
  • v-if使用条件语句或三元表达式代替
<div>{ condition ?  <span>A</span> : <span>B</span> }</div>
  • v-for使用map代替
import { defineComponent, ref } from "vue";
const App = defineComponent({
  setup(){
    const list = ref<string[]>([])
    return () => {
      list.value.map((data,index) => <p key={index}>{data}</p>)
    }
  }
});

  • 自定义指令
defineComponent({
  directives: {
    focus: {
      mounted(el) {
        el.focus()
      }
    }
  },
  setup() {
    return () => <input v-focus>
  }
})

插槽

JSX中想要实现Vue中的插槽写法也有很大不同,主要利用一个叫做v-slots的指令来实现:

Parent.tsx

export default defineComponent({
  setup() {
    return () => (
      <Child
        v-slots={{
          prefix: () => <i>prefix</i>, // 具名插槽
          suffix: (props: Record<"name", string>) => <span>{props.name}</span>, // props可作插槽作用域的作用
        }}
      >
        默认插槽内容
      </Child>
    );
  },
});
const Child = defineComponent({
  setup(props, { slots }) {
    return () => (
      <>
        默认插槽: {slots.default && slots.default()}
        <br />
        具名插槽: {slots.prefix && slots.prefix()}
        <br />
        作用域插槽:{slots.suffix && slots.suffix({ name: "suffix" })}
      </>
    );
  },
});

emit

vue中子向父传值一般都是emit的方式,这个在vue3中大致写法相似,只是多了一个定义emit的步骤,这也是为了后续的类型推倒做准备。

defineComponent({
  emits: ["click"],
  setup(props ,{ emit }) {
    return () => (
      <button onClick={() => {emit("click")}}>点我触发emit</button>
    );
  },
});

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号