当前位置:   article > 正文

今天教大家使用vue2封装一个全局可用的message提示组件_vue 封装消息提示

vue 封装消息提示

像element-ui,ViewDesgin这种组件库我们肯定使用过,当我们用message组件的时候可以直接this.$Message.loadong/success/error,... 那么这个是怎么实现的呢,今天教大家实现一个message组件挂载到vue全局

1、创建一个Message组件,在components目录下新建一个MessageComponent.vue;随便写点什么上去先

 2、在iconfont.cn中找自己需要的图标

下载下来后解压,在assets目录下新建icon文件夹 ,将以下的代码复制到icon文件中:

 记得改一下引入的地址:

在MessageComponent中引入字体图标:

  1. <style scoped>
  2. @import url('../assets/icon/iconfont.css');
  3. </style>

好了,至此字体图标已经完成了。

3、核心逻辑 :

编写 omponents文件夹下的 MessageComponent.js 入口文件,首先定义一个全局变量避免组件多次创建,然后实现 install 方法,因为 Vue.use() 会调用 install ,那自然我们就可以在 intsall 方法参数里获取到 Vue实例了。

我们通过 Vue.extend 创建一个组件构造器,传入之前编写好的组件 MessageComponent.vue ,这样组件构造器就定义好了,使用 new 关键字对组件进行实例化得到一个组件实例 MessageInstanse。

然后将组件实例挂载到DOM,至此插件的核心逻辑就完成了。

  1. import Message from './MessageComponent.vue'
  2. let MessageInstanse = null
  3. const MessagePlugin = {
  4. install(Vue) {
  5. if (!MessageInstanse) {
  6. // Vue.extend() 方法创建了一个名为 MessageComponent 的组件构造器。
  7. const MessageComponent = Vue.extend(Message);
  8. MessageInstanse = new MessageComponent();
  9. // 将通知组件挂载到DOM中
  10. const container = document.createElement("div");
  11. document.body.appendChild(container);
  12. MessageInstanse.$mount(container);
  13. }
  14. }
  15. export default MessagePlugin

4、下面我们在 main.js 中引入插件并使用。

  1. // 全局的插件
  2. import MessagePlugin from './components/MessageComponent'
  3. Vue.use(MessagePlugin)

 启动项目并在浏览器打开,可以看到组件成功挂在到DOM。

5、实现通知方法:

想通过 this.$notify.success() 这样的方式调用,上面可以拿到Vue实例了,给实例原型添加属性;在MessageComponent.js中:添加了四个方法

  1. Vue.prototype.$Message = {
  2. // 加载
  3. loading: (message, duration = 1000 * 60 * 60 * 24) => {
  4. MessageInstanse.showMessage(message, 'loading', duration)
  5. },
  6. // 成功
  7. success: (message, duration) => {
  8. MessageInstanse.showMessage(message, 'success', duration)
  9. },
  10. // 失败
  11. error: (message, duration) => {
  12. MessageInstanse.showMessage(message, 'error', duration)
  13. },
  14. // 警告
  15. warning: (message, duration) => {
  16. MessageInstanse.showMessage(message, 'warning', duration)
  17. },
  18. // 关闭
  19. close: () => {
  20. MessageInstanse.closeMessage()
  21. }
  22. }

上面代码呢,我们给Vue原型添加了$Message 对象,对象中编写了我们需要的通知方法,然后呢我们通过通知组件实例 MessageInstanse去调用他的 showMessage 方法去打开通知,closeMessage 方法关闭通知。

打开通知时,第一个参数是通知内容,第二个就是消息类类型,第三个是延时参数

MessageComponent.js全部代码如下:

  1. import Message from './MessageComponent.vue'
  2. let MessageInstanse = null
  3. const MessagePlugin = {
  4. install(Vue) {
  5. if (!MessageInstanse) {
  6. // Vue.extend() 方法创建了一个名为 MessageComponent 的组件构造器。
  7. const MessageComponent = Vue.extend(Message);
  8. MessageInstanse = new MessageComponent();
  9. // 将通知组件挂载到DOM中
  10. const container = document.createElement("div");
  11. document.body.appendChild(container);
  12. MessageInstanse.$mount(container);
  13. }
  14. Vue.prototype.$Message = {
  15. // 加载
  16. loading: (message, duration = 1000 * 60 * 60 * 24) => {
  17. MessageInstanse.showMessage(message, 'loading', duration)
  18. },
  19. // 成功
  20. success: (message, duration) => {
  21. MessageInstanse.showMessage(message, 'success', duration)
  22. },
  23. // 失败
  24. error: (message, duration) => {
  25. MessageInstanse.showMessage(message, 'error', duration)
  26. },
  27. // 警告
  28. warning: (message, duration) => {
  29. MessageInstanse.showMessage(message, 'warning', duration)
  30. },
  31. // 关闭
  32. close: () => {
  33. MessageInstanse.closeMessage()
  34. }
  35. }
  36. }
  37. }
  38. export default MessagePlugin

6、实现两个方法:

在MessageComponent.vue中,组件实现打开和关闭通知的逻辑,使用 setTimeout 定时器,

通知显示与隐藏,使用translate和transition过度动画,代码如下:

  1. <template>
  2. <div ref="message" class="lx-message">
  3. <!-- 字体 -->
  4. <i class="iconfont" :class="iconClass"></i>
  5. <!-- 消息提示 -->
  6. <span :class="messageClass">
  7. {{ message }}
  8. </span>
  9. </div>
  10. </template>
  11. <script>
  12. export default {
  13. name: 'MessageComponent',
  14. data() {
  15. return {
  16. message: '',
  17. // 类型
  18. type: '',
  19. // 事件
  20. duration: 2000,
  21. // 计时器
  22. timer: null,
  23. }
  24. },
  25. computed: {
  26. // 动态添加类名
  27. iconClass() {
  28. // 成功
  29. if (this.type === 'success') {
  30. return `icon-correct`
  31. // 错误
  32. } else if(this.type === 'error') {
  33. return `icon-error`
  34. // 警告
  35. } else if (this.type === 'warning') {
  36. return `icon-jinggao-warning`
  37. // 加载
  38. } else if (this.type === 'loading') {
  39. return `icon-refresh rotate`
  40. }
  41. return ``
  42. },
  43. messageClass() {
  44. if (this.type === 'success') {
  45. return `lx-message-content`
  46. } else if(this.type === 'error') {
  47. return `lx-message-error`
  48. } else if(this.type === 'warning') {
  49. return `lx-message-warning`
  50. } else if(this.type === 'loading') {
  51. return `icon-message-refresh`
  52. }
  53. return ``
  54. }
  55. },
  56. methods: {
  57. // 打开的方法
  58. showMessage(message, type, duration) {
  59. if(type === 'success') {
  60. this.type = type;
  61. this.message = message || '这是一条成功消息'; // 不传message就是默认值
  62. this.duration = duration || 2000;
  63. }
  64. else if (type === 'error') {
  65. this.type = type;
  66. this.message = message || '这是一条失败消息';
  67. this.duration = duration || 2000;
  68. }
  69. else if (type === 'warning') {
  70. this.type = type;
  71. this.message = message || '这是一条警告消息';
  72. this.duration = duration || 2000;
  73. }
  74. else if (type === 'loading') {
  75. this.type = type;
  76. this.message = message || '这是一条加载消息';
  77. this.duration = duration || 2000;
  78. }
  79. // 过渡
  80. this.$refs.message.style.transform = "translate(-50%,75px)";
  81. if (this.timer) {
  82. this.timer = clearTimeout(this.timer);
  83. }
  84. this.timer = setTimeout(() => {
  85. this.closeMessage();
  86. }, this.duration);
  87. },
  88. // 关闭的方法
  89. closeMessage() {
  90. if (this.timer) {
  91. this.timer = clearTimeout(this.timer);
  92. }
  93. // 过渡
  94. this.$refs.message.style.transform = "translate(-50%,0px)";
  95. }
  96. }
  97. }
  98. </script>
  99. <style scoped>
  100. @import url('../assets/icon/iconfont.css');
  101. </style>
  102. <style scoped lang="less">
  103. .lx-message {
  104. max-width: 70%;
  105. position: fixed;
  106. height: 25px;
  107. display: flex;
  108. align-items: center;
  109. top: -40px;
  110. left: 50%;
  111. transform: translateX(-50%);
  112. padding: 5px 15px;
  113. border-radius: 8px;
  114. text-align: center;
  115. background-color: #edf7fc;
  116. border-color: #b9c0c4;
  117. border: 1px solid transparent;
  118. transition: 0.55s;
  119. z-index: 999;
  120. span {
  121. margin-left: 5px;
  122. }
  123. i {
  124. &.rotate {
  125. animation: moveicon 1.5s infinite linear;
  126. }
  127. }
  128. }
  129. @keyframes moveicon {
  130. 0% {
  131. rotate: 0deg;
  132. }
  133. 100% {
  134. rotate: 360deg;
  135. }
  136. }
  137. .icon-correct {
  138. color: #19be6b;
  139. font-size: 22px;
  140. }
  141. .lx-message-content {
  142. color: #19be6b;
  143. }
  144. .icon-error {
  145. color: #ee3c10;
  146. font-size: 22px;
  147. }
  148. .lx-message-error {
  149. color: #ed3f13;
  150. }
  151. .icon-jinggao-warning {
  152. color: #ff9900;
  153. font-size: 22px;
  154. }
  155. .lx-message-warning {
  156. color: #eb8d01;
  157. }
  158. .icon-refresh {
  159. color: #57c5f7;
  160. font-size: 22px;
  161. }
  162. .icon-message-refresh {
  163. color: #57c5f7;
  164. }
  165. </style>

上述showMessage方法中代码都一样。我们可以抽离出一个方法叫base 

  1. base(type, duration) {
  2. this.type = type;
  3. this.duration = duration || 2000;
  4. },

修改如下:

  1. base(type, duration) {
  2. this.type = type;
  3. this.duration = duration || 2000;
  4. },
  5. // 打开的方法
  6. showMessage(message, type, duration) {
  7. if(type === 'success') {
  8. this.message = message || '这是一条成功消息';
  9. this.base(type, duration)
  10. }
  11. else if (type === 'error') {
  12. this.message = message || '这是一条失败消息';
  13. this.base(type, duration)
  14. }
  15. else if (type === 'warning') {
  16. this.message = message || '这是一条警告消息';
  17. this.base(type, duration)
  18. }
  19. else if (type === 'loading') {
  20. this.message = message || '这是一条加载消息';
  21. this.base(type, duration)
  22. }
  23. // 过渡
  24. this.$refs.message.style.transform = "translate(-50%,75px)";
  25. if (this.timer) {
  26. this.timer = clearTimeout(this.timer);
  27. }
  28. this.timer = setTimeout(() => {
  29. this.closeMessage();
  30. }, this.duration);
  31. }

7、测试组件:

  1. <template>
  2. <div id="app">
  3. <lx-button @click="error" size="large" type="error">错误</lx-button>
  4. <lx-button @click="warning" size="small" type="warning">警告</lx-button>
  5. <lx-button disabled>禁用</lx-button>
  6. <lx-button @click="loadingData" type="info">加载</lx-button>
  7. <lx-button @click="$Message.close()" >关闭</lx-button>
  8. <lx-button @click="success" size="big" type="success">成功</lx-button>
  9. </div>
  10. </template>
  11. <script>
  12. export default {
  13. methods: {
  14. loadingData() {
  15. this.$Message.loading('正在加载...')
  16. this.$api.get('/api/list').then(res => {
  17. this.$Message.close()
  18. if(res.status >= 200) {
  19. this.$Message.success('加载成功...')
  20. this.message = res.data
  21. } else {
  22. this.$Message.error('加载失败...')
  23. }
  24. })
  25. },
  26. success() {
  27. this.$Message.success('这是一条成功消息...')
  28. },
  29. warning() {
  30. this.$Message.warning('这是一条警告消息...')
  31. },
  32. error() {
  33. this.$Message.error('这是一条错误消息...')
  34. }
  35. }
  36. }
  37. </script>
  38. <style>
  39. </style>

按钮也是自己封装的按钮,根据传递的类型更改按钮的大小尺寸和颜色背景是否禁用。点击对应的按钮会弹出下滑效果的提示,加载按钮的提示图标加了一直旋转的动画更美观,加载成功就会弹出成功提示的消息 点击关闭就会触发关闭的回调

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/817979
推荐阅读
相关标签
  

闽ICP备14008679号