【vue】Vue3中使用函数调用组件内函数和创建组件

613 阅读2分钟

uniapp+uview vue3+typescript版本,使用函数方式调用和创建组件,并使用组件内的方法

项目场景

今天突然觉得在视图上应用组件,然后在script脚本里操作组件这方式特别的麻烦。因为每次使用组件时都要进行应用,不管你用不用你都要引用,就比如以下图片 在这里插入图片描述 所以我为了偷懒就开始想直接调用函数去创建组件和使用组件内的方法。从而不用每次使用弹出框或者警示框是都要在视图中进行引入。


解决方案:

于是是我开open度娘,网上特别多答案都是需要我使用createApp创建实例,并对组件传入你想要给他的参数,就相当于父传子参数一样。就比如以下这样子: 在这里插入图片描述 项目代码: gitee.com/derekgo/uni…

但是我发现还真的只能创建实例和传参数,不能调用组件内的方法。反正我是在createApp函数里挂载后也找不到组件内的方法使用。于是我想到了vue也有函数式组件h,然后再用render进行渲染,创建虚拟dom,渲染到视图中。于是我这么写了。

toast.ts

import { h, ref, render} from "vue";
import uToast from "@/uni_modules/vk-uview-ui/components/u-toast/u-toast.vue"
import {typeType} from "@/plugins/model/toast/types";

interface propsInterface{
    title:string,
    type?:typeType,
    duration?:number,
    position?:string,
    zIndex?:number,
}
const parentNode = document.createElement('div')
parentNode.setAttribute("id","toast-style")
let optionsInit:propsInterface = {
    title:"",
    type:"default",
    duration:2000,
    position:"center",
    zIndex:999,
}
let options = ref<propsInterface>(optionsInit)

const handleToastRender = () => {
    // 创建 虚拟dom
    const boxVNode = h(uToast, {...options.value})
    // 将虚拟dom渲染到 container dom 上
    render(boxVNode, parentNode)
    // 最后将 container 追加到 body 上
    document.body.appendChild(parentNode)
    return boxVNode;
}

let modalInstance: any

const handleToast = () => {
    const show = (props:propsInterface)=>{
        if (modalInstance) {
            const toastVue = modalInstance.component
            // 调用上述组件中定义的open方法显示弹框
            // 注意不能使用toastVue.ctx来调用组件函数(build打包后ctx会获取不到)
            toastVue.proxy.show(props);
        } else {
            options.value = Object.assign(options.value,props)
            modalInstance = handleToastRender()
            show(options.value)
        }
    }
    const hide = ()=>{
        if (modalInstance) {
            const toastVue = modalInstance.component
            console.log(toastVue.proxy);
            // 调用上述组件中定义的open方法显示弹框
            // 注意不能使用toastVue.ctx来调用组件函数(build打包后ctx会获取不到)
            toastVue.proxy.hide();
        } else {
            modalInstance = handleToastRender()
            hide()
        }
    }
    return {show,hide}
}

export default handleToast

把toast.ts文件的函数挂载到vue的原型链

import {toast} from "./toast"
xxx
export function createApp() {
  const app = createSSRApp(App);
   app.config.globalProperties.$toast = toast()
  return {
    app,
  };
}

项目中使用

...
const {appContext,proxy} = getCurrentInstance() as ComponentInternalInstance

let globalProperties = appContext.config.globalProperties;
g
lobalProperties.$toast.show({title:"222"})

项目代码 gitee.com/derekgo/uni…

在这里插入图片描述

踩坑不易,还希望各位大佬支持一下\textcolor{gray}{踩坑不易,还希望各位大佬支持一下}
📃 个人主页:\textcolor{green}{个人主页:} 沉默小管
📃 个人网站:\textcolor{green}{个人网站:} 沉默小管
📃 个人导航网站:\textcolor{green}{个人导航网站:} 沉默小管导航网
📃 我的开源项目:\textcolor{green}{我的开源项目:} vueCms.cn
🔥 技术交流QQ群:837051545\textcolor{green}{技术交流QQ群:837051545}
👍 点赞,你的认可是我创作的动力!\textcolor{green}{点赞,你的认可是我创作的动力!}
⭐️ 收藏,你的青睐是我努力的方向!\textcolor{green}{收藏,你的青睐是我努力的方向!}
✏️ 评论,你的意见是我进步的财富!\textcolor{green}{评论,你的意见是我进步的财富!}
如果有不懂可以留言,我看到了应该会回复 如有错误,请多多指教