vue以API的方式加载组件

本文介绍了Vue 3.0中如何通过API方式导入并使用自定义消息提示组件,对比了2.x与3.x的组件实例差异,并讨论了组件挂载的不同策略,包括静态和动态挂载的影响。同时,文中还分享了遇到的问题及解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

大部分组件的使用,基本都是通过import方式导入,这也是最常用的。但是有些时候也需要通过API方法的形式调用。比较常见的比如element ui 的Message 消息提示。这里主要介绍3.x版本的写法,2.x版本可以看我的另一篇文章,简单写了个例子以及自己的理解。

Vue.extend、message消息提示

API方式加载组件

参考文章:
vue 3.0 封装一个message提示组件
极简系列—vue3.x消息组件message

全局API与vue2.x变化

变更前变更后
Vue.extend(组件选项)Vue.createApp(组件选项)
Vue.prototypeconfig.globalProperties,如const app = createApp({}) app.config.globalProperties.$http = () => {}

写一个最简单的消息提示

消息组件:api.vue

<template>
  <div class="message" v-show="showMessage">
    <div class="content">{{ message }}</div>
  </div>
</template>

<script>
import { defineComponent, onMounted, ref, watch } from "vue";
export default defineComponent({
  props: {
    messageType: {
      type: String,
      default: "",
    },
    title: {
      type: String,
      default: "",
    },
  },
  setup(props) {
    const showMessage = ref(false);
    const message = ref("");

    onMounted(() => {
      message.value = props.title;
    });

    watch(message, (val) => {
      showMessage.value = true;
      setTimeout(() => {
        showMessage.value = false;
      }, 2000);
    });

    return {
      showMessage,
      message
    };
  },
});
</script>

<style scoped lang="scss">
.message {
  min-width: 200px;
  max-width: 300px;
  min-height: 50px;
  height: auto;
  background: #ecf5ff;
  border-radius: 10px;
  line-height: 30px;
  color: #409eff;
  font-size: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  top: -800px;
  left: calc(50% - 100px);
}
</style>

出口文件:api.js

  • 利用渲染函数h即createVNode,将message.vue组件编译成vnode
  • 利用mount将vnode挂载到指定元素上
  • 通过$el获取真实DOM
import { createApp, h } from "vue";

//导入消息组件
import MessageComponent from "./api.vue";

//处理数据
function handleData(messageType, title) {
  //创建挂载容器
  const div = document.createElement("div");
  //创建实例
  const app = createApp({
    render() {
      return h(MessageComponent, { messageType, title });
    },
  });

  document.body.appendChild(app.mount(div).$el);
}

export default {
  //普通提示
  info(title) {
    handleData("info", title);
  },
};

使用

<script>
import Message from "./api.js";

import { defineComponent } from "vue";
export default defineComponent({
  setup() {
    const sendMessage = () => {
       Message.info("哈哈哈")
    };
    return {
      sendMessage,
    };
  },
});
</script>

效果图

在这里插入图片描述

问题(坑)

说一下遇到的一些问题,个人理解,如果有不对的地方,感谢指出。

问题1

//继承基础信息
let MessageConstructor = Vue.extend(Main);
//创建实例
let Instance = new MessageConstructor();

2.x的时候可以获取到组件实例,通过组件实例可以获取到组件的props、data、methods

 return h(MessageComponent, { messageType, title });

3.x的时候,你只能通过传递参数的方式进行数据的修改。(h函数的第二个参数是组件的props属性,具体看官方文档)

问题2

//vue 3.0 封装一个message提示组件
<div id="app"></div>
<div id="message"></div>
app.mount('#message');

//极简系列---vue3.x消息组件message
const container = document.createElement("div");
document.body.appendChild(vm.mount(container).$el);

两个文章的挂载方式不同。第一种是直接在index.html里直接写死一个div,然后挂载;第二种是动态生成div,然后挂载。虽然最终都是在body标签里多了一个div,但是推荐使用第二种。第一种消息提示出现后,多了一个滚动条;第二种消息提示出来后,未出现滚动条。两种方式具体有什么不同,个人太笨,不太清楚。

问题3

我自己写的实例

onMounted(() => {
   message.value = props.title;
 });

 watch(message, (val) => {
   showMessage.value = true;
   setTimeout(() => {
     showMessage.value = false;
   }, 2000);
 });

最初想法是直接监听props.title但是没有监听函数没有进入。应该是渲染组件时属性直接赋值了,相当于组件最初就有初始值,属性值没有改变,没有走监听。所以只能再变通一下。

问题4,使用方式

第一种方式时导入js文件

import Message from "./api.js";

第二种方式,注册到全局

//main.js
//消息提示
import message from "../src/views/yc/test/api/api.js";
const app = createApp(App);
app.config.globalProperties.$message = message;

//使用
const { proxy } = getCurrentInstance();
 const sendMessage = () => {
   proxy.$myMessage.info("哈哈哈");
 };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无知的小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值