还不知道命令式组件?还不了解Vue.extend?看完这篇文章你就懂了

1,086 阅读1分钟

最近在做uni-app的项目,由于项目中有很多地方需要用到modal,loading这种组件。但是uni提供的api又不好看,所以博主只能自己封装了,由于UI组件库使用的是uView,所以就基于uView的modal进行二次封装(uView自带的Modal组件不支持命令式调用,需要在template标签中使用才行,使用比较麻烦)。

先看下uView自带的怎样使用:

<template>
	<view>
                // 还需要使用一次组件,比较麻烦
		<u-modal v-model="show" :content="content"></u-modal>
		<u-button @click="open">
			打开模态框
		</u-button>
	</view>
</template>

<script>
	export default {
		data() {	
			return {
				show: false,
				content: '东临碣石,以观沧海'
			}
		},
		methods: {
			open() {
				this.show = true;
			}
		}
	}
</script>

改良后的用法

<template>
	<button @click="showModal">点击</button>
</template>

<script>
	export default {
		methods: {
			showModal() {
                                // 无需在template中使用,直接在js中调用即可,是不是很方便
				this.$modal('内容', '标题')
					.then(() => {
						uni.showToast({
							title: '点击确定了'
						})
					}).catch(() => {
						uni.showToast({
							title: '点击取消了'
						})
					})
			}
		}
	}
</script>

是不是很好奇是怎样封装的,别急,我们慢慢看来

  1. 首先在components目录下新建Modal目录,并在该目录下新建Modal.jsModal.vue文件

image.png

  1. Modal.vue内容
<template>
	<u-modal v-model="show" :content="content" :title="title" show-cancel-button @confirm="confirm" @cancel="cancel" />
</template>
  1. Modal.js内容
import Vue from 'vue';
import Modal from './Modal.vue'

const ModalConstructor = Vue.extend(Modal)

function showModal({ title, content }) {
	return new Promise((resolve, reject) => {
		const modalDOM = new ModalConstructor({
			data() {
				return {
					show: true,
					title,
					content
				}
			},

			methods: {
				confirm() {
					resolve()
				},

				cancel() {
					reject()
				}
			}
		})
		
		document.body.appendChild(modalDOM.$mount().$el)
	})
}

export default function modalRegister () {
	Vue.prototype.$modal = showModal
}

最后我们来看效果

chrome-capture.gif

其实这边只是简单的封装下,方便大多数人理解,因为只要理解这种命令式组件封装原理,就可以根据自己的业务需求进行扩展,比如增加props,methods。另外,封装loading组件就不展开了,因为那个比这个更简单,相信大家已经可以举一反三了。