vue3组件父子传值

549 阅读1分钟
  1. 父组件提供数据
  2. 父组件将数据传递给子组件
  3. 子组件通过defineProps进行接收
  4. 子组件渲染父组件传递的数据

父组件页面 引入子组件

  <px-sign
        v-else-if="node.type == 5 || node.type == 6"
        :data="node"
        :show="show"
        :iszfyh="iszfyh"
        :isManage="isManage"
        :admin="admin"
        :directoryList="directoryList"
        :showDownload="showDownload"
        :status="status"
        @cancelfile="cancelfile"
        @closeDialog="closeDialog"
        @handleSubmit="handleSubmit"
        @handleChange="handleChange"
      ></px-sign>

emits属性是Vue 3中新增的一个选项,用于明确组件可以触发哪些事件。这样在组件实例中使用emit方法触发事件时,就可以在开发阶段或者TypeScript中进行类型检查,以避免拼写错误或者不必要的事件触发。emits的值指示这个组件可以触发两个事件:closeDialogupdateData。使用emit方法触发事件时,就可以在开发阶段或者TypeScript中进行类型检查,以避免拼写错误或者不必要的事件触发。 emits的值指示这个组件可以触发两个事件:closeDialog和updateData。使用emit方法并传入相应的事件名和参数可以触发这两个事件,比如:
emits: ["closeDialog", "updateData"],

在父组件中监听这些事件,就可以根据具体情况进行处理,例如更新数据或关闭弹窗。

传递给子组件的数据:

        :data="node"
        :show="show"
        :iszfyh="iszfyh"
        :isManage="isManage"
        :admin="admin"
        :directoryList="directoryList"
        :showDownload="showDownload"
        :status="status" 

这写是方法:

        @cancelfile="cancelfile"
        @closeDialog="closeDialog"
        @handleSubmit="handleSubmit"
        @handleChange="handleChange"
        

父组件方法的写法:

    //提交上传
        function handleSubmit() {
          if (visitedViews.value) {
            proxy.$modal
              .confirm("提交后进入审批,非驳回不可上传,请确认后提交!")
              .then(function () {
                let params = {
                  ...props.node,
                  isUpload: 1,
                };
                console.log("params", params);
                flowSubmit(params).then((res) => {
                  const loading = ElLoading.service({
                    lock: true,
                    text: "数据提交中,请稍后...",
                    background: "rgba(0, 0, 0, 0.7)",
                  });
                  ctx.emit("updateData")
                  ctx.emit("closeDialog");
                  setTimeout(function () {
                    loading.close();
                  }, 2000); // 定时时间
                });
              });
          } else {
            console.log(5252);
            ElMessage({
              type: "error",
              message: "上传文件不可为空",
            });
          }
        }
      
        

1 props 是父组件传递的属性值(以对象形式传递),而 ctx 是提供给组件的上下文对象。通过 ctx 可以获取一些 Vue 内置的工具函数(如 emit、attrs、slots 等),同时也可以将一些函数或数据设置为响应式的。

      setup(props, ctx) {
        const { proxy } = getCurrentInstance();
        let directoryList = ref([]);
 这段代码使用Vue 3的computed函数创建了一个计算属性show,其值由props对象中的show属性计算得出。

具体来说,computed函数接收一个函数,该函数作为计算属性的getter函数,当计算属性被访问时,该函数被调用并返回计算属性的值。

在本例中,getter函数中使用箭头函数返回props对象中的show属性,即show计算属性的值等于props.show。这意味着当props.show发生变化时,show计算属性的值也会相应地更新。

这种方式可以方便地从父组件中读取数据,并将其转换为计算属性,以供子组件使用。

           let show = computed(() => props.show);
            let iszfyh = computed(() => props.iszfyh);
            let isManage = computed(() => props.isManage);
            let admin = computed(() => props.admin);
            let node = computed(() => props.node);
            let status = computed(() => props.status);
            const active = ref(null);
            const store = useStore();
            const visitedViews = computed(() =>       store.state.operate.have);
            const hsitoryStephome = reactive({
              hsitoryStep: {
                open: false,
              },
            });
            const isUpload = ref(1);
            const sdeptarr = ref([]);
            if (node.value.spTime1 != null) {
              spTime1.value = changedateformate(node.value.spTime1);
            }
            if (node.value.spTime2 != null) {
              spTime2.value = changedateformate(node.value.spTime2);
            }
            if (node.value.uploadTime != null) {
              uploadTime.value = changedateformate(node.value.uploadTime);
            }
           
1.  `hsitoryStephome`是一个响应式对象或ref对象,里面包含了 `hsitoryStep` 这个响应式属性。将 `hsitoryStep` 赋值给了常量 `hsitoryStep`,这样就可以在组件中使用 `hsitoryStep` 这个响应式数据。
            const { hsitoryStep } = toRefs(hsitoryStephome);
            
            这段代码定义了一个箭头函数closeDialog,它接收一个无参数的参数列表。当执行closeDialog函数时,它会调用ctx对象的emit方法,并传递一个字符串参数"closeDialog"。这意味着,使用该函数时,在上下文ctx中触发了一个名为"closeDialog"的事件。
            let closeDialog = () => {
              ctx.emit("closeDialog");
            };
            let updateData = (data) => {
              ctx.emit("updateData", data);
            };
            
            

步骤:

  1. 子组件通过defineEmit获取emit对象(因为没有this)
  2. 子组件通过emit触发事件,并且传递数据
  3. 父组件提供方法
  4. 父组件通过自定义事件的方式给子组件注册事件

子组件中:子组件通过defineProps进行接收

        const props = defineProps({
          data: { type: Object },
          show: { type: Boolean },
          status: { type: Number },
          iszfyh: { type: Boolean },
          isManage: { type: Boolean },
          admin: { type: Boolean },
          directoryList: { type: Array },
          showDownload: { type: Boolean },
        });
            

Vue3中的watchEffect函数,它可以让我们监听响应式数据的变化并执行回调函数。

          watchEffect(() => {
          node.value = {
            areaId: props.data.areaId,
            projectId: props.data.projectId,
          };
        });
        

子组件内部:

          function cancelfile() {
                  emit("cancelfile");
                } 

在父组件中,监听子组件发出的事件,并对传递过来的参数进行处理 父组件中:

      function cancelfile() {
          proxy.$modal.confirm("撤销后需再次上传方可审批").then(function () {
            let params = {
              ...props.node,
            };
            cancel(params).then((res) => {
              const loading = ElLoading.service({
                lock: true,
                text: "正在撤回中...",
                background: "rgba(0, 0, 0, 0.7)",
              });
              ctx.emit("updateData");
              // proxy.$modal.msgSuccess("提交成功");
              ctx.emit("closeDialog");
              setTimeout(function () {
                loading.close();
              }, 2000); // 定时时间
            });
          });
        }
        
        
        

记录一下 这个博主讲的好清晰 blog.csdn.net/csdn7272326…