【vue3】vue3接收props以及emit的用法

技术:vue3.2.40
UI框架:arco-design 2.44.7
css技术:less 4.1.3

实现:子组件接收props以及通过emit方法传值父组件

vue3使用的组合式API,我这里使用的是defineComponent

1.父页面调用子组件

<template>
  <div class="dataManagerMentPage">
    <a-table :columns="fieldColumns" :data="tableData" :scrollbar="true">
      <template #category="{ record }">
        {{ handModelType(record.category) }}
      </template>
      <template #optional="{ column, record, rowIndex }">
        <a-button @click="handDetails(column, record, rowIndex)" type="text"
          >详情</a-button
        >
      </template>
    </a-table>
    <modelDetails
      :modalForm="modalForm"
      @handleCancel="handleCancel"
      @handleModalOk="handleModalOk"
    ></modelDetails>
  </div>
</template>

<script lang="ts">
  import {
    defineComponent,
    reactive,
    toRefs,
    onUnmounted,
    onMounted,
  } from 'vue';

  import modelDetails from './components/modelDetails.vue';

  export default defineComponent({
    name: 'DataManagerMent',
    components: {
      modelDetails,
    },
    setup() {
      interface IDataManagerMant {
        // table字段名
        fieldColumns: any[];
        // table数据源
        tableData: any[];
        modalForm: {
          visible: boolean;
          title: string;
          data: object;
        };
      }
      const dataManagerMant = () => ({
        modalForm: {
          visible: false,
          title: '',
          data: null,
        },
        // table字段名
        fieldColumns: [
          {
            title: '设备ID',
            dataIndex: 'id',
            ellipsis: true,
            tooltip: true,
          },
          {
            title: '设备名称',
            dataIndex: 'deviceName',
            ellipsis: true,
            tooltip: true,
          },
          {
            title: '设备序列号',
            dataIndex: 'deviceOuterId',
            ellipsis: true,
            tooltip: true,
          },
          {
            title: '设备类型',
            dataIndex: 'category',
            slotName: 'category',
          },
          {
            title: '厂商',
            dataIndex: 'manufacturer',
            ellipsis: true,
            tooltip: true,
          },
          {
            title: '绑定模型',
            dataIndex: 'relatedModelId',
          },
          {
            title: '创建时间',
            dataIndex: 'createDate',
          },
          {
            title: '操作',
            dataIndex: 'optional',
            slotName: 'optional',
            align: 'center',
          },
        ],
        // table数据源
        tableData: [],
      });
      const state: IDataManagerMant = reactive(dataManagerMant());

      // 查看详情页
      function handDetails(column: any, record: any, rowIndex: any) {
        state.modalForm = {
          visible: true,
          title: record.id,
          data: record,
        };
      }
      // 判断设备类型
      function handModelType(category: string) {
        let name = '';
        switch (category) {
          case 'VEHICLE':
            name = '车辆';
            break;
          case 'VIDEO':
            name = '视频';
            break;
          case 'COMMON':
            name = '默认';
            break;

          default:
            name = '默认';
            break;
        }
        return name;
      }
      // 关闭弹窗
      function handleCancel() {
        state.modalForm = {
          visible: false,
          title: '',
          data: {},
        };
      }
      // 弹窗保存按钮事件
      function handleModalOk() {
        handleCancel();
      }

      return {
        ...toRefs(state),
        handDetails,
        handleCancel,
        handleModalOk,
        handModelType,
      };
    },
  });
</script>

<style lang="less" scoped>
  .dataManagerMentPage {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
  }
</style>

2.子组件

<template>
  <a-modal
    width="50%"
    :visible="modalForm.visible"
    @ok="handleOk"
    @cancel="handleCancel"
    :title="'数据详情-' + modalForm.title"
    okText="保存"
    cancelText="取消"
    title-align="start"
    :okLoading="loading"
  >
    <a-spin :loading="loading" tip="正在获取数据中...">
      <div class="modelDetailsPage">
        
      </div>
    </a-spin>
  </a-modal>
</template>

<script lang="ts">
  import {
    defineComponent,
    reactive,
    toRefs,
    onUnmounted,
    onMounted,
    watch,
  } from 'vue';
  import { Message } from '@arco-design/web-vue';



  export default defineComponent({
    name: 'ModelDetails',
    props: {
      // 父级的
      modalForm: {
        visible: {
          type: Boolean,
          default: false,
        },
        title: {
          type: String,
          default: '',
        },
      },
    },

    setup(props, { emit }) {
      interface IDataManagerMant {
        loading: boolean;
      }
      const dataManagerMant = () => ({
        loading: false,
      });
      const state: IDataManagerMant = reactive(dataManagerMant());
      // 保存按钮事件
      function handleOk() {
        state.loading = true;
        Message.success('保存成功!');
        emit('handleModalOk');
        state.loading = false;
      }
      // 返回按钮事件
      function handleCancel() {
        emit('handleCancel');
      }

      watch(
        () => props.modalForm,
        (newV, oldV) => {
          if (newV.visible) {
            // 这里可以写处理化执行的函数方法=
          }
        }
      );
      return {
        ...toRefs(state),
        handleOk,
        handleCancel,
      };
    },
  });
</script>
<style lang="less" scoped>
  .modelDetailsPage {
    width: 100%;
    height: 100%;
    padding: 0 12px;
  }
</style>

注意点:

1.setup里如果需要接收props和使用emit,只需要带参数 setup(props, { emit })
2.setup里面只需要带emit(‘handleCancel’),不需要带$$符号,这个符号是vue2的写法
3.watch监听的方法,放在setup里面

你可能感兴趣的:(vue.js,前端,javascript)