vue3-tsx写法

144 阅读1分钟

父组件

<template>
  <div>
    <div class="box">index组件</div>
    <test accept-attr="menffy-props" @on-click="handleEmit" />
  </div>
</template>

<script lang="ts">
export default {
  name: 'ApplyAWSIndex',
};
</script>
<script setup lang="ts">
import test from './app';

const handleEmit = (v) => {
  console.log('父组件接收到子组件事件:', v);
};
</script>

<style scoped lang="less">
.box {
  background-color: yellow;
}
</style>

app.tsx

// 方法一:直接返回渲染函数
// export default function () {
//   return <div>我是menffyzheng</div>;
// }

// 方法二, options-api
// import { defineComponent } from 'vue';
//
// export default defineComponent({
//   data() {
//     return {
//       age: 18,
//     };
//   },
//   render() {
//     return <div>我的年龄{this.age}</div>;
//   },
// });

// 方法三, setup函数模式
// 支持v-show
// ref在template里会自动.value读值,但是在tsx里是不会,需要手动.value
// 不支持v-if, 使用三元表达式代替
// 不支持v-for,使用map代替
// 不支持v-bind,在标签上直接使用{}就行
// 返回的渲染函数在整体上只能上一个dom元素,即必须用一个<div></div>或<></>包起来
// props emit
// 插槽
// 支持v-model
import { defineComponent, ref } from 'vue';

const A = (_, { slots }) => (
  <>
    <div>{slots.default ? slots.default() : '默认值'}</div>
    <div>{slots.foo?.()}</div>
  </>
);
interface PropsInterface {
  acceptAttr: string;
}
export default defineComponent({
  name: 'ComponentName',
  props: {
    acceptAttr: {
      type: String,
      default: '',
    },
  },
  emits: ['on-click'],
  setup(props: PropsInterface, { emit }) {
    const show = ref(true);
    const data = ref([
      {
        name: 'menffy',
      },
      {
        name: 'menffy2',
      },
      {
        name: 'menffy3',
      },
    ]);
    const bindAttr = 'attr';
    const handleClick = (v) => {
      console.log('触发事件', v);
      emit('on-click', v);
    };
    const slots = {
      default: () => <div>我是插槽defualt</div>,
      foo: () => <div>我是插槽foo</div>,
    };
    const targetValue = ref<string>('');
    return () => (
      // 只能整体返回一个标签
      <>
        <span>双向绑定值输入框:</span>
        <input type="text" v-model={targetValue.value} />
        <div>双向绑定值:{targetValue.value}</div>
        <A v-slots={slots}></A>
        <hr />
        <div>
          {show.value ? <div id={bindAttr}>我是方法三</div> : ''}
          {data.value.map((item, index) => {
            return (
              <div>
                {index} - {item.name}
              </div>
            );
          })}
        </div>
        <div>我是接收的属性值:{props.acceptAttr}</div>
        <a onClick={() => handleClick('params')}>点击触发事件</a>
      </>
    );
  },
});