最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue實(shí)現(xiàn)Dialog封裝

 更新時(shí)間:2021年07月11日 09:00:55   作者:TMaize  
在寫(xiě)業(yè)務(wù)的時(shí)候很常見(jiàn)的一個(gè)場(chǎng)景就是需要在不同的頁(yè)面調(diào)用同一個(gè)表單,常用的交互就是把表單以彈窗的形式展示,本文主要介紹了Vue實(shí)現(xiàn)Dialog封裝,感興趣的可以了解一下

在寫(xiě)業(yè)務(wù)的時(shí)候很常見(jiàn)的一個(gè)場(chǎng)景就是需要在不同的頁(yè)面調(diào)用同一個(gè)表單,常用的交互就是把表單以彈窗的形式展示,但是在每個(gè)頁(yè)面又重復(fù)的引入表單組件有時(shí)候又很麻煩

解決方案有兩個(gè):

  1. 在根組件里面引入動(dòng)態(tài)組件,在業(yè)務(wù)里面通過(guò)this.$root.openDialog(name, props)去控制動(dòng)態(tài)組件的展示形式
  2. 封裝成插件的形式去調(diào)用,比如this.$dialog('EditDialog.vue', props)

當(dāng)然了,業(yè)務(wù) Dialog 組件要有一套規(guī)范,props 接收一個(gè) onOk、onCancel 回調(diào),data 里面定義一個(gè) visible 屬性

<template>
  <el-dialog :title="title" :visible.sync="visible" append-to-body>
    <!-- 業(yè)務(wù)代碼 -->
  </el-dialog>
</template>

<script>
export default {
  props: ['onOk', '其他業(yè)務(wù)需要的屬性'],
  data() {
    return {
      visible: false
    }
  }
}
</script>

Vue2 寫(xiě)法

在 Vue2 里面我個(gè)人感覺(jué)寫(xiě)成插件是比較好用的,實(shí)現(xiàn)如下,使用混入做了一些操作,和業(yè)務(wù)進(jìn)行解耦

有點(diǎn)不太好的地方是組件是動(dòng)態(tài)插入的,Vue devtools 要刷新下才能看到組件

const mixin = {
  mounted() {
    document.body.appendChild(this.$el)
    this.visible = true
  },
  watch: {
    visible(value) {
      // 動(dòng)畫(huà)結(jié)束后銷(xiāo)毀實(shí)例
      if (value === false) {
        setTimeout(() => {
          this.$destroy()
          if (this.$el && this.$el.parentNode) {
            this.$el.parentNode.removeChild(this.$el)
          }
        }, 400)
      }
    }
  }
}

export default {
  install(Vue, options) {
    Vue.prototype.$dialog = (name, props) => {
      // 相對(duì)于該插件的位置,靜態(tài)編譯期間會(huì)檢查的
      import('../components/dialogs/' + name)
        .then(module => {
          const component = module.default
          const mixins = component.mixins || []
          mixins.push(mixin) // 實(shí)現(xiàn)自動(dòng)打開(kāi),動(dòng)態(tài)了混入生命周期函數(shù)和銷(xiāo)毀操作
          component.mixins = mixins
          return Vue.extend(component)
        })
        .then(Dialog => {
          const dialog = new Dialog({
            propsData: props || {}
          })
          dialog.$mount()
        })
    }
  }
}

調(diào)用方式如下,注意 onOk 回調(diào)的 this 指向,使用箭頭函數(shù)直接就避免了 😎

this.$dialog('GroupEdit.vue', {
  type: 'edit',
  group: {},
  onOk: () => {
    this.freshList()
  }
})

Vue3 插件版寫(xiě)法

很糟糕的是,由于 Vue3 的升級(jí)Vue.extend沒(méi)有了,$mount也沒(méi)有了,組件只能在應(yīng)用里面去渲染

每個(gè)應(yīng)用之間的數(shù)據(jù)是隔離的,所以插件什么的都要重新引入。同時(shí)如果要交互交互的話(huà)也比較麻煩,引入同一個(gè) vuex 實(shí)例應(yīng)該可以,但是沒(méi)怎試

