vue中装弹框为子组件 涉及的相关父子组件传参的问题

Posted 嘴巴嘟嘟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue中装弹框为子组件 涉及的相关父子组件传参的问题相关的知识,希望对你有一定的参考价值。

业务要求 : 父组件点击 按钮 子组件 弹框
在这里插入图片描述

【VUE报错】vue.runtime.esm.js?2b0e:619 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “dialogVisible”

抽取弹框会遇到的问题:

  1. 打开弹框时父传子,修改弹框显示属性为true(没问题)
  2. 关闭弹框时子传父,子组件需要去修改父组件的弹框显示属性,涉及到单向数据流(子组件无法修改父组件的属性)
    下面给出解决方案:
    主界面
<template>
  <div>
    <el-row>
      <el-col>
        <el-button type="primary" @click="addObj()">新增</el-button>
      </el-col>
      <el-col :span="24">
        <el-table :data="tableData" style="width: 100%">
          <el-table-column width="40"> </el-table-column>
          <el-table-column prop="date" label="日期" width="200">
          </el-table-column>
          <el-table-column prop="name" label="姓名" width="200">
          </el-table-column>
          <el-table-column prop="sex" label="性别" width="150">
            <template slot-scope="{ row }">
              {{ row.sex == 1 ? "男" : "女" }}
            </template>
          </el-table-column>
          <el-table-column prop="phone" label="联系电话" width="200">
          </el-table-column>
          <el-table-column prop="address" label="地址"> </el-table-column>
          <el-table-column label="操作">
            <template slot-scope="scope">
              <el-button
                size="mini"
                @click="handleEdit(scope.$index, scope.row)"
                >编辑</el-button
              >
              <el-button
                size="mini"
                type="danger"
                @click="handleDelete(scope.$index, scope.row)"
                :plain="true"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table></el-col
      >
    </el-row>
    <operation
      :listObj="dataValue"
      :dialogVisible="isShow"
      @close="closeDialog"
      @newForm="newForm"
    ></operation>
  </div>
</template>

<script>
import operation from "./operation.vue";
export default {
  name: "List",
  components: {
    operation,
  },
  data() {
    return {
      dataValue: {},
      tableData: [
        {
          id: "1",
          date: "2016-05-02",
          name: "王小虎",
          sex: "1",
          phone: "13866668888",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          id: "2",
          date: "2016-05-04",
          name: "王小虎",
          sex: "1",
          phone: "13866668888",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          id: "3",
          date: "2016-05-01",
          name: "王小虎",
          sex: "0",
          phone: "13866668888",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          id: "4",
          date: "2016-05-03",
          name: "王小虎",
          sex: "1",
          phone: "13866668888",
          address: "上海市普陀区金沙江路 1518 弄",
        },
      ],
      isShow: false,
    };
  },
  methods: {
    handleEdit(index, row) {
      this.dataValue = row;
      this.isShow = true;
    },
    handleDelete(index, row) {
      const h = this.$createElement;
      this.$message({
        message: h("p", null, [
          h("span", null, "已经删除 "),
          h("i", { style: "color: teal" }, "删除成功"),
        ]),
      });
      this.tableData.splice(index, 1);
    },
    addObj() {
      this.dataValue = {};
      this.isShow = true;
    },
    closeDialog() {
      this.isShow = false;
    },
    newForm(value) {
      let id = value.id;
      if (!id) {
        value.id = this.tableData.length + 1;
      } else {
        // console.log(this.tableData.indexOf(value));
        this.tableData.push(value);
      }
    },
  },
};
</script>

<style  scoped>
.el-table {
  text-align: center;
}
.el-table .warning-row {
  background: oldlace;
}

.el-table .success-row {
  background: #f0f9eb;
}
.el-main[data-v-5954443c] {
  line-height: 0px;
}
.tankuang {
  height: 20%;
}
</style>

子组件

<template>
  <el-dialog
    :modal="false"
    :title="Object.keys(form).length == 0 ? '新增' : '修改'"
    :visible.sync="dialogFormVisible"
    :show-close="false"
    @close="closeDialog()"
  >
    <el-form
      :model="form"
      :rules="rulesform"
      ref="formData"
      class="demo-ruleForm"
    >
      <el-form-item label="日期" :label-width="formLabelWidth" prop="date">
        <el-date-picker
          type="date"
          placeholder="选择日期"
          v-model="form.date"
          style="width: 100%"
        ></el-date-picker>
      </el-form-item>
      <el-form-item label="姓名" :label-width="formLabelWidth" prop="name">
        <el-input v-model="form.name" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="性别" :label-width="formLabelWidth" prop="sex">
        <el-radio v-model="form.sex" label="1"></el-radio>
        <el-radio v-model="form.sex" label="0"></el-radio>
      </el-form-item>
      <el-form-item label="联系电话" :label-width="formLabelWidth" prop="phone">
        <el-input v-model="form.phone" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="地址" :label-width="formLabelWidth" prop="address">
        <el-input v-model="form.address" autocomplete="off"></el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisibleClose('formData')">取 消</el-button>
      <el-button type="primary" @click="dialogFormVisibleSave('formData')"
        >确 定</el-button
      >
    </div>
  </el-dialog>
</template>

<script>
export default {
  name: "operation",
  props: {
    listObj: {
      type: Object,
    },
    dialogVisible: {
      type: Boolean,
    },
  },
  watch: {
    dialogVisible(vale) {
      this.dialogFormVisible = vale;
    },
    listObj: function (newVal, oldVal) {
      this.form = newVal;
    },
  },

  data() {
    return {
      title: "",
      form: {
        date: "",
        name: "",
        sex: 0,
        phone: "",
        address: "",
      },
      dialogFormVisible: this.dialogVisible,
      formLabelWidth: "120px",
      rulesform: {
        date: [
          { required: true, message: "请输入正确时间格式", trigger: "blur" },
        ],
        name: [
          { required: true, message: "请输入正确名字", trigger: "blur" },
          { min: 2, max: 5, message: "长度在 3 到 5 个字符", trigger: "blur" },
        ],
        sex: [{ required: true, message: "请选择性别", trigger: "blur" }],
        phone: [
          { required: true, message: "请输入正确手机号", trigger: "blur" },
        ],
        address: [
          { required: true, message: "请输入正确地址", trigger: "blur" },
        ],
      },
    };
  },
  methods: {
    dialogFormVisibleClose(formData) {
      this.$refs[formData].resetFields();
      this.$emit("close");
    },
    dialogFormVisibleSave(formData) {
      this.$refs[formData].validate((valid) => {
        if (valid) {
          this.$emit("newForm", this.form);
          this.$emit("close");
        } else {
          return false;
        }
      });
    },
    closeDialog() {
      this.$emit("close");
    },
  },
};
</script>

<style  scoped>
</style>

注意:首先第一个问题是 关于点出弹框问题 没法获取父组件传过来的值,使用watch监听即可获得,判断新老数据,关闭弹窗则使用 子组件发送给父组件 提交close 实现关闭

以上是关于vue中装弹框为子组件 涉及的相关父子组件传参的问题的主要内容,如果未能解决你的问题,请参考以下文章

vue组件传参

vue非父子组件间传参问题

vue父子组件传值

vue中的父子组件之间的通信--新增修改弹框

vue父子传参

React --react父子组件传参