一、Vue2实现:

使用.sync修饰符:实现子组件同步改变父组件通过props对应绑定的父组件变量值。

<!-- 父组件:使用封装的el-dialog子组件 -->
<add-or-edit-dep-dialog v-if="showAddOrEditDialog" :show.sync="showAddOrEditDialog" :title="title" @update="updateList"/>
<script lang="ts">
@Component({
  name: 'FatherComponent',
  components: {
    AddOrEditDepDialog: () => import(/* webpackChunkName: 'add-or-edit-dep-dialog' */ './components/add-or-edit-dep-dialog.vue'),
  }
})
...
private showAddOrEditDialog = false
</script>
<!-- 子组件:使用了el-dialog组件 -->
<template>
  <div class="add-or-edit-detail-container">
    <!--:before-close="closeDg",用于解决第一次点击可以弹框,第2次点击弹框不出现的bug  -->
    <el-dialog :title="title" :visible.sync="visible" width="65%" top="5vh" :destroy-on-close="true" :close-on-click-modal="false" :show-close="!loading" :before-close="closeDg">
      <div class="add-box my-custom-form" v-loading="loading">
        <el-form ref="form" :model="form" label-width="28%" size="small" :rules="formRules">
          ...
        </el-form>
        <el-divider/>
        <el-row type="flex" justify="center">
          <el-button @click="closeDg" class="mr-10">取消</el-button>
          <el-button type="primary" @click="submit('form')">确定</el-button>
        </el-row>
      </div>
    </el-dialog>
  </div>
</template>
<script lang="ts">
import { Component, Vue, Prop, Watch } from 'vue-property-decorator'

@Component({
  name: 'AddOrEditDepDg'
})
export default class extends Vue {
  @Prop({ default: false }) private show!: boolean

  private visible = false

  ... // 省略代码

  @Watch('show', { immediate: true })
    private setShow(val: boolean) {
       this.visible = val
    }

  private closeDg() {
    this.$emit('update:show', false)
  }
}
</script>

二、Vue3实现:

xxx.sync 修饰符在vue3中已废弃,需改用 v-model: xxx 用法。

setup语法糖实现:

<!-- 父组件 -->
<use-child-dialog v-model:show="showChild" />

<script setup lang="ts">
  import { ref } from "vue";
  let showChild = ref(false)
</script>
<!-- 子组件 -->
<script lang="ts" setup>
 const emit = defineEmits(["update:show"]);
 const close = () => {
   emit('update:show', false) // 自动修改父组件的变量值为false
}
</script>

非setup语法糖实现: 

<!-- 父组件 -->
<template>
   <div class="parent_wrapper">
    <ProjectNameEdit v-model:show="showAddOrEdit" :title="dialogTitle" @update-show="updateShow"/>
   </div>
</template>

<script>
import { defineComponent, reactive, toRefs, onMounted } from 'vue'
import ProjectNameEdit from './components/project-name-edit.vue'

export default defineComponent({
  components: {
    ProjectNameEdit
  },
  setup() {
    const state = reactive({
      dialogTitle: '',
      showAddOrEdit: false
    }),
    
    ... // 省略代码
    
    const updateShow = (payLoad) => {
      state.showAddOrEdit = payLoad // 子组件传给父组件的值
    }

    return {
      ...toRefs(state),
      updateShow
    }
  }
})
</script>
<!-- 子组件 -->
<template>
 <el-dialog v-model="visible" :title="title" :before-close="closeDg">
    <el-form :model="form" label-width="120px">
      ....
      <el-form-item>
        <el-button type="primary" @click="onSubmit">立即创建</el-button>
        <el-button @click="closeDg">取消</el-button>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>
<script>
import { defineComponent, reactive, toRefs, onMounted, watch } from 'vue'

export default defineComponent({
  props: {
    show: Boolean
  },

  emits: ['update-show'], // 定义声明emit触发的事件名

  setup(props, { emit }) {
    const state = reactive({
      form: {},
      visible: false
    })
    
    // 监听props对象的show属性
    watch(() => props.show, (newVal) => {
      state.visible = newVal
    }, { immediate: true })

    const closeDg = () => {
      state.visible = false
      emit('update-show', false) // 触发父事件,并传布尔值false
    }

    ... // 省略代码

    return {
      ...toRefs(state),
      closeDg
    }
  },
})
</script>

Logo

前往低代码交流专区

更多推荐