為了低耦合只能去新建一個(gè)應(yīng)用去掛載渲染

import { createApp, defineComponent } from 'vue'
import ElementPlus from 'element-plus'

const mixin = {
  mounted() {
    document.body.appendChild(this.$el)
    this.visible = true
  },
  watch: {
    visible(value) {
      // 動(dòng)畫(huà)結(jié)束后銷(xiāo)毀實(shí)例
      if (value === false) {
        setTimeout(() => {
          this.$.appContext.app.unmount()
        }, 400)
      }
    }
  }
}

export default {
  install(app) {
    app.config.globalProperties.$dialog = (name, props) => {
      import('../components/dialogs/' + name)
        .then(module => {
          const component = module.default
          let mixins = component.mixins || []
          mixins.push(mixin)
          component.mixins = mixins

          return defineComponent(component)
        })
        .then(Dialog => {
          const app = createApp(Dialog, props || {})
          app.use(ElementPlus)
          app.mount(document.createElement('div'))
        })
    }
  }
}

Vue3 動(dòng)態(tài)組件寫(xiě)法

在 Vue3 里面,插件版的寫(xiě)法同樣達(dá)到了要求,但是完全是一個(gè)新引應(yīng)用了,如果在業(yè)務(wù)里訪問(wèn)this.$root,vuex,router還是有點(diǎn)麻煩的

所以 Vue3 里面還是動(dòng)態(tài)組件的寫(xiě)法比較好

在根組件引入動(dòng)態(tài) component,定義一些控制變量

<template>
  <router-view></router-view>
  <component :is="currentDialog" v-bind="currentDialogProps" />
</template>

<script>
export default {
  data() {
    return {
      currentDialog: null,
      currentDialogProps: null
    }
  }
}
</script>

調(diào)用的的話(huà)this.$root.$dialog(),看起來(lái)太難看,其實(shí)還是可以手動(dòng)模擬插件的效果的

const app = createApp(App)
const vm = app.mount('#app')

initDialog(app, vm)

function initDialog(app, vm) {
  const mixin = {
    mounted() {
      this.visible = true
    },
    watch: {
      visible(value) {
        // 動(dòng)畫(huà)結(jié)束后銷(xiāo)毀實(shí)例
        if (value === false) {
          setTimeout(() => {
            this.$root.currentDialog = null
            this.$root.currentDialogProps = {}
          }, 400)
        }
      }
    }
  }

  app.config.globalProperties.$dialog = (name, props) => {
    import('./components/dialogs/' + name).then(module => {
      const component = module.default
      let mixins = component.mixins || []
      mixins.push(mixin)
      component.mixins = mixins
      // 不需要 defineComponent(component)
      vm.currentDialog = markRaw(component)
      vm.currentDialogProps = markRaw(props || {})
    })
  }
}

一些比較 hack 的寫(xiě)法

vue3 組件實(shí)例獲取應(yīng)用實(shí)例

vm.$.appContext.app == app

vue3 應(yīng)用實(shí)例獲取組件實(shí)例,注意_instance 僅在 dev 環(huán)境能訪問(wèn)到

app._instance.proxy == vm
app._instance.root.proxy == vm
app._instance.ctx.$root == vm

騷操作還是有的,但是最好不要用

const app = createApp(App)
const vm = app.mount('#app')

if (process.env.NODE_ENV === 'production') {
  app._instance = {
    proxy: vm,
    root: {
      proxy: vm
    },
    ctx: {
      $root: vm
    }
  }
}

