1. 程式人生 > >element--Diaolog彈窗開啟之後渲染元件

element--Diaolog彈窗開啟之後渲染元件

描述:父子兩個元件,父元件開啟子元件彈窗,然後執行方法請求介面,獲取資料之後渲染頁面,且每次點選都執行該方法。

遇到的問題:

最開始簡單地將方法放在子元件mounted裡面,只有第一次開啟彈窗會執行方法。

瞭解到,彈窗只建立了一次。所以,在想是不是可以用keep-alive模式下的actived,然而並沒有什麼用。actived和deactived只在keep-alive使用時生效。

然後想到在開啟彈窗時候,強行呼叫子元件的方法

// initForm: 子元件方法
// this.dialog.data.id: 子元件的請求介面的引數
this.$refs.dialog.initForm(this.dialog.data.id)

這次算是ok了,但是僅僅這樣還不夠。多次請求介面發現,如果介面請求速度夠快,方法會提前執行,渲染元件。

這本來不是什麼壞事,壞就壞在渲染階段。如果資料先一步到位,然後開始渲染元件,這時候彈窗還沒有建立虛擬dom,會有bug。例如:我的彈窗如果是一個echart的圖表,需要繫結一個dom節點進行渲染。節點都沒有渲染出來,就會報錯。

所以,第一次使用時候採用的方案:

直接在呼叫子元件方法的外面包了一個setTimeout,讓彈窗飛一會,然後再渲染。

後面回過頭看了一下,其實不用這麼麻煩,element中彈窗元件有個回撥函式

選擇opened

<el-button @click="edit(id)">修改</el-button>
<el-button @click="add">新增</el-button>
<el-dialog
  :title="dialog.title"
  :visible.sync="dialog.visible"
  :width="dialog.width"
  center
  @opened="initForm"> <!-- element自帶的彈窗打開回調函式 -->
  <component :is="dialog.name" ref="dialog"></component><!-- 動態元件:子元件 -->
</el-dialog>

<script>
import { Add, Edit } from './Dialog'
export default {
  components: {
    Add,
    Edit
  },
  data () {
    return {
      dialog: { // 彈窗元件傳遞資料
        title: '',
        visible: false,
        width: '',
        name: '' // 元件名
      }
    }
  },
  methods: {
    // 新增連結配置資訊
    add () {
      this.dialog = {
        visible: true,
        title: '新增連線配置資訊',
        width: '1000px',
        name: 'add-config'
      }
    },
    // 編輯修改裝置資訊
    edit (id) {
      this.dialog = {
        visible: true,
        title: '修改連線配置資訊',
        width: '1000px',
        name: 'edit-config',
        data: id
      }
    },
    // 彈窗打開回調(更新資料)
    initForm () {
      switch (this.dialog.name) {
        case 'add':
          this.$refs.dialog.initForm()
          break
        case 'edit':
          this.$refs.dialog.initForm(this.dialog.data.id)
          break
        default:
          break
      }
    }
  }
}
</script>