element ui dialog和drawer jsx 封装函数式调用
VNode和组件定义对象的区别
- VNode比较轻量
- 返回的是渲染结果,不是组件定义
- 可以直接插入模板中使用
- 没有创建新组件,无额外实例开销
- 不能拥有自己的状态或生命周期
- 适合简单内容渲染
- 组件定义对象
- 创建了一个全新的 Vue 组件
- 有自己的组件生命周期和状态管理
- 会产生额外的组件实例开销
- 适合需要封装独立逻辑的场景
封装 el-dialog
jsx
import Vue, {defineComponent, ref} from 'vue';
/**
*
* @param options
* @param {Function | Object} options.content -- 渲染函数 或者 组件定义对象
* @param {Object} [options.props] -- dialog属性配置
* @param {Object} [options.slots] -- dialog插槽配置
* @param {Object} [options.on] -- dialog事件配置
* @param {Boolean} [options.drag] -- dialog拖拽 默认true
* @returns {Object} - instance返回dialog实例
* @property {Function} destroy - 销毁dialog实例
*/
function create(options) {
const {
content: Content,
props = {},
slots,
on = {},
drag = true,
} = options;
const visible = ref(false);
const closed = on['closed']
on['update:visible'] = val => visible.value = val
on['closed'] = () => {
closed?.();
clearDom()
}
const directives = []
if (drag) {
directives.push({
name: 'dialogDrag',
value: true,
})
}
const contentRef = ref(null)
const Profile = Vue.extend(defineComponent({
setup() {
return () => <el-dialog
{...{on, directives}}
scopedSlots={slots}
props={{
width: '500px',
visible: visible.value,
'append-to-body': true,
'destroy-on-close': true,
...props
}}>
{
typeof Content === 'function'
? Content()
: <Content ref={el => contentRef.value = el}/>
}
</el-dialog>
}
}))
const instance = new Profile();
instance.$mount();
document.body.appendChild(instance.$el);
visible.value = true;
function clearDom() {
instance.$destroy();
instance.$el.remove()
}
function destroy() {
visible.value = false
}
function getContentRef() {
if (typeof Content === 'function') {
return
}
return contentRef
}
instance.destroy = destroy
instance.getContentRef = getContentRef
return instance
}
export default {
create
}封装el-drawer
jsx
import Vue, {defineComponent, onMounted, ref} from 'vue';
/**
*
* @param options
* @param {Object} [options.props] -- drawer属性配置
* @param {Object} [options.slots] -- drawer插槽配置
* @param {Object} [options.on] -- drawer事件配置
* @param {Function | Object} options.content -- VNode 或者 组件定义对象
*
* @returns {Object} - instance返回el-drawer实例
* @property {Function} destroy - 销毁drawer实例
*/
function create(options) {
const {
content: Content,
props = {},
slots,
on = {}
} = options
const visible = ref(false);
const drawerRef = ref(null);
const contentRef = ref(null)
const Profile = Vue.extend(defineComponent({
setup() {
const closed = on['closed']
on['update:visible'] = val => visible.value = val
on['closed'] = () => {
closed?.();
clearDom()
}
return () => <el-drawer
ref={el => drawerRef.value = el}
{...{on}}
scopedSlots={slots}
props={{
modal: false,
direction: 'rtl',
size: '75%',
visible: visible.value,
withHeader: false,
'append-to-body': true,
'destroy-on-close': true,
...props
}}>
{
typeof Content === 'function'
? Content()
: <Content ref={el => contentRef.value = el}/>
}
</el-drawer>
}
}))
const instance = new Profile();
instance.$mount();
document.body.appendChild(instance.$el);
visible.value = true
function clearDom() {
instance.$destroy();
instance.$el.remove()
}
function destroy() {
drawerRef.value.closeDrawer()
}
function getRef() {
return drawerRef.value
}
function getContentRef() {
if (typeof Content === 'function') {
return
}
return contentRef
}
instance.destroy = destroy
instance.getRef = getRef
instance.getContentRef = getContentRef
return instance
}
export default {create}用例
VNode用例
js
dialog.create({
content: () => <div>hello</div>
})组件定义对象用例
js
dialog.create({
// 也可引入.vue文件等 -- Vue组件都行
content: defineComponent({
setup() {
return () => <div>hello</div>
}
})
})