使用ant-design-vue的madal在table中,只能点击一次,并且会报错Avoid mutating a prop directly since...

使用ant-design-vue的madal在table中,只能点击一次,并且会报错

一、问题描述

最近学习过程中遇到这样一个问题。我想实现点击表格的每一行的修改按钮,都弹出一个modal框。

最初的思路(注意:之前用element-ui这么做没问题),封装一个modal组件,然后在父组件进行引入,当点击修改按钮的时候,改变显示与否的状态,并且传给modal子组件,子组件通过props接收。

但问题来了,点击第一次,可以正常弹出并且关闭,点击第二次modal框不弹了,并且始终报错
[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: “visible”

看一个大概示例
父组件

<template>
  <div>
    <a-table
      :columns="columns"
      :data-source="userData"
      bordered
      rowKey="_id"
      size="small"
      :pagination="false"
    >
      <span slot="roleTags" slot-scope="roleTags">
        <a-tag color="blue">{
    
    {
    
     roleTags}}</a-tag>
      </span>
      <span slot="jobTags" slot-scope="jobTags">
        <a-tag color="green">{
    
    {
    
     jobTags}}</a-tag>
      </span>
      <span slot="action" slot-scope="userInfo">
        <a-button type="link" @click="showUpdateModal">修改</a-button>

        <a-divider type="vertical" />
        <a-popconfirm
          title="确定删除?"
          ok-text="是"
          cancel-text="否"
          @confirm="sureDelete(userInfo)"
          @cancel="cancelDelete"
        >
          <a>删除</a>
        </a-popconfirm>
      </span>
    </a-table>

    <div class="pagination">
      <a-pagination
        size="small"
        :total="this.total"
        show-size-changer
        show-quick-jumper
        :defaultPageSize="this.pageSize"
        :pageSizeOptions="['2','5','10','15']"
        :show-total="total => `共${this.total}条`"
        @change="currentSizeData"
        @showSizeChange="changeSize"
      />
    </div>
    <UpdateUser :updateUserModal="updateUserModal" />
  </div>
</template>

<script>
import {
    
     getAllUser, getRoleId, deleteUser } from '@/network/user.js'
import {
    
     formateDate } from '@/utils/dateUtils.js'

import UpdateUser from './UpdateUser'

const columns = [
  {
    
    
    title: '用户名',
    dataIndex: 'username',
    align: 'center',
  },
  {
    
    
    title: '邮箱',
    dataIndex: 'email',
    align: 'center',
  },
  {
    
    
    title: '联系方式',
    dataIndex: 'phone',
    align: 'center',
  },
  {
    
    
    title: '所属角色',
    align: 'center',
    dataIndex: 'roleName',
    scopedSlots: {
    
     customRender: 'roleTags' },
  },
  {
    
    
    title: '职称',
    align: 'center',
    dataIndex: 'job',
    scopedSlots: {
    
     customRender: 'jobTags' },
  },
  {
    
    
    title: '注册时间',
    dataIndex: 'create_time',
    align: 'center',
    customRender: formateDate
  },
  {
    
    
    title: '操作',
    align: 'center',
    scopedSlots: {
    
     customRender: 'action' },
  },
];

export default {
    
    
  name: 'userManager',
  data () {
    
    
    return {
    
    
      userData: [],
      columns,
      pageNum: 1,
      pageSize: 5,
      total: 0,
      updateUserModal: false, //更新用户的modal
    };
  },
  components: {
    
    
    UpdateUser
  },
  computed: {
    
    

  },
  mounted () {
    
    
    this.getAllUser(this.pageNum, this.pageSize)
  },
  methods: {
    
    
    //获取所有用户列表
    async getAllUser (pageNum, pageSize) {
    
    
      const usersInfos = await getAllUser(pageNum, pageSize)
      console.log(usersInfos)
      if (usersInfos.status == 200) {
    
    
        this.total = usersInfos.data.data.total
        for (let item of usersInfos.data.data.list) {
    
    
          const curRoleId = item.role_id
          //有的用户还没有角色,防止因为传空值给后端接口造成问题
          if (curRoleId != '') {
    
    
            //根据roleid获取角色名称
            const curRoleName = await getRoleId(curRoleId)
            item.roleName = curRoleName.data.data
          }
        }
        this.userData = usersInfos.data.data.list
      }
    },
    //删除一个用户
    sureDelete (userInfo) {
    
    
      console.log(userInfo)
      deleteUser(userInfo._id).then(res => {
    
    
        if (res.data.status === 200) {
    
    
          this.$message.success(res.data.msg)
          //删除用户之后重新获取所有用户
          this.getAllUser(this.pageNum, this.pageSize)
        }
      })
    },
    //取消删除
    cancelDelete () {
    
    
      this.$message.success('取消删除成功')
    },
    //点击页码重新发起请求
    currentSizeData (currentPage, pageSize) {
    
    
      this.getAllUser(currentPage, this.pageSize)
    },
    //改变页码时,重新获取数据
    changeSize (current, size) {
    
    
      this.pageSize = size
      this.getAllUser(current, this.pageSize)
    },
    //显示更新用户的modal
    showUpdateModal () {
    
    
      console.log('*********')
      this.updateUserModal = true
    }
  },

};
</script>

<style scoped>
/* 分页位置 */
.pagination {
    
    
  margin-top: 15px;
  float: right;
}
</style>

子组件

<template>
  <div class="updateModal">
    <a-modal
      :visible="updateUserModalStatu"
      title="更新用户信息"
      @cancel="cancel"
      :destroyOnClose="destory"
    >
      <p>Some contents...</p>
      <p>Some contents...</p>
      <p>Some contents...</p>
    </a-modal>
  </div>
</template>

<script>
export default {
    
    
  name: '',
  props: {
    
    
    updateUserModal: {
    
    
      type: Boolean,
      default: () => {
    
    
        return false
      }
    }
  },
  data () {
    
    
    return {
    
    
      destory: true,
      updateUserModalStatu: this.updateUserModal,
    };
  },

  watch: {
    
    
    updateUserModal (value) {
    
    
      console.log(value)
      this.updateUserModalStatu = value
    }
  },
  computed: {
    
    

  },
  methods: {
    
    
    cancel () {
    
    
      console.log('****')
      this.updateUserModalStatu = false
    }
  },
  components: {
    
    

  },
};
</script>

<style scoped>
</style>

二、解决办法

利用vue $refs实现
不通过传值和props接收传值的方式了,通过使用ref直接操作子组件,控制其显示与否
父组件

<template>
  <div>
    <a-table
      :columns="columns"
      :data-source="userData"
      bordered
      rowKey="_id"
      size="small"
      :pagination="false"
    >
      <span slot="roleTags" slot-scope="roleTags">
        <a-tag color="blue">{
    
    {
    
     roleTags}}</a-tag>
      </span>
      <span slot="jobTags" slot-scope="jobTags">
        <a-tag color="green">{
    
    {
    
     jobTags}}</a-tag>
      </span>
      <span slot="action" slot-scope="userInfo">
        <a-button type="link" @click="showUpdateModal">修改</a-button>
        <a-divider type="vertical" />
        <a-popconfirm
          title="确定删除?"
          ok-text="是"
          cancel-text="否"
          @confirm="sureDelete(userInfo)"
          @cancel="cancelDelete"
        >
          <a>删除</a>
        </a-popconfirm>
      </span>
    </a-table>

    <div class="pagination">
      <a-pagination
        size="small"
        :total="this.total"
        show-size-changer
        show-quick-jumper
        :defaultPageSize="this.pageSize"
        :pageSizeOptions="['2','5','10','15']"
        :show-total="total => `共${this.total}条`"
        @change="currentSizeData"
        @showSizeChange="changeSize"
      />
    </div>
    <UpdateUser ref="modal" />
  </div>
</template>

<script>
import {
    
     getAllUser, getRoleId, deleteUser } from '@/network/user.js'
import {
    
     formateDate } from '@/utils/dateUtils.js'

import UpdateUser from './UpdateUser'

const columns = [
  {
    
    
    title: '用户名',
    dataIndex: 'username',
    align: 'center',
  },
  {
    
    
    title: '邮箱',
    dataIndex: 'email',
    align: 'center',
  },
  {
    
    
    title: '联系方式',
    dataIndex: 'phone',
    align: 'center',
  },
  {
    
    
    title: '所属角色',
    align: 'center',
    dataIndex: 'roleName',
    scopedSlots: {
    
     customRender: 'roleTags' },
  },
  {
    
    
    title: '职称',
    align: 'center',
    dataIndex: 'job',
    scopedSlots: {
    
     customRender: 'jobTags' },
  },
  {
    
    
    title: '注册时间',
    dataIndex: 'create_time',
    align: 'center',
    customRender: formateDate
  },
  {
    
    
    title: '操作',
    align: 'center',
    scopedSlots: {
    
     customRender: 'action' },
  },
];

export default {
    
    
  name: 'userManager',
  data () {
    
    
    return {
    
    
      userData: [],
      columns,
      pageNum: 1,
      pageSize: 5,
      total: 0,
      updateUserModal: false, //更新用户的modal
    };
  },
  components: {
    
    
    UpdateUser
  },
  computed: {
    
    

  },
  mounted () {
    
    
    this.getAllUser(this.pageNum, this.pageSize)
  },
  methods: {
    
    
    //获取所有用户列表
    async getAllUser (pageNum, pageSize) {
    
    
      const usersInfos = await getAllUser(pageNum, pageSize)
      console.log(usersInfos)
      if (usersInfos.status == 200) {
    
    
        this.total = usersInfos.data.data.total
        for (let item of usersInfos.data.data.list) {
    
    
          const curRoleId = item.role_id
          //有的用户还没有角色,防止因为传空值给后端接口造成问题
          if (curRoleId != '') {
    
    
            //根据roleid获取角色名称
            const curRoleName = await getRoleId(curRoleId)
            item.roleName = curRoleName.data.data
          }
        }
        this.userData = usersInfos.data.data.list
      }
    },
    //删除一个用户
    sureDelete (userInfo) {
    
    
      console.log(userInfo)
      deleteUser(userInfo._id).then(res => {
    
    
        if (res.data.status === 200) {
    
    
          this.$message.success(res.data.msg)
          //删除用户之后重新获取所有用户
          this.getAllUser(this.pageNum, this.pageSize)
        }
      })
    },
    //取消删除
    cancelDelete () {
    
    
      this.$message.success('取消删除成功')
    },
    //点击页码重新发起请求
    currentSizeData (currentPage, pageSize) {
    
    
      this.getAllUser(currentPage, this.pageSize)
    },
    //改变页码时,重新获取数据
    changeSize (current, size) {
    
    
      this.pageSize = size
      this.getAllUser(current, this.pageSize)
    },
    //显示更新用户的modal
    showUpdateModal () {
    
    
      this.$refs.modal.show()
    }
  },

};
</script>

<style scoped>
/* 分页位置 */
.pagination {
    
    
  margin-top: 15px;
  float: right;
}
</style>

子组件

<template>
  <div class="updateModal">
    <a-modal :visible="updateUserModal" title="更新用户信息" @cancel="cancel">
      <p>Some contents...</p>
      <p>Some contents...</p>
      <p>Some contents...</p>
    </a-modal>
  </div>
</template>

<script>
export default {
    
    
  name: '',
  // props: {
    
    
  //   updateUserModal: {
    
    
  //     type: Boolean,
  //     default: () => {
    
    
  //       return false
  //     }
  //   }
  // },
  data () {
    
    
    return {
    
    
      updateUserModal: false,
    };
  },
  computed: {
    
    

  },
  methods: {
    
    
    cancel () {
    
    
      this.updateUserModal = false
    },
    show () {
    
    
      this.updateUserModal = true
    }
  },
  components: {
    
    

  },
};
</script>

<style scoped>
</style>

猜你喜欢

转载自blog.csdn.net/qq_41880073/article/details/123323351
今日推荐