组件hooks

钩子定义

src/views/study/components/HooksDemo.vue

<template>
  <div>
    <h1 class="title-1" v-if="propsRef?.styleType === 1">{{ propsRef?.title }}</h1>
    <h2 class="title-2" v-else-if="propsRef?.styleType === 2">{{ propsRef?.title }}</h2>
    <h2 class="title-3" v-else>{{ propsRef?.title }}</h2>
    <div class="m-content">
      <slot></slot>
      <slot name="table" a="aaa" b="bbb" :tableData="propsRef?.tableData"></slot>
    </div>
    <div class="m-footer">
      <slot name="footer">
        <a-button @click="handleClick">传消息</a-button>
      </slot>
    </div>
  </div>
</template>
<script setup>
  import { onMounted, ref } from 'vue';
  // 定义属性
  const props = defineProps({
    title: {
      type: String,
      required: true,
    },
    styleType: {
      type: Number,
      default: 1,
    },
    tableData: {
      type: Array,
      default() {
        return [];
      },
    },
  });
  const propsRef = ref(props);
  // 定义事件
  const emits = defineEmits(['sendMessage', 'register']);
  const handleClick = () => {
    // 传消息给父组件,触发事件
    emits('sendMessage', '您好!', '我是消息:' + propsRef.value?.styleType);
  };
  const methods = {
    show: () => {
      console.log('show');
    },
    setProps(mProps) {
      propsRef.value = {
        ...propsRef.value,
        ...mProps,
      };
    },
    getProps() {
      return propsRef.value;
    },
  };
  onMounted(() => {
    emits('register', methods);
  });
  defineExpose(methods);
</script>
<style lang="less" scoped>
  .title-1 {
    font-size: 48px;
    font-weight: 500;
    color: #df9090;
  }
  .title-2 {
    font-size: 36px;
    font-weight: 500;
    color: #333;
  }
  .title-3 {
    font-size: 24px;
    font-weight: 500;
    color: #3d2f2f;
  }
  .m-content {
    margin-top: 10px;
    border: 1px solid #ccc;
  }
  .m-footer {
    border: 1px solid #333;
  }
</style>

使用钩子

src/views/study/components/useHooksDemo.ts

import { ref } from 'vue';

export const useHooksDemo = (props: any) => {
  const hooksDemoRef = ref();
  const register = (instance: any) => {
    hooksDemoRef.value = instance;
    hooksDemoRef.value?.setProps(props);
  };
  const methods = {
    getProps() {
      return hooksDemoRef.value?.getProps();
    },
    setProps(props: any) {
      hooksDemoRef.value?.setProps(props);
    },
    show() {
      hooksDemoRef.value?.show();
    },
  };
  return [register, methods];
};

src/views/study/uidemo/hooksdemo.vue

<template>
  <PageWrapper>
    <HooksDemo title="我是标题" @register="register" />
    <a-button @click="handleClick">修改样式类型</a-button>
  </PageWrapper>
</template>
<script setup>
  import HooksDemo from '../components/HooksDemo.vue';
  import { useHooksDemo } from '../components/useHooksDemo';
  const [register, { getProps, setProps }] = useHooksDemo({
    title: '我是标题啊',
  });
  const handleClick = () => {
    const styleType = getProps()?.styleType;
    setProps({
      styleType: styleType == 1 ? 2 : 1,
    });
  };
</script>
<style lang="less" scoped></style>