html 如何在Vue 3中使用h函数来完成父子组件之间的属性/事件的绑定/传递?

tsm1rwdh  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(69)

我使用Vue3和naive ui来开发前端,但我主要是一个后端开发人员,我对前端不太了解。
我使用naive ui的BasicTable为列表中的每一行数据添加一个Edit button,通过点击Edit按钮,弹出一个对话框,在这里我可以完成对当前行记录的修改,点击OK将修改后的数据发送到后端完成修订。
在naive ui中,对话框是通过useDialog().create()创建的,而普通对话框直接显示为组件,没有弹出效果,所以我只能使用默认的useDialog方法。
这样,如果我想在对话框中自定义表单,我必须使用render function h。我使用h函数创建一个子组件,如下所示:

function handleEdit(record: Recordable) {
    currentRecord.value = record;
    const dialogIns = dialog.create({
      title: 'edit User',
      content: () => {
        return h(EditEmployee, {
          source: currentRecord.value,
          on: {
            updateEmployee: (value) => {
              console.log(`emit Value is ${JSON.stringify(value)}`);
              dialogIns.destroy();
            },
            cancelUpdate: () => {
              console.log('cancel');
              dialogIns.destroy();
            },
          },
        });
      },
      // positiveText: 'Submit',
      // negativeText: 'Cancel',
      // onPositiveClick: () => {},
      // onNegativeClick: () => {},
    });
  }

字符串
接下来,我定义了子组件a form and two buttons,这两个按钮分别代表提交和取消。

<template>
  <div>
    <n-form :model="editEmployee">
      <n-form-item label="Id">
        <n-input v-model:value="editEmployee.eid" disabled />
      </n-form-item>
      <n-form-item label="Name">
        <n-input v-model:value="editEmployee.empName" />
      </n-form-item>
      <n-form-item label="Identity">
        <n-input v-model:value="editEmployee.sysId" />
      </n-form-item>
      <n-form-item label="InGroupId">
        <n-input v-model:value="editEmployee.inGroupId" />
      </n-form-item>
      <n-grid :cols="24">
        <n-gi :span="16"></n-gi>
        <n-gi :span="4">
          <n-button type="info" @click="handleUpdate"> Submit</n-button>
        </n-gi>
        <n-gi :span="4">
          <n-button type="tertiary" @click="handleCancel">Cancel</n-button>
        </n-gi>
      </n-grid>
    </n-form>
  </div>
</template>

<script lang="ts" setup>
  import { computed, ref } from 'vue';

  const emit = defineEmits(['updateEmployee', 'cancelUpdate']);

  const source_data = defineProps<{
    source: {
      eid: number;
      sysId: string | null;
      empName: string | null;
      inGroupId: string | null;
    };
  }>();

  const editEmployee = ref({ ...source_data.source });

  function handleUpdate() {
    console.log(`update Event for param ${JSON.stringify(editEmployee.value)}`);
    emit('updateEmployee', editEmployee.value);
  }

  function handleCancel() {
    emit('cancelUpdate');
  }
</script>

<style lang="less" scoped></style>


Submitting获取当前表单数据,然后将其发送给父组件,后者将更新数据(因为在naive ui的对话框组件中,提交和取消由父组件(onPositiveClick, onNegativeClick)控制,子组件不能在没有任何按钮的情况下给予新数据给父组件,所以子组件必须主动地将其发送给父组件(至少它需要向父组件提交关闭对话框事件))。
但是在我定义之后,我发现子组件的emit方法根本不会被父组件接收,我尝试了很多方法,但是都失败了。
所以,我的问题是如何让父组件接收到子组件发出的emit事件,因为我实际在浏览器中调试的时候,发现子组件中的console.log方法被触发了,但是发出之后,父组件却无法接收,我想知道这是怎么回事。

p3rjfoxz

p3rjfoxz1#

在父组件中创建一个函数,并在子组件中创建一个具有Function类型的props,然后将函数从父组件传递到子组件,并在子组件中调用它。
在父组件中

<script setup>

function updateEmployee(value) {
   console.log(value)
}
     
 

dialog.create({ 
   content: () => h(EditEmployee, {
      onUpdateEmployee: updateEmployee
     })
  })
</script>

字符串
在子组件中

<template>
 <button @click="onUpdateEmployee(value)">update</button>
</template>

<script setup>
  const props = defineProps({
   onUpdateEmployee: {
      type: Function,
      required: true,
   }
})
</script>

相关问题