vue3-tsx

949 阅读1分钟
//父组件
import { defineComponent, withModifiers, ref, reactive } from "vue";
import SlotComp from "@/components/SlotComp";

export default defineComponent({
  name: "Comp1",
  props: {
    message: { type: String },
    modelValue: { type: String },
  },
  setup(props, { emit }) {
    const CONTEXY = import.meta.env.VITE_APP_CONTEXT;
    const imgSrc = `${CONTEXY}/image/1.png`;
    const placeholder = "请输入";
    const isShow = ref(true);
    const num = ref(10);
    const condition = ref(true);
    const inputValue = ref("");
    const list = ref([100, 200, 300, 400]);
    const student = reactive({
      name: "zs",
      age: 10,
      schoolName: "XXX小学",
    });
    const add = (n: number) => {
      num.value = num.value + n;
    };
    const desrease = (n: number) => {
      num.value -= n;
    };
    const add30 = (n: number) => {
      num.value += 30;
    };
    const changeShow = () => {
      isShow.value = !isShow.value;
    };
    const showMessage = () => {
      return (
        <div>
          <h2>age:{student.age}</h2>
          <h2>img:{imgSrc}</h2>
        </div>
      );
    };
    const h1 = <div>我是条件1</div>;
    const h2 = <div>我是条件2</div>;
    const slots = {
      default: () => {
        return <h3>我是默认插槽,可以不传递的</h3>;
      },
      header: () => {
        return <h3>我是新来的header</h3>;
      },
      content: (name: string) => (
        <div>
          <div>我收到了来自子组件的插槽内容</div>
          <h2>{name}</h2>
        </div>
      ),
      footer: (scope: any) => (
        <div>
          <div>我收到了来自子组件的插槽内容</div>
          <h2>{scope.sonMessage}</h2>
          <h2>{scope.sonAge}</h2>
        </div>
      ),
    };
    return () => (
      <div>
        <div>{num.value}</div>
        <div>{showMessage()}</div>
        <button onClick={() => add(10)}>+10</button>
        <button onClick={() => desrease(20)}>-20</button>
        {/* 禁止冒泡 */}
        <button onClick={withModifiers(() => add30(30), ["stop"])}>+30</button>
        <hr />
        <h2>数据动态绑定</h2>
        <img src={imgSrc} alt="" />
        <input type="text" placeholder={placeholder} />
        {isShow.value && <h2>显示和隐藏</h2>}
        <button onClick={changeShow}>显示/隐藏</button>
        <p>{inputValue.value}</p>
        <input type="text" v-model={inputValue.value} />
        {condition.value ? h1 : h2}
        <button onClick={(e) => (condition.value = !condition.value)}>changeCondition</button>
        <hr />
        <h2>样式绑定</h2>
        <h2 class={["a", true ? "b" : "", false ? "c" : ""].join(" ")}>class样式绑定</h2>
        <h2 class={{ a: true }}>class样式对象方式绑定</h2>
        <hr />
        <h2>遍历</h2>
        <div>
          <p>数组遍历</p>
          {list.value.map((item, index) => (
            <h3 key={index}>{item}</h3>
          ))}
        </div>
        <div>
          <p>遍历对象</p>
          {Object.keys(student).map((i) => (
            <h3 key={i}>
              {/* 解决索引报错问题 */}
              {i}-{student[i as keyof typeof student]}
            </h3>
          ))}
        </div>

        <hr />
        <h2>父子通信</h2>
        <p>{props.modelValue}</p>
        <button onClick={(e) => emit("update:modelValue", "水浒传")}>update:modelValue</button>
        <p>{props.message}</p>
        <button onClick={() => emit("update:message", "hello vite")}>update:message</button>
        <hr />
        <h2>插槽用法 </h2>
        <SlotComp v-slots={slots}></SlotComp>
        //属性展开 模拟v-bind={{info}}
       <Comp2 {...info}/>
      </div>
    );
  },
});

//子组件--主要是插槽
import { defineComponent, ref, onMounted, reactive } from "vue";
export default defineComponent({
  setup(props, { slots }) {
    const sonMessage = ref("我是子组件message");
    const sonInfo = reactive({
      name: "zs",
      age: 10,
    });
    onMounted(() => {
      setTimeout(() => {
        sonMessage.value = "111我是子组件message";
        sonInfo.age++;
      }, 2000);
    });
    return () => (
      <div>
        <div>{slots.default?.() ?? <h1>我是默认插槽</h1>}</div>
        <div>{slots.header?.()}</div>

        {/* 作用域插槽 :子组件向父组件传一个值,就直接传*/}
        <div>{slots.content?.(sonInfo.name)}</div>

        {/* 作用域插槽 :子组件向父组件传多个值,就传一个对象*/}
        <div>{slots.footer?.({ sonMessage: sonMessage.value, sonAge: sonInfo.age })}</div>
      </div>
    );
  },
});