• vue组件,可以通过npm引用的组件


    本文章通过实现一个vue-dialog的弹出层组件,然后附加说明如果发布此包到npm,且能被其他项目使用。

    功能说明

    • 多层弹出时,只有一个背景层。
    • 弹出层嵌入内部组件。
    • 弹出层按钮支持回调
    • 源码下载

    实现

    • 多层弹出时,只有一个背景层
      利用两个组件实现,一个背景层组件(只提供一个背景层,组件名:background.vue),一个弹出层内容管理组件(实现多个内容层的管理,组件名:master.vue)。
    • 弹出层嵌入内部组件
      使用vue的component组件实现,他可以完美支持。
    • 弹出层按钮支持回调
      在master.vue中实现,详细解析此代码
      html代码
    <template>
        <div> 
            <div class="modal-content"  v-for="(comp,index) in comps" v-bind:style="style(index,comp)" >
              <div class="modal-header" >
                header
              </div>
              <div class="modal-body">
                <component :is="comp"></component>
              </div>
              <div class="modal-footer">
                <button type="button" class="btn btn-default" v-on:click="clickHandler(btn.value, comp, index)" v-for="btn in btns" >{{btn.text}}</button>
              </div>
            </div> 
          <hDialogBack ref="back" v-bind:z-index="realIndex-1" ></hDialogBack>
        </div>
    </template>
    • comps:内部组件的集合
    • realIndex:一个computed属性,读取props的mIndex属性,表示内部层的zIndex层级关系。
    • component加载组件
    • btns:表示按钮的集合,现还不支持组件独立配置按钮列表。
    • style:此方法用于生成内部组件居中的css代码。

    js代码:

    <script>
    import hDialogBack from './background'
    
    function getclientPoint () {
      return {
         document.documentElement.clientWidth || document.body.clientWidth,
        height: document.documentElement.clientHeight || document.body.clientHeight
      }
    }
    
    export default {
      name: 'HDialog',
      data () {
        return {
          comps: []
        }
      },
      props: {
        'btns': {
          type: Array,
          default: function () {
            return [{ text: 'ok', value: 'ok'}, { text: 'cancel', value: 'cancel'}]
          }
        },
        'mIndex': {
          type: Number,
          default: 19861016
        }
      },
      computed: {
        realIndex: function () {
          return this.mIndex
        }
      },
      components: {
        hDialogBack
      },
      methods: {
        open: function (comp) {
          comp.promise = new Promise(function (resolve, reject) {
            comp.resolve = resolve
            comp.reject = reject
          })
          comp.width = comp.width || 600
          comp.height = comp.height || 400
          this.comps.push(comp)
          if (!this.$refs.back.show) {
            this.$refs.back.open()
          }
          return comp.promise
        },
        clickHandler: function (type, comp, index) {
          let self = this
          let close = function () {
            self.comps.splice(index, 1)
            if (self.comps.length === 0 && self.$refs.back.show) {
              self.$refs.back.close()
            }
          }
          /** 只提供promise模式 */
          comp.resolve({'type': type, 'close': close})
        },
        style: function (index, comp) {
          let point = getclientPoint()
          return {
            zIndex: this.realIndex + index,
             comp.width + 'px',
            height: comp.height + 'px',
            left: ((point.width - comp.width) / 2) + 'px',
            top: ((point.height - comp.height) / 2) + 'px'
          }
        }
      }
    }
    </script>
    • open方法,用于打开弹出层,且返回一个Promise。
    • 嵌入background.vue组件,用于提供背景层。
    • clickHandler方法:master.vue组件按钮的事件响应函数,会resolve在open方法中提供的promise。

    css代码:

    <style>
    .modal-content {
      position: absolute;
    }
    </style>

    如何实用

    • 首先需要在顶层引入master.vue,然后嵌入到与app组件平级,如下代码:
    new Vue({
      el: '#app',
      template: '<div><App></App><HDialog ref="hDialog" ></HDialog></div>',
      components: { App }
    })

    一定要指定ref值,这是弹出层实现的关键。

    • 在任意一个子组件中如下使用:
    let promise = this.$root.$refs.hDialog.open({
          template: '<div>第二层了</div>'
        })
        promise.then(function (arg) {
          alert('第二层' + arg.type)
          arg.close()
    })
    • 使用$root.$refs找到弹出层管理组件
    • 使用调用其open方法,并接受一个promise类型的返回值
    • 使用promise即可。

    发布到npm

    • 如果组件需要被其他人引用,最好使用commonjs2规范,webapck如下配置:
    output: {
    path: './dist',
    filename: '[name].js',
    library: 'vue-hdialog',
    libraryTarget: 'commonjs2'
    }
    • 在npmjs上注册一个账号
    • 利用npm login 登录
    • 使用npm publish 发布,如果你想卸载可以用npm unpublish --force.
    • 发布是需要package.json检测version和name字段,如果已存,或者是存在被卸载的都不行。
    • package.json中的main节点是指定其他引用时,默认导出的文件。
  • 相关阅读:
    [Leetcode][Python]29: Divide Two Integers
    [Leetcode][Python]28: Implement strStr()
    [Leetcode][Python]27: Remove Element
    前端笔记(百度)
    关于html5新增的功能(百度)
    一些我容易混淆的知识(关于数组的操作、对字符串的操作)
    web前端~~浏览器兼容问题(百度)
    关于前端的性能优化问题
    封装ajax(二)闭包的形式
    封装ajax
  • 原文地址:https://www.cnblogs.com/cqhaibin/p/6488702.html
Copyright © 2020-2023  润新知