iview-modal的组件式调用和函数式调用

1,958 阅读1分钟

基础用法

<template>
    <Button type="primary" @click="modal1 = true">Display dialog box</Button>
    <Modal
        v-model="modal1"
        title="Common Modal dialog box title"
        @on-ok="ok"
        @on-cancel="cancel">
        <p>Content of dialog</p>
        <p>Content of dialog</p>
        <p>Content of dialog</p>
    </Modal>
</template>
<script>
    export default {
        data () {
            return {
                modal1: false
            }
        },
        methods: {
            ok () {
                this.$Message.info('Clicked ok');
            },
            cancel () {
                this.$Message.info('Clicked cancel');
            }
        }
    }
</script>

通过v-model绑定value属性来控制modal的出现与消失,点击按钮的时候把modal1赋值为true,弹出modal。点击关闭按钮或者点击modal蒙层的时候会自动吧modal1置为false,从而隐藏modal界面。

vue官方文档有提到,v-model其实是以下简写形式

<input type="text" v-bind:value="dataA" v-on:input="dataA = $event.target.value" />

在iview的源码里可以看到把传入的value作为v-show的值 跳转源码

组件式调用

上面是直接把modal写在当前页面来调用的,为了组织代码,一般会把modal抽出为一个组件,这就要用组件式调用。

创建一个basic-modal组件

<template lang="html">
  <Modal
      v-model="isShow"
      title="title"
      @on-ok="ok"
      @on-cancel="cancel">
      <p>Content of dialog</p>
      <p>Content of dialog</p>
      <p>Content of dialog</p>
  </Modal>
</template>

<script>
export default {
  name: 'basic-modal',
  props: {
    visible: {
      type: Boolean,
      default: () => false
    }
  },
  watch: {
    visible: {
      handler (newval, oldval) {
        this.isShow = newval
      }
    }
  },
  data () {
    return {
      isShow: this.visible
    }
  },
  methods: {
    ok () {
      this.$Message.info('Clicked ok')
      this.$emit('modal-close')
    },
    cancel () {
      this.$emit('modal-close')
      this.$Message.info('Clicked cancel')
    }
  }
}
</script>

<style lang="css" scoped>
</style>

主要注意的也是v-modal这个参数,外部输入一个visible属性,组件监听visible,把最新值赋给isShow,isShow再赋值给组件的v-modal。不能直接把visible属性拿来赋值v-model,因为关闭弹窗的时候,会修改value为false,如果是visible,这就变成双向流动了,会报错。于是组件内部自己维护一个isShow字段,跟随visible的变化而变化。关闭弹窗的时候同时抛出一个'modal-close'的事件,让父组件更新visible属性。

父组件调用modal组件

<template >
  <div class="">
    <Button type="primary" @click="handleModalVisible">Display basic modal</Button>
    <basic-modal :visible="modalVisible" @modal-close="modalClose"></basic-modal>
  </div>
</template>

<script>
import basicModal from './basic-modal.vue'
export default {
  name: 'home',
  components: {
    basicModal
  },
  methods: {
    handleModalVisible () {
      this.modalVisible = true
    },
    modalClose () {
      this.modalVisible = false
    }
  },
  data () {
    return {
      modalVisible: false,
    }
  }

}
</script>
<style lang="css" scoped>
</style>

函数式调用

modal也支持函数式调用,就是在js代码里唤出弹窗,而不是先写在html里然后通过修改visible的方式。iview官网也有用例

this.$Modal.info({
    title: title,
    content: content
});

函数式调用也支持自定义内容,用render函数即可实现,也支持onOk,onCancel回调。更多的参数可以参考源码 点击跳转

      this.$Modal.info({
        showCancel: false,
        title: 'this is title',
        onOk: () => {
          console.log('onok')
        },
        render: h => {
          return h('Input', {
            props: {
              value: this.value,
              autofocus: true,
              placeholder: 'please...'
            },
            on: {
              input: val => {
                this.value = val
              }
            }
          })
        }
      })
    }

vue的函数式调用

现在介绍一种比较基础的vue函数式调用,没有用到ivew,所以界面需要自己调试,但是使用范围更广,是参考别人的实现Vue——函数式调用组件

创建一个loading.vue文件

<template>
  <div class="loading" v-if="isShow">
    <div class="">
      {{info}}
    </div>
  </div>
</template>

<script>
export default {
  name: 'loading',
  data () {
    return {
      info: '正在加载',
      isShow: false
    }
  },
  methods: {
    showLoading (opt) {
      opt = opt || {}
      this.info = opt.info || '正在加载'
      this.isShow = true
      setTimeout(() => {
        this.hideLoading()
      }, opt.during || 2000)
    },

    hideLoading () {
      this.isShow = false
    }
  }
}
</script>
<style lang="css" scoped>
</style>

创建一个loading.js文件

import Vue from 'Vue'
import Loading from './loading.vue'

const v = new Vue({
  render (h) {
    return h(Loading)
  }
})

v.$mount()
document.body.appendChild(v.$el)

const load = v.$children[0]

function showLoading (opt) {
  load.showLoading(opt)
}

export default {
  showLoading
}

然后可以在main.js里把loading为Vue的原型方法

import loading from './path.../loading'
Vue.prototype.$loading = loding

父组件中使用this.$loading.showLoading({info: 'on loading...'})

或者不需要全局注册,只在需要用到的地方引入loading再使用也行。

import loading from './loading'
export default {
	methods: {
    	showLoading () {
          loading.showLoading({info: '加载。。。'})
        },
    }
}