iview Modal應用:在列表應用頁彈出新增/編輯數據頁,操作完畢后關閉彈出頁刷新列表頁


在實際應用中,往往需要一個報表列表頁,支持表單數據的添加或修改,操作完畢后關閉子頁並刷新列表頁面,效果如下圖

 

 主頁面關鍵代碼:

1)在主頁面引入待彈出modal頁的組件

    <productEditModal
      :show="{'showModal': showModal, 'productId': productId}"
      @on-close="closeModal"
    ></productEditModal>
<script>
import productEditModal from '@/content/productEdit'// 引入子頁面
export default {
  components: {
    productEditModal
  },
...
</script>

2)在主頁面中定義彈窗和關閉彈出的函數,其中,showModal、productId為定義的變量,將會傳入彈出子頁,分別代表是否彈出頁和傳入到子頁面主鍵值

  methods: {
    // 關閉彈框,賦值父頁面。isRefresh用於標識是否刷新父頁面(子頁面內容有變化時傳入true值)
    closeModal (resVal) {
      console.log('子組件傳來的值:' + resVal)
      this.showModal = resVal.isClose
      if (resVal.isRefresh) {
        this.getList()
      }
    },
    // 彈出頁面
    openModal (index) {
      console.log('序列號:' + index)
      this.showModal = true
      this.productId = 0// 默認新增0
      index > -1 && (this.productId = this.tbData[index].id)
    },
    ...
}

 子頁面關鍵代碼:

1)定義modal頁面內容

<template>
  <Modal
    v-model="showModal"
    title="產品編輯"
    width="800"
    :footer-hide=true
    :closable="false"
  >
  <!--此處放置表單中的控件-->
  </Modal>
</template>

2)子頁面在watch中接收父頁面傳來值並調用子頁數據加載方法

export default {
  // 父組件傳來的值
  props: ['show', 'productId'],
  data () {
    // 這里存放數據
    return {
      showModal: false,
      curProduct: { id: 0, name: '', code: '', remark: '' }// 當前頁面的產品信息
    }
  },
  // 監聽屬性 類似於data概念
  computed: {},
  // 方法集合
  methods: {
    // 關閉子頁面
    onCancel (isRefresh) {
      this.showModal = false
      this.curProduct = { id: 0, name: '', code: '', remark: '' }// 初始化
      this.$emit('on-close', { isclose: true, isRefresh: isRefresh })
    },
    ...
    init(productId){//缺省}
  },
  // 獲取父頁面傳來的值,並根據主鍵id請求數據
  watch: {
    show (validate) {
      console.log(validate)
      if (validate.showModal === true) {
        this.showModal = validate.showModal
        if (validate.productId > 0) {
          this.init(validate.productId)
        } else {
          this.curProduct = { id: 0, name: '', code: '', remark: '' }// 初始化
        }
      }
    }
  }

3)子頁面重寫保存和關閉按鈕,隱藏modal的底部按鈕區(:footer-hide=true),自行控制彈出頁面的開關,請查看子頁完整代碼。

主頁完整代碼如下:

<template>
  <div class="main-content">
    <Row type="flex">
      <i-col
        span="2"
        class="main-lable"
      >
        產品名稱:
      </i-col>
      <i-col span="6">
        <i-input
          placeholder="請輸入產品名稱"
          style="width: 200px"
          v-model="proName"
        ></i-input>
      </i-col>
      <i-col span="8">
        <Button
          type="info"
          icon="ios-search"
          @click="getList"
        >查詢</Button>
        <Button
          icon="ios-add"
          type="success"
          @click="openModal(-1)"
        >新增</Button>
      </i-col>
    </Row>
    <div style="margin-top:10px">
      <Table
        border
        :columns="tbColumns"
        :data="tbData"
      >
        <template
          slot-scope="{ row, index }"
          slot="action"
        >
          <Button
            type="error"
            size="small"
            style="margin-right: 5px"
            @click="deleteRow(index)"
          >刪除</Button>
          <Button
            type="info"
            size="small"
            style="margin-right: 5px"
            @click="openModal(index)"
          >編輯</Button>
        </template>
      </Table>
    </div>
    <div class="main-page">
      <Page
        :total="totals"
        :page-size="pageSize"
        @on-change="change"
        show-elevator
      ></Page>
    </div>
    <productEditModal
      :show="{'showModal': showModal, 'productId': productId}"
      @on-close="closeModal"
    ></productEditModal>
  </div>
</template>

<script>
import productEditModal from '@/content/productEdit'// 數據源列表
export default {
  data () {
    return {
      self: this,
      proName: '', // 產品名稱(過濾項)
      totals: 0, // 數據行數
      pageSize: 10, // 每頁顯示條數
      pageIndex: 1, // 當前頁
      tbColumns:
        [
          {
            title: '編號',
            width: 80,
            key: 'id'
          },
          {
            title: '產品名稱',
            width: 150,
            key: 'name'
          },
          {
            title: '產品代碼',
            width: 100,
            key: 'code'
          },
          {
            title: '產品描述',
            key: 'remark'
          },
          {
            title: '操作',
            slot: 'action',
            width: 200,
            align: 'center'
          }
        ],
      tbData: [],
      showModal: false, // 是否顯示子組件
      productId: 0// 傳給子組件的主鍵id
    }
  },
  components: {
    productEditModal
  },
  methods: {
    // 關閉彈框,賦值父頁面
    closeModal (resVal) {
      console.log('子組件傳來的值:' + resVal)
      this.showModal = resVal.isClose
      if (resVal.isRefresh) {
        this.getList()
      }
    },
    // 彈出頁面
    openModal (index) {
      console.log('序列號:' + index)
      this.showModal = true
      this.productId = 0// 默認新增0
      index > -1 && (this.productId = this.tbData[index].id)
    },
    // 刪除一條數據
    deleteRow (index) {
      var that = this
      let proId = this.tbData[index].id
      if (proId > 0) {
        this.$Modal.confirm({
          title: '提示',
          content: '確認要刪除名稱為[' + this.tbData[index].name + ']的產品嗎?',
          onOk: () => {
            this.$axios
              .delete('/api/v1/product/' + proId)
              .then(response => {
                console.log(response)
                debugger
                if (response.data.isError) {
                  console.log(response)
                  this.$Modal.error({
                    title: '提示',
                    content: '刪除失敗!',
                    onOk: () => {
                      // this.$Message.info('Clicked ok')
                    },
                    onCancel: () => {
                      // this.$Message.info('Clicked cancel')
                    }
                  })
                  // this.$Message.error('新增失敗:' + response.data.message)
                } else {
                  this.$Modal.success({
                    title: '提示',
                    content: '刪除成功!',
                    onOk: () => {
                      // this.$Message.info('Clicked ok')
                      // this.onCancel(true)
                      debugger
                      that.getList()
                    },
                    onCancel: () => {
                      // this.$Message.info('Clicked cancel')
                    }
                  })
                }
              })
              .catch(function (error) { // 請求失敗處理
                console.log(error)
              })
          },
          onCancel: () => {
            this.$Message.info('您已取消刪除.')
          }
        })
      }
    },
    // 加載表格內容(含過濾、分頁)
    getList () {
      // 拼裝請求數據
      let filter = {}
      this.proName && (filter.name = { like: this.proName })
      this.$axios
        .post('/api/v1/product/list', { filter: filter, sort: { id: 'ASC', name: 'DESC' }, page: this.pageIndex, limit: this.pageSize })
        .then(response => {
          console.log(response)
          this.tbData = response.data.data.docs
          this.totals = response.data.data.totals
          // console.log(this.totals)
        })
        .catch(function (error) { // 請求失敗處理
          console.log(error)
        })
    },
    // 分頁改變時
    change (page) {
      // console.log(page)
      this.pageIndex = page
      this.getList()
    }
  },
  // 生命周期 - 掛載完成,template模板掛在到組件上(可以訪問DOM元素)
  mounted () {
    this.getList()
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.main-content {
  height: 100%;
}
.main-lable {
  line-height: 30px;
  text-align: right;
}
.main-page {
  width: 100%;
  position: absolute;
  bottom: 2px;
  text-align: center;
}
</style>
View Code

子頁完整代碼如下:productEdit.vue

<template>
  <Modal
    v-model="showModal"
    title="產品編輯"
    width="800"
    :footer-hide=true
    :closable="false"
  >
    <i-form :label-width="100">
      <div class="ivu-card ivu-card-dis-hover">
        <div
          class="ivu-card-body"
          style="verflow-y:auto;overflow-x: hidden;"
        >
          <div
            class="ivu-row"
            style="margin-left: -12px; margin-right: -12px;"
          >
            <Row type="flex">
              <i-col span="12">
                <Form-item
                  label="產品名稱:"
                  prop="name"
                >
                  <i-input
                    v-model="curProduct.name"
                    placeholder="請輸入產品名稱"
                    style="width:80%"
                  ></i-input>
                </Form-item>
              </i-col>
              <i-col span="12">
                <Form-item
                  label="產品代碼:"
                  prop="code"
                >
                  <i-input
                    v-model="curProduct.code"
                    placeholder="請輸入產品代碼"
                    style="width:80%"
                  ></i-input>
                </Form-item>
              </i-col>
            </Row>
            <Row type="flex">
              <i-col span="24">
                <Form-item label="數據源描述:">
                  <Input
                    type="textarea"
                    :rows="4"
                    placeholder="請輸入數據源描述"
                    v-model="curProduct.remark"
                    style="width:91%"
                  />
                </Form-item>
              </i-col>
            </Row>
            <div style="text-align: right;margin-top: 10px;">
              <!-- <Button @click="onCancel()">取消</Button> -->
              <button
                type="button"
                class="ivu-btn ivu-btn-primary"
                @click="onSave"
              >
                <span>提交</span>
              </button>
              <button
                type="button"
                class="ivu-ml ivu-btn ivu-btn-default"
                @click="onCancel(false)"
              >
                <span>取消</span>
              </button>
            </div>
          </div>
        </div>
      </div>
    </i-form>
  </Modal>
</template>
<script>
// 這里可以導入其他文件(比如:組件,工具js,第三方插件js,json文件,圖片文件等等)
// 例如:import 《組件名稱》 from '《組件路徑》';

export default {
  // 父組件傳來的值
  props: ['show', 'productId'],
  data () {
    // 這里存放數據
    return {
      showModal: false,
      curProduct: { id: 0, name: '', code: '', remark: '' }// 當前頁面的產品信息
    }
  },
  // 監聽屬性 類似於data概念
  computed: {},
  // 方法集合
  methods: {
    // 關閉子頁面
    onCancel (isRefresh) {
      this.showModal = false
      this.curProduct = { id: 0, name: '', code: '', remark: '' }// 初始化
      this.$emit('on-close', { isclose: true, isRefresh: isRefresh })
    },
    // 保存產品信息
    onSave () {
      console.log(this.isNew)
      if (this.curProduct.id > 0) {
        this.$axios
          .put('/api/v1/product', { entity: this.curProduct })
          .then(response => {
            if (response.data.isError) {
              this.$Modal.error({
                title: '提示',
                content: '修改失敗',
                onOk: () => {
                  // this.$Message.info('Clicked ok')
                },
                onCancel: () => {
                  // this.$Message.info('Clicked cancel')
                }
              })
            } else {
              this.$Modal.success({
                title: '提示',
                content: '修改成功!',
                onOk: () => {
                  this.onCancel(true)
                  // this.$Message.info('Clicked ok')
                },
                onCancel: () => {
                  // this.$Message.info('Clicked cancel')
                }
              })
            }
          })
          .catch(function (error) {
            // 請求失敗處理
            console.log(error)
          })
      } else {
        this.$axios
          .post('/api/v1/product', { entity: this.curProduct })
          .then(response => {
            if (response.data.isError) {
              console.log(response)
              this.$Modal.error({
                title: '提示',
                content: '保存失敗',
                onOk: () => {
                  // this.$Message.info('Clicked ok')
                },
                onCancel: () => {
                  // this.$Message.info('Clicked cancel')
                }
              })
              // this.$Message.error('新增失敗:' + response.data.message)
            } else {
              this.$Modal.success({
                title: '提示',
                content: '保存成功!',
                onOk: () => {
                  // this.$Message.info('Clicked ok')
                  this.onCancel(true)
                },
                onCancel: () => {
                  // this.$Message.info('Clicked cancel')
                }
              })
            }
          })
          .catch(function (error) {
            // 請求失敗處理
            console.log(error)
          })
      }
    },
    init: function (proId) { // 初始化頁面內容
      console.log('子頁初始化:' + proId)
      // 編輯時
      if (proId > 0) {
        // 根據proId獲得數據源信息,並加載到頁面上
        this.$axios
          .get('/api/v1/product/' + proId)
          .then(response => {
            // console.log(response);
            (response.data.data) && (this.curProduct = response.data.data)
            console.log(this.curProduct)
          })
          .catch(function (error) { // 請求失敗處理
            console.log(error)
          })
      }
    }
  },
  // 獲取父頁面傳來的值,並根據主鍵id請求數據
  watch: {
    show (validate) {
      console.log(validate)
      if (validate.showModal === true) {
        this.showModal = validate.showModal
        if (validate.productId > 0) {
          this.init(validate.productId)
        } else {
          this.curProduct = { id: 0, name: '', code: '', remark: '' }// 初始化
        }
      }
    }
  }
}
</script>
View Code

 參考鏈接:https://blog.csdn.net/lemisi/article/details/89176251


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM