Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一个高度可定制的vue modal插件 #10

Open
shaodahong opened this issue Jul 28, 2017 · 5 comments
Open

一个高度可定制的vue modal插件 #10

shaodahong opened this issue Jul 28, 2017 · 5 comments
Labels

Comments

@shaodahong
Copy link
Owner

shaodahong commented Jul 28, 2017

前言

modal 是前端开发中普遍且高频的组件之一,很多UI框架中都会实现modal 来增强实践中的交互,但是都没有达到我想要的,因为开发管理后台类页面时modal 形式多变,而且会相互嵌套,这样的话对可定制性有很大的要求

项目地址

vuejs-modal
Demo

预期目标

  1. 可以自定义modal,一个vue 组件就是一个modal
  2. 想要调用modal 直接通过this.$modal[modal名]()来调用
  3. this.$modal[modal名]()是个promise,可以根据它的状态来得到modal 上的状态(确定或者取消等)
  4. 可以通过this.$modal[modal名](params)来传参复用modal

实现

vue 提供use 函数来让我们安装插件

vue.use(plugin, options)

plugin 可以是object 也可以是function,如果是object 那么需要提供install 方法,如果是function 那么这个function 就是install,use 还提供了options 参数,options 在install 方法中可以获取到

// vuejs-modal.js
var Modal = {
    /**
     * 
     * 
     * @param {Function} Vue 
     * @param {{name?: string, id?: string, modals: object, style?: object}} options 
     */
    install: function (Vue, options) {
    }
}

install 第一个参数是vue 构造函数,第二个options 就是use 的时候传的options,有了vue 构造函数我们可以做很多事了,我们来是实现下$modal

// vuejs-modal.js
install: function (Vue, options) {
        // 定义一个defaultOptions 来初始默认的属性
        // 可以通过options 来覆盖掉默认的属性
        var defaultOptions = Object.assign({
            name: '$modal', //使用this 调用的插件名,默认是$modal
            id: 'modal', //html 页面上初始化的div id 名,默认是modal
            modals: null, //默认的modals,初始是没有的,需要传参,如果没有会报错
            style: {
                position: 'fixed',
                top: 0,
                left: 0,
                right: 0,
                bottom: 0,
                zIndex: 1000
            }
            // 默认的样式,zIndex 是递增的
        }, options)
    },

核心:

// 声明一个modals 空间
let modals = Vue.prototype[defaultOptions.name] = {};

// 绑定modal
Object.keys(defaultOptions.modals).forEach(v => {

    /**
     * 
     * 
     * @param {object} options 
     * @returns 
     */
    modals[v] = options => {
        return new Promise((resolve, reject) => {
            try {
                new Vue({
                    render: h => h(defaultOptions.modals[v], {
                        // 每个modal提供options参数,参数会传递给props
                        props: options,
                        style: Object.assign(defaultOptions.style, {
                            zIndex: this.zIndex
                        }),
                       // 默认提供两个事件$on 和$cancel,$on 会resolve,$cancel 会reject
                       // $on 需要参数$el 来remove 调modal,$cancel 同理
                        on: {
                            $ok: function ($el, info) {
                                $el.remove()
                                resolve(info)
                            },
                            $cancel: function ($el, info) {
                                $el.remove()
                                reject(info)
                            }
                        }
                    })
                }).$mount('#' + defaultOptions.id)
            } catch (error) {
                console.error('vuejs-modal', error)
            }

        })
    }

})

问题

  1. 本来理想情况下是vue 有没有compile 方法提供,这样直接调用compile 后挂载到body 下面,但是看了文档compile 倒是有但是只在独立构建下有用,over,只好使用new vue()的方式来变相的compile,但是需要建坑
var div = document.createElement('div');
div.setAttribute('id', 'modal');
document.getElementsByTagName('body')[0].appendChild(div)
  1. 关闭modal 这个一直有个疑问,是建议使用者手动关闭还是插件来关闭,目前是插件关闭,但是需要把this.$el传递进来,后来想了想还是插件关闭,这样的话使用者可以少写一行代码,后续可能会有所调整
  2. 这个插件不太适用于modal 少且单一的项目,因为我是开发管理后台类页面,modal 页面不是简单的提示信息,会有些交互等,所以和这个插件很契合
  3. 插件没有很详细的兼容,使用rollup 来打包,并且只引入了promise 和assigin 的Polyfill
  4. 后续升级看业务中的使用情况
@tflower
Copy link

tflower commented Jul 31, 2017

很棒哦

@shaodahong
Copy link
Owner Author

@tflower 谢谢,小东西,没有技术含量的,纯业务驱动

@wangshuai99
Copy link

请问这需要vue什么版本

@shaodahong
Copy link
Owner Author

@wangshuai99 2+

@goodluck2016
Copy link

顶一个,期待更多分享

@shaodahong shaodahong added the vue label Oct 16, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants