vue: 自定义一个message组件

1,042 阅读1分钟

前因

因为在上家公司没有操作过把组件转换为函数调用,现在想自己动手尝试下自定义message组件,夯实下基础。

第一步:确定ui

ui一开始是想简单实现下组件,主要的工作是在于install函数。

微信图片_20210927181754.png 所以只是涉及了简单的页面。

第二步:开始编写组件

组件的代码很简单,如下所示。

  <div class="message" v-show="show">
    <div class="message-content">
      <span class="message-text">消息内容</span>
    </div>
  </div>
</template>
<script>
export default {
  name: 'message',
  props: {
    show: {
      type: Boolean,
      default: false
    },
    duration: {
      type: Number,
      default: 0
    }
  },
  watch: {
    async show (o) {
      if (o) {
        this.duration !== 0 && setTimeout(() => {
          setTimeout(() => {
            this.show = false
          }, 500)
        }, this.duration)
      }
    }
  },
  methods: {
    close () {
      setTimeout(() => {
        this.show = false
      }, 500)
    }
  }
};
</script>
<style scoped>
.message {
  position: fixed;
  top: 0px;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100vw;
  height: 100vh;
  /* */
  display: flex;
  align-items: center;
  justify-content: center;
}

.message .message-content {
  width: 120px;
  height: 100px;
  background-color: rgba(0, 0, 0, 0.75);
  border-radius: 5px;
  line-height: 1.5;
  padding: 10px 0;
  display: flex;
  align-items: center;
  flex-direction: column;
  justify-content: center;
}
.message .message-content .message-text {
  padding-top: 10px;
  color: #fff;
  font-size: 14px;
}
</style>

第三步:开始编写index.js


export default {
  install (Vue) {
    Vue.prototype['$message'] = function (options = {}) {
      const Message = Vue.extend(MessageSub);
      const component = new Message({
        data: options
      }).$mount();
      document.body.appendChild(component.$el); // 因为函数调用不存在parent,所以需要添加到body中
      Vue.nextTick(() => {
        component.show = true;
      });
    };
  }
};

简单实现了一下。参考了网上的代码,以前没使用过extend方法。

总结: 到这里,message已经是简单实现了,同时也了解到了extend方法的使用技巧。(extend 方法返回构造函数,然后在new一下,最后添加到document.body中)

进阶:优化组件

目前的组件只是基础版本,需要在优化下。

问题1:多次调用$message事件会产生多个Message 实例,这个是不被允许的。所以我提供了一个变量来缓存组件。

let cache; // index.js中定义

if (cache) {
   Vue.nextTick(() => {
        component.show = true;
   });
   return true
}

问题2:假设这个message不会自动关闭,那么需要在$message方法需要返回一个方法,用来关闭message组件。

return {
    close () {
       cache.close.call(Vue);
    }
};

具体组件的close方法也很简单

close () {
      setTimeout(() => {
        this.show = false
      }, 500)
    }

总结:至此,已经解决了2个问题。

总结

通过这个自定义组件,学到了如何把组件转为函数调用。 写的不好,请大家多多包涵。