到此這篇關(guān)于Vue實(shí)現(xiàn)Dialog封裝的文章就介紹到這了,更多相關(guān)Vue Dialog封裝內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • IE9 elementUI文件上傳的問(wèn)題解決

    IE9 elementUI文件上傳的問(wèn)題解決

    這篇文章主要介紹了IE9 elementUI文件上傳的問(wèn)題解決,有需要了解IE9 elementUI文件上傳的朋友可參考。希望此文章對(duì)各位有所幫助
    2018-10-10
  • vue3中storeToRefs讓store中的結(jié)構(gòu)出來(lái)的數(shù)據(jù)也能變成響應(yīng)式(推薦)

    vue3中storeToRefs讓store中的結(jié)構(gòu)出來(lái)的數(shù)據(jù)也能變成響應(yīng)式(推薦)

    這篇文章主要介紹了vue3中storeToRefs讓store中的結(jié)構(gòu)出來(lái)的數(shù)據(jù)也能變成響應(yīng)式,本文通過(guò)實(shí)例代碼給大家介紹的分需要的朋友可以參考下
    2024-09-09
  • vue項(xiàng)目中使用fetch的實(shí)現(xiàn)方法

    vue項(xiàng)目中使用fetch的實(shí)現(xiàn)方法

    這篇文章主要介紹了vue項(xiàng)目中使用fetch的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Vue項(xiàng)目報(bào)錯(cuò):Uncaught?SyntaxError:?Unexpected?token?'<'的解決方法

    Vue項(xiàng)目報(bào)錯(cuò):Uncaught?SyntaxError:?Unexpected?token?'<&a

    最近在做vue項(xiàng)目時(shí),需要引入一個(gè)第三方的js文件,在index.html中通過(guò)以下方式引入JS文件編譯后就報(bào)了這個(gè)問(wèn)題,這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目報(bào)錯(cuò):Uncaught?SyntaxError:?Unexpected?token?'<'的解決方法,需要的朋友可以參考下
    2022-08-08
  • Vue3?源碼解讀靜態(tài)提升詳解

    Vue3?源碼解讀靜態(tài)提升詳解

    這篇文章主要為大家介紹了Vue3源碼解讀靜態(tài)提升示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • vue中keep-alive多級(jí)路由緩存問(wèn)題

    vue中keep-alive多級(jí)路由緩存問(wèn)題

    本文主要介紹了vue中keep-alive多級(jí)路由緩存問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • 基于VUE實(shí)現(xiàn)的九宮格抽獎(jiǎng)功能

    基于VUE實(shí)現(xiàn)的九宮格抽獎(jiǎng)功能

    這篇文章主要介紹了基于VUE實(shí)現(xiàn)的九宮格抽獎(jiǎng)功能,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-09-09
  • ElementUI中利用table表格自定義表頭Tooltip文字提示

    ElementUI中利用table表格自定義表頭Tooltip文字提示

    這篇文章主要介紹了ElementUI中利用table表格自定義表頭Tooltip文字提示,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • uniapp開(kāi)發(fā)打包多端應(yīng)用完整方法指南

    uniapp開(kāi)發(fā)打包多端應(yīng)用完整方法指南

    這篇文章主要介紹了uniapp開(kāi)發(fā)打包多端應(yīng)用完整流程指南,包括了uniapp打包小程序,uniapp打包安卓apk,uniapp打包IOS應(yīng)用,需要的朋友可以參考下
    2022-12-12
  • 詳解Vue + Vuex 如何使用 vm.$nextTick

    詳解Vue + Vuex 如何使用 vm.$nextTick

    這篇文章主要介紹了詳解Vue + Vuex 如何使用 vm.$nextTick,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11

最新評(píng)論

广丰县| 成武县| 海安县| 墨脱县| 五常市| 辛集市| 扎兰屯市| 蕲春县| 陆川县| 武功县| 合阳县| 井研县| 榕江县| 鲁山县| 南皮县| 浮山县| 长岛县| 宿迁市| 高青县| 怀仁县| 宣汉县| 会昌县| 阿克| 阜平县| 南丹县| 台南县| 博湖县| 花莲县| 响水县| 雅江县| 宁波市| 苍梧县| 凯里市| 肥东县| 周至县| 报价| 阿坝县| 久治县| 安义县| 丽江市| 错那县|