avue或者vue子组件数据变化后刷新父组件

本文详细介绍了如何在使用Avue表单设计器时,通过子组件操作触发父组件数据的刷新,包括两种方法:直接在父组件中定义刷新方法和通过子组件的自定义事件更新父组件。涉及到了Vue组件间的通信和数据同步技巧。

关注Avue表单设计器的使用: 【Avue表单设计器的使用技巧】

关注Avue企业级开发应用官方源代码: 官方源代码

 

描述:  使用avue.js或者vue.js做后台管理系统时,常常涉及到子组件(子弹窗) 修改,添加操作后,需要刷新父组件重新加载数据:

           父组件代码:  重点关注该方法:

           父组件中定义该方法:

 handleRefreshChange() {
      this.getList(this.page);  // 父组件获取后台的数据
 }
<template>
  <div class="user">
    <basic-container>
      <avue-crud
        :option="option"
        ref="crud"
        v-model="form"
        :page="page"
        @on-load="getList"
        @size-change="sizeChange"
        @current-change="currentChange"
        :table-loading="listLoading"
        @search-change="handleFilter"
        @refresh-change="handleRefreshChange"
        @row-update="update"
        @row-save="create"
        :before-open="handleOpenBefore"
        :data="list"
      >
        <template slot="username" slot-scope="scope">
          <span>{{ scope.row.username }}</span>
        </template>
        <template slot="amount" slot-scope="scope">
          <div v-if="scope.row.currType === 'VIR'">
            {{ scope.row.amount }}
          </div>
          <div v-if="scope.row.currType !== 'VIR'">
            {{ scope.row.amount / 100 }}
          </div>
        </template>

        <template slot="role" slot-scope="scope">
          <span v-for="(role, index) in scope.row.roleList" :key="index">
            <el-tag>{{ role.roleName }} </el-tag>&nbsp;&nbsp;
          </span>
        </template>
        <template slot="deptId" slot-scope="scope">
          {{ scope.row.deptName }}
        </template>
        <template slot="lockFlag" slot-scope="scope">
          <el-tag>{{ scope.label }}</el-tag>
        </template>
        <template slot="menu" slot-scope="scope">
          <el-button v-show = "scope.row.status == 100 || scope.row.status == 110"
            type="text"
            icon="el-icon-edit"
            @click="handleView(scope.row, scope.index)">冲账
          </el-button>
          <el-button  v-show = "scope.row.status === -100"
            type="text"
            icon="el-icon-edit"
            @click="handlePushItem(scope.row, scope.index)">重新记账
          </el-button>
        </template>
      </avue-crud>
    </basic-container>
    <info-view v-if="infoVisible" ref="infoView"></info-view>
  </div>
</template>

<script>
import { fetchList, putObj, putObjStatus } from "@/api/acct/acctTradeRecord";
import { deptRoleList } from "@/api/admin/role";
import { fetchTree } from "@/api/admin/dept";
import { tableOption } from "@/const/crud/acct/acctTradeRecord";
import InfoView from "./record-form";
import { mapGetters } from "vuex";

export default {
  name: "table_user",
  components: {
    InfoView,
  },
// data()函数返回对象 : {}
  data() {
    return {
      option: tableOption,
      treeDeptData: [],
      checkedKeys: [],
      roleProps: {  // 配置项传递数据
        label: "roleName",
        value: "roleId",
      },
      defaultProps: {
        label: "name",
        value: "id",
      },
      page: {
        total: 0, // 总页数
        currentPage: 1, // 当前页数
        pageSize: 10, // 每页显示多少条,
        isAsc: false, //是否倒序
      },
      searchParam: {},
      list: [],
      listLoading: true,
      role: [],
      form: {},  // 配置项key,value为一个空对象,相当于先声明一个变量,并初始化一个空对象
      rolesOptions: [],
      infoVisible: false,
    };
  },
  computed: {
    ...mapGetters(["permissions"]),
  },
  watch: {
    role() { // 没执行该方法时,都创建一个新实例对象{this.form.role = this.role},避免共享变量安全问题
      this.form.role = this.role;
    },
  },
  created() {
    this.business_user_add = this.permissions["business_user_add"];
    this.business_user_edit = this.permissions["business_user_edit"];
    this.business_user_del = this.permissions["business_user_del"];
  },
  methods: {
    getList(page, params) {
      if (params == undefined) {
        params = this.searchParam;
      }
      this.listLoading = true;
      fetchList(
        Object.assign(
          {
            current: page.currentPage,
            size: page.pageSize,
          },
          params
        )
      ).then((response) => {
        this.list = response.data.data.records;
        this.page.total = response.data.data.total;
        this.listLoading = false;
      });
    },
    getNodeData(data) {
      deptRoleList(this.$store.state.user.userInfo.tenantId).then(
        (response) => {
          this.rolesOptions = response.data.data;
        }
      );
    },
    sizeChange(pageSize) {
      this.page.pageSize = pageSize;
    },
    currentChange(current) {
      this.page.currentPage = current;
    },
    handleFilter(param, done) {
      this.page.currentPage = 1;
      this.getList(this.page, param);
      this.searchParam = param;
      done();
    },
    // 父组件定义刷新的页面方法
    handleRefreshChange() {
      this.getList(this.page);
    },
    handleOpenBefore(show, type) {
      window.boxType = type;
      // 查询部门树
      fetchTree().then((response) => {
        this.treeDeptData = response.data.data;
      });
      // 查询角色列表
      deptRoleList(this.$store.state.user.userInfo.tenantId).then(
        (response) => {
          this.rolesOptions = response.data.data;
        }
      );
      // 若是编辑、查看回显角色名称
      if (["edit", "views"].includes(type)) {
        this.role = [];
        for (let i = 0; i < this.form.roleList.length; i++) {
          this.role[i] = this.form.roleList[i].roleId;
        }
      } else if (type === "add") {
        // 若是添加角色列表设置为空
        this.role = [];
      }
      show();
    },

    create(row, done, loading) {
      addObj(this.form)
        .then(() => {
          this.getList(this.page);
          done();
          this.$notify.success("创建成功");
        })
        .catch(() => {
          loading();
        });
    },
    update(row, index, done, loading) {
      putObj(this.form)
        .then(() => {
          this.getList(this.page);
          done();
          this.$notify.success("修改成功");
        })
        .catch(() => {
          loading();
        });
    },
    handleView(row, index) {
      this.infoVisible = true;
      this.$nextTick(() => {
        this.$refs.infoView.init(row.id); // 给InfoView组件中的init方法赋值
      });
    },
    handlePushItem(row, index) {
       this.$confirm("此操作将重新记账操作, 是否继续?", "提示", {
                        confirmButtonText: "确定",
                        cancelButtonText: "取消", type: "warning"
                 }
                ).then(()=> {
                      putObjStatus(row).then(response=>{      
                      let resultCode = response.data.code;
                      console.info("resultData: "+JSON.stringify(resultCode));
                      this.getList(this.page);
                      if(resultCode ===0){
                          this.$message.success('操作成功')
                      }else{
                          this.$message.error("操作失败");
                      }
                      
                   }).catch((e)=>{
                       this.getList(this.page); // 当前页面刷新
                      this.$message.error(e)
                   });
                }).catch(()=>{});

    },
  },
};
</script>

子组件代码: (子弹窗)

 关注子组件(子页面)调用父页面的方法,刷新父页面;

this.$parent.handleRefreshChange(); // 刷新父页面

<style type="text/css">
       .customWidth{
        width:30%;
    }
</style>
<template>
  <!-- 添加或修改菜单对话框 -->
  <el-dialog 
             :visible.sync="visible"  customClass="customWidth">
    <el-form ref="dataForm" :model="form"  label-width="80px">
      
      <el-form-item label="编号" prop="cusNo">
        <el-input v-model="form.cusNo" placeholder="编号不能为空" disabled/>
      </el-form-item>
      <el-form-item label="冲账原因" prop="reason">
        <el-input v-model="form.reason" type="textarea" rows="10" placeholder="请输入冲账原因"/>
      </el-form-item>
      

    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button type="primary" @statusChange="listenSignStatus" @click="dataFormSubmit">确 定</el-button>
      <el-button @click="visible = false">取 消</el-button>
    </div>
  </el-dialog>
</template>

<script>
  import {putObj} from '@/api/acct/acctTradeRecord'
  import TableForm from './'
  import "@riophae/vue-treeselect/dist/vue-treeselect.css"
  export default {
    name: "record-info",
    components: {TableForm},
    data() {
      return {
        // 遮罩层
        loading: true,
        // 是否显示弹出层
        visible: false,
        form: {
          cusNo: undefined,
          reason: undefined,
        }
      };
    },
    methods: {
      init(id) {
        if (id != null) {
          this.form.cusNo = id;
        }
        this.visible = true
      },
    dataFormSubmit() {
        this.$refs['dataForm'].validate((valid) => {
          if (valid) {
            putObj(this.form).then((response) => {
              let resultCode = response.data.code;
              console.info("resultData: " + JSON.stringify(resultCode));
              this.$message.success('恭喜您,冲账成功');
              this.visible = false;   // 关闭子组件
              this.$parent.handleRefreshChange(); // 刷新父页面
            }).catch((e)=>{
              this.$parent.handleRefreshChange(); // 调用父组件的方法,直接进行刷新
              this.$message.error(e);
            });
          }
        })
      },
    
    }
  };
</script>

方法二: 

  1. //在父组件中设置

  2. <template>
      <div class="user">
        <basic-container>
          <avue-crud
            :option="option"
            ref="crud"
            v-model="form"
            :page="page"
            @on-load="getList"
            @size-change="sizeChange"
            @current-change="currentChange"
            :table-loading="listLoading"
            @search-change="handleFilter"
            @refresh-change="handleRefreshChange"
            @row-update="update"
            @row-save="create"
            :before-open="handleOpenBefore"
            :data="list"
     
          >
            <template slot="username" slot-scope="scope">
              <span>{{ scope.row.username }}</span>
            </template>
            <template slot="amount" slot-scope="scope">
              <div v-if="scope.row.currType === 'VIR'">
                {{ scope.row.amount }}
              </div>
              <div v-if="scope.row.currType !== 'VIR'">
                {{ scope.row.amount / 100 }}
              </div>
            </template>
    
            <template slot="role" slot-scope="scope">
              <span v-for="(role, index) in scope.row.roleList" :key="index">
                <el-tag>{{ role.roleName }} </el-tag>&nbsp;&nbsp;
              </span>
            </template>
            <template slot="deptId" slot-scope="scope">
              {{ scope.row.deptName }}
            </template>
            <template slot="lockFlag" slot-scope="scope">
              <el-tag>{{ scope.label }}</el-tag>
            </template>
            <template slot="menu" slot-scope="scope">
              <el-button v-show = "scope.row.status == 100 || scope.row.status == 110"
                type="text"
                icon="el-icon-edit"
                @click="handleView(scope.row, scope.index)">冲账
              </el-button>
              <el-button  v-show = "scope.row.status === -100"
                type="text"
                icon="el-icon-edit"
                @click="handlePushItem(scope.row, scope.index)">重新记账
              </el-button>
            </template>
          </avue-crud>
        </basic-container>
        <info-view v-if="infoVisible"  @refresh-TableData="refreshChangeDataList" 
     ref="infoView"></info-view>  《只能配置在子组件中,才能生效,配置在父组件中不生效,亲测》
      </div>
    </template>
    
    <script>
    import { fetchList, putObj, putObjStatus } from "@/api/acct/acctTradeRecord";
    import { deptRoleList } from "@/api/admin/role";
    import { fetchTree } from "@/api/admin/dept";
    import { tableOption } from "@/const/crud/acct/acctTradeRecord";
    import InfoView from "./record-form";
    import { mapGetters } from "vuex";
    
    export default {
      name: "table_user",
      components: {
        InfoView,
      },
      data() {
        return {
          option: tableOption,
          treeDeptData: [],
          checkedKeys: [],
          roleProps: {
            label: "roleName",
            value: "roleId",
          },
          defaultProps: {
            label: "name",
            value: "id",
          },
          page: {
            total: 0, // 总页数
            currentPage: 1, // 当前页数
            pageSize: 10, // 每页显示多少条,
            isAsc: false, //是否倒序
          },
          searchParam: {},
          list: [],
          listLoading: true,
          role: [],
          form: {},
          rolesOptions: [],
          infoVisible: false,
        };
      },
      computed: {
        ...mapGetters(["permissions"]),
      },
      watch: {
        role() {
          this.form.role = this.role;
        },
      },
      created() {
        this.business_user_add = this.permissions["business_user_add"];
        this.business_user_edit = this.permissions["business_user_edit"];
        this.business_user_del = this.permissions["business_user_del"];
      },
      methods: {
        getList(page, params) {
          if (params == undefined) {
            params = this.searchParam;
          }
          this.listLoading = true;
          fetchList(
            Object.assign(
              {
                current: page.currentPage,
                size: page.pageSize,
              },
              params
            )
          ).then((response) => {
            this.list = response.data.data.records;
            this.page.total = response.data.data.total;
            this.listLoading = false;
          });
        },
        getNodeData(data) {
          deptRoleList(this.$store.state.user.userInfo.tenantId).then(
            (response) => {
              this.rolesOptions = response.data.data;
            }
          );
        },
        sizeChange(pageSize) {
          this.page.pageSize = pageSize;
        },
        currentChange(current) {
          this.page.currentPage = current;
        },
        handleFilter(param, done) {
          this.page.currentPage = 1;
          this.getList(this.page, param);
          this.searchParam = param;
          done();
        },
        // 刷新父页面的方法,并获取来自子页面的数据
        refreshChangeDataList(valData){
          console.info("子组件传递的参数:"+valData);
          this.getList(this.page);
        },
        handleRefreshChange() {
          this.getList(this.page);
        },
        handleOpenBefore(show, type) {
          window.boxType = type;
          // 查询部门树
          fetchTree().then((response) => {
            this.treeDeptData = response.data.data;
          });
          // 查询角色列表
          deptRoleList(this.$store.state.user.userInfo.tenantId).then(
            (response) => {
              this.rolesOptions = response.data.data;
            }
          );
          // 若是编辑、查看回显角色名称
          if (["edit", "views"].includes(type)) {
            this.role = [];
            for (let i = 0; i < this.form.roleList.length; i++) {
              this.role[i] = this.form.roleList[i].roleId;
            }
          } else if (type === "add") {
            // 若是添加角色列表设置为空
            this.role = [];
          }
          show();
        },
    
        create(row, done, loading) {
          addObj(this.form)
            .then(() => {
              this.getList(this.page);
              done();
              this.$notify.success("创建成功");
            })
            .catch(() => {
              loading();
            });
        },
        update(row, index, done, loading) {
          putObj(this.form)
            .then(() => {
              this.getList(this.page);
              done();
              this.$notify.success("修改成功");
            })
            .catch(() => {
              loading();
            });
        },
        handleView(row, index) {
          this.infoVisible = true;
          this.$nextTick(() => {
            this.$refs.infoView.init(row.id); // 给InfoView组件中的init方法赋值
          });
        },
        handlePushItem(row, index) {
           this.$confirm("此操作将重新记账操作, 是否继续?", "提示", {
                            confirmButtonText: "确定",
                            cancelButtonText: "取消", type: "warning"
                     }
                    ).then(()=> {
                          putObjStatus(row).then(response=>{      
                          let resultCode = response.data.code;
                          console.info("resultData: "+JSON.stringify(resultCode));
                          this.getList(this.page);
                          if(resultCode ===0){
                              this.$message.success('操作成功')
                          }else{
                              this.$message.error("操作失败");
                          }
                          
                       }).catch((e)=>{
                           this.getList(this.page); // 当前页面刷新
                          this.$message.error(e)
                       });
                    }).catch(()=>{});
    
        },
      },
    };
    </script>
    

    子组件代码如下:

  3. <style type="text/css">
           .customWidth{
            width:30%;
        }
    </style>
    <template>
      <!-- 添加或修改菜单对话框 -->
      <el-dialog 
                 :visible.sync="visible"  :ticustomClass="customWidth">
        <el-form ref="dataForm" :model="form"  label-width="80px">
          
          <el-form-item label="编号" prop="cusNo">
            <el-input v-model="form.cusNo" placeholder="编号不能为空" disabled/>
          </el-form-item>
          <el-form-item label="冲账原因" prop="reason">
            <el-input v-model="form.reason" type="textarea" rows="10" placeholder="请输入冲账原因"/>
          </el-form-item>
          
    
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button type="primary"  @click="dataFormSubmit">确 定</el-button>
          <el-button @click="visible = false">取 消</el-button>
        </div>
      </el-dialog>
    </template>
    
    <script>
      import {putObj} from '@/api/acct/acctTradeRecord'
      import TableForm from './'
      import "@riophae/vue-treeselect/dist/vue-treeselect.css"
      export default {
        name: "record-info",
        components: {TableForm},
        data() {
          return {
            // 遮罩层
            loading: true,
            // 是否显示弹出层
            visible: false,
            form: {
              cusNo: undefined,
              reason: undefined,
            }
          };
        },
        methods: {
          init(id) {
            if (id != null) {
              this.form.cusNo = id;
            }
            this.visible = true
          },
    // 提交完成后刷新父页面
        dataFormSubmit() {
            this.$refs['dataForm'].validate((valid) => {
              if (valid) {
                putObj(this.form).then((response) => {
                  let resultCode = response.data.code;
                  console.info("resultData: " + JSON.stringify(resultCode));
                  this.$message.success('恭喜您,冲账成功');
                  this.visible = false; 
                  this.$emit('refresh-TableData',true); // 刷新父页面this.$emit('eventName',param)
                  //this.$parent.handleRefreshChange();
                }).catch((e)=>{
                  this.$emit('refresh-TableData',true);
                  //this.$parent.handleRefreshChange(); // 调用父组件的方法,直接进行刷新
                  this.$message.error(e);
                });
              }
            })
          },
        
        }
      };
    </script>
    

  4. 子页面刷新父组件:  this.$emit('refresh-TableData',true); // 刷新父页面this.$emit('eventName',param),事件名为refresh-TableData 与父组件<avue-crud> 中的配置:

  5.    @refresh-TableData="refreshChangeDataList"  《父组件中配置refreshChangeDataList 方法名,并在配置项methods中申明该方法,如下》! 保持一致 【@refresh-TableData】

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值