TSX in Vue3 | 青训营笔记

376 阅读2分钟

这是我参与「 第五届青训营 」伴学笔记创作活动的第 9 天

TSX in Vue3

一、为什么使用tsx

组件库需要反复迭代,需求非常灵活多变,需要强大的控制能力,用tsx可以获得最强的控制力

二、组件的创建

1、vue中的tsx与react中的tsx有很多相似也有很多不同的地方,比如vue中有插槽,react中没有

2、函数式组件

export default () => <div>test</div>

3、defineComponent

export default defineComponent({
  render() {
    return <div>test</div>
  }
})

4、defineComponent的Conposition API

export default defineComponent({
	setup(props, ctx) {
    return () => {
      return <div>test</div>
    }
  }
})

摒弃this,对ts支持最好,有最强的控制力,所有东西都是单独导进来的

三、TSX语法

1、vue中的tsx借助babel-plugin-jsx插件

2、与react的jsx不同:修饰符、slot、directive指令、emit事件派发

3、修饰符:

利用withModifiers高阶函数实现当前元素点击独立有效,阻住冒泡过程

第一个参数是点击事件,第二个参数是添加的修饰符,用数组包裹所有修饰符

export default defineComponent({
	setup(props, ctx) {
    // 创建响应式数据
    const count = ref(0)
    const inc = () => {
      count.value++
    }
    return () => {
      return <div onClick={withModifiers(inc, ['self'])}>test: {count.value}</div>
      // 利用withModifiers高阶函数实现当前元素点击独立有效,阻住冒泡过程
      // 第一个参数是点击事件,第二个参数是添加的修饰符,用数组包裹所有修饰符
    }
  }
})

4、directive指令

v-model双向绑定直接使用

v-show直接使用

v-if用三元表达式代替

v-for使用map代替

export default defineComponent({
	setup(props, ctx) {
    const count = ref(0)
    const inc = () => {
      count.value++
    }
    return () => {
      return <div onClick={withModifiers(inc, ['self'])}>test: {count.value}</div>
      <input type="test" v-model={count.value} />
    }
  }
})

自定义指令focus获取焦点,使用自定义组件,自动获取焦点,传参、修饰符

export default defineComponent({
  derectives: {
    focus: {
      // 当挂载的时候,获取元素el,设置focus方法
      mounted(el) {
        el.focus()
      }
    }
  }
	setup(props, ctx) {
    return () => {
      // 使用自定义组件,自动获取焦点
      // 传值、参数、修饰符
      return <input type="test" v-focus={[val, arg, ['modifiers']]} />
    }
  }
})

5、插槽slot ☀︎

在外部定义插槽的内容

// 父元素template
<template>
	<Test>
    <Template #default>aaa</Template>
		<Template #title>title</Template>
  </Test>
</template>
// 父元素jsx
<Test v-slots={{
    title: () => <h3>title</h3>
}}>abc</Test>

在内部获取插槽,显示插槽内容

{slots.default ? slots.default() : 'default content'}

6、事件派发emit

这是我参与「 第五届青训营 」伴学笔记创作活动的第 9 天

在test组件内编写

export default defineComponent ({
  emits: ['click'],
	setup(props, { slots, emit }) {
    const count = ref(0)
    const inc = () => {
      count.value++
      emit('click')
    }
    return () => {
      return <div onClick={inc}>test: {count.value}</div>
    }
  }
})

使用test组件,此时onClick派发出来就可以在项目中使用

<Test @click="onClick"></Test>