初学vue3的时候倒是扒了一点点源码,似是而非,而且一直做的工作都是很简单的功能,怎么说呢,ui框架也几乎让我很容易的就可以写出一个成型的页面,有时就忘了初学的时候的一些心得。
本内容只说createVNode函数的用法,不做源码探究
1.简单使用-创建一个组件
<template><RenderTest></RenderTest></template>
<script setup>import{ defineComponent, createVNode }from"vue";const RenderTest =defineComponent({render(){// 参数1:元素名字符串; 参数2:元素属性; 元素子节点,支持createVNode嵌套returncreateVNode("div",{class:"text"},"render-text")}});</script>
效果图:
2.简单使用-渲染组件
虽然在日常中这么写特别鸡肋,甚至有些傻逼,但是别急,慢慢来。
先写一个简单要引用的子组件
<template><div>{{title}}</div></template><scriptsetuplang="ts"name="SimpleTemplate">import{defineProps}from"vue";
defineProps<{title: string}>();</script>
父组件
<template><SimpleTemplateCopy/></template><scriptsetup>import{ defineComponent, createVNode }from"vue";import SimpleTemplate from"./SimpleTemplate/index.vue";const SimpleTemplateCopy =defineComponent({render(){returncreateVNode(SimpleTemplate,{title:"twoB"})}})</script>
3.日常使用-我用到它们的地方
element-plus说实话很不错,但是太常使用它有些审美疲劳,但是它的一些组件确实很好用,特别是那些提示弹窗之类,发现了吗,它们都是在函数去调用的,那么如何在纯js中去使用一个已经封装好了的组件呢?反正我是用它们。
简单的实现一下吧。
手写先写一个confirm的组件
<template><divclass="small-window"><divclass="upper-tip"><span>{{ title }}</span></div><divclass="message-content">
{{ message }}
</div><divclass="button-area"><divclass="my-button"style="background-color: #11a9ea"@click="submitCallBack">{{ submitText }}</div><divclass="my-button"style="background-color: #cecece"@click="cancelCallBack">{{ cancelText }}</div></div></div></template><scriptsetuplang="ts"name="Confirm">import{defineProps}from"vue";
defineProps<{title:{type: string,default:"提示"},message: string,submitText: string,cancelText: string,cancelCallBack:()=>void,submitCallBack:()=>void,}>()</script><stylescopedlang="less">.small-window{width: 500px;height: 350px;background-color: white;border: 1px solid rgba(169, 169, 169, 0.92);border-radius: 15px;display: flex;flex-direction: column;.upper-tip{font-size: 18px;height: 45px;width: 100%;font-weight: 700;}.message-content{width:calc(100% - 40px);padding: 15px 20px 15px 20px;height: 150px;text-indent: 32px;display: flex;justify-content: center;font-size: 16px;}.button-area{display: flex;justify-content: end;width:calc(100% - 40px);padding: 15px 20px 15px 20px;.my-button{width: 68px;margin-left: 20px;height: 50px;cursor: pointer;}}}</style>
然后给这个组件找个挂载点以及render到dom上
import{createVNode, render}from"vue";import Confirm from"./Confirm.vue";exportdefault({title, message, submitText, cancelText})=>{const mask = document.createElement('div');
mask.setAttribute('style','position: fixed; background-color: rgba(0, 0, 0, 0.5); width: 100vw; height: 100%; display: flex; justify-content: center; align-items: center');
mask.setAttribute('key', Date.now().toString());
document.body.appendChild(mask);returnnewPromise((reslove, reject)=>{// 封装组件属性方法constsubmitCallBack=()=>{
console.log(456)//调用完毕后应该清空节点render(null, mask)
mask.remove();reslove(true)}// 封装组件属性方法constcancelCallBack=()=>{
console.log(456)//清空节点render(null, mask);
mask.remove();reject()};// 在此处才创建节点并挂载属性const VNode =createVNode(Confirm,{
title,
message,
submitText,
cancelText,
cancelCallBack,
submitCallBack
})render(VNode, mask);});};
然后使用它
<template><button@click="openMyConfirm">12313213</button></template><scriptsetup>import myConfirm from"./Confirm/index.js"constopenMyConfirm=()=>{myConfirm({title:"提示",message:"你好呀",submitText:"你好",cancelText:"我不好"}).then(()=>{
console.log('点击确认事件处理')}).catch(e=>{
console.log('点击取消事件处理')})}</script>
效果图:很丑,但是起码他是个成熟的confirm了
版权归原作者 苏小邪 所有, 如有侵权,请联系我们删除。