100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > vue3 手动封装message消息组件(提示框:参考element-ui)

vue3 手动封装message消息组件(提示框:参考element-ui)

时间:2020-11-05 13:08:52

相关推荐

vue3 手动封装message消息组件(提示框:参考element-ui)

vue3 手动封装message消息组件

使用场景封装组件message.vueindex.js 调用方式按需/局部调用全局调用 番外推荐参考文章

使用场景

如图所示消息提示框组件的使用场景很清楚:

一般用于登录提示或者一些表单提交(网络请求)的状态提示

参考链接: element-ui_Message 消息提示.

封装组件

目录的话 需要对应vue文件和js同级即可,如图所示(我的项目里面命名为tip)

message.vue

<template><div class="pop-message" :style="style[type]" v-show="visible"><i class="icon" :class="[style[type].icon]"></i><span class="text">{{str }}</span></div></template><script>import {onMounted, ref } from "vue";export default {name: "popmessage",//这个是传值方法,通过父级组件传入提示状态以及提示文本//可以根据不同业务自定义更多的状态props: {type: {type: String,//success 成功//warn 警告//error 错误default: "success",},str: {type: String,default: "登陆成功",},},setup() {//定义一个对象,包含三种情况的样式,对象key就是类型字符串//icon图标这一部分省略了,有需要的可以自己加入const style = {warn: {// icon: "icon-warning",color: "#E6A23C",backgroundColor: "rgb(253, 246, 236)",borderColor: "rgb(250, 236, 216)",},error: {// icon: "icon-shanchu",color: "#F56C6C",backgroundColor: "rgb(254, 240, 240)",borderColor: "rgb(253, 226, 226)",},success: {// icon: "icon-queren2",color: "#67C23A",backgroundColor: "rgb(240, 249, 235)",borderColor: "rgb(225, 243, 216)",},};const visible = ref(false);onMounted(() => {visible.value = true;});return {style, visible };},};</script><style scoped lang="less">//css样式部分可以根据需求自定义.pop-message {position: absolute;z-index: 9999;left: 50%;margin-left: -150px;top: 50px;display: flex;justify-content: center;align-items: center;width: 300px;height: 50px;border: 1px solid #e4e4e4;background: #f5f5f5;color: #999;border-radius: 4px;//以下是过渡动画,如不需要可删去亦可改进animation: move 0.38s linear forwards;@keyframes move {0% {transform: translate3d(0, -75px, 0);opacity: 0.16;}50% {opacity: 0.68;}100% {transform: none;opacity: 1;}}}</style>

index.js

//引入创建虚拟节点和渲染方法import {createVNode, render } from "vue";import tip from "./tip.vue";//定义一个div容器const div = document.createElement("div");//将定义的容器添加到dom上document.body.appendChild(div);//定义定时器:一定时间后清除let timer = null;export default ({str, type }) => {//调用创建虚拟节点方法//第一个参数为要创建的虚拟节点即编写好的vue组件//第二个参数为props的参数const vnode = createVNode(tip, {str, type });//调用渲染方法:将虚拟节点渲染到dom中render(vnode, div);//开启定时器,若原先存在则先进行清除timer&&clearTimeout(timer);timer = setTimeout(() => {render(null, div);}, 2000);};

调用方式

按需/局部调用

<script>import {onMounted } from "vue";//在需要用到该组件的页面中引入import popmessage from "./components/tip/index.js";export default {setup(props, context) {onMounted(() => {// 直接调用方法名即可//参数type对于组件中设置好的不同状态//参数str对应消息提示文本popmessage({type: "warn", str: "我是提示框" })});return {};},};</script>

全局调用

vue3与vue2不同,原先的vue.prototypeAPI已经被弃用,

取而代之的是app.config.globalPropertiesAPI

在全局目录main.js中进行全局定义,然后在组件中引入即可

(其实写到这里,我突然想起来尤大更新的v3版本旨在简化全局定义实际却没有调用到的组件,精简项目大小,对所需组件进行按需引入,所以在vue3中进行全局定义组件,显得有点吃饱撑着了。。。。不过写了就写完了吧)

main.js文件

import {createApp } from 'vue'import App from './App.vue'import router from "./router/index"//main.js中引入所需组件import popmessage from "./components/tip/index.js";const app = createApp(App);app.use(router);app.mount("#app");//全局注册组件app.config.globalProperties.$popmessage = popmessage

在任意组件中,这里将会使用到getCurrentInstanceAPI获取当前组件实例,相当于vue2中的this

另外这个API有些坑,还好我的项目还没有打包上线,这个API直接调用所获取的对象仅适用于生产环境,打包之后不可用,根据以下参考内容,也对应进行改进了打包上线可用的版本,具体如下代码。

参考链接: Vue3中关于getCurrentInstance的大坑!.

任意组件 xx.vue

<script>import {getCurrentInstance, onMounted } from "vue";export default {setup(props, content) {// 注册全局对象,调用全局组件popmessage、const {proxy} = getCurrentInstance();// 仅适用于生产环境,打包后不可用const instance = getCurrentInstance();onMounted(()=>{//可用于打包后状态proxy.$popmessage({type: "success", str: "登录成功" });//仅适用于生产环境instance.proxy.$popmessage({type: "success", str: "登录成功" });})return {};},};</script>

番外

既然都用到vue3了,按需引入的思想早已深入人心,之所以想记录下这个小组件,大多是因为番外的内容。既然vue3的全局调用如此麻烦,远不如局部按需调用,而且又是将组件封装成一个方法(函数)进行调用,到此我想到父子组件传值进行全局定义,这时候provide/inject这个API就把getCurrentInstance甩了几条街了,话不多说直接看代码。

(以下代码全为个人想法,若有不对或者什么不好的欢迎指出,小弟也是在学习的过程。)

既然是全局调用provide就应该在项目底层的App.vue文件中

<script>import {onMounted, provide } from "vue";import popmessage from "./components/tip/index.js";export default {name: "App",setup(props, context) {onMounted(() => {// 包装全局组件为方法,调用方法即可provide("popmessage", popmessage);});return {};},};</script>

任意组件 xx.vue

<script>import {onMounted, inject } from "vue";export default {name: "App",setup(props, context) {onMounted(() => {const popmessage = inject("popmessage");popmessage({type: "success", str: "登录成功" })});return {};},};</script>

推荐参考文章

链接: Vue项目中原生写消息提示组件.

链接: vue3.0 message消息提示组件.

链接: vue3.0手动封装消息提示框.

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。