在项目开发过程中可能我们习惯了使用各种现成的UI库,它可以帮助我们快速的完成项目开发,例如我们在项目中经常使用到的Toast、Message提示组件,我们通常只需要通过js来调用就可以使用了,和我们平常使用组件的方式(import导入、components注册)并不一样,那接下来我们就自己来实现一个通过js方法来使用的组件。我们最后要实现的组件就是element-UI的Message消息提示
一、准备工作
我们首先在项目中新建一个文件夹来存放这个组件,我建在了/src/components/Message/
,很显然Message就是我放提示组建的目录。
接着我们在Message
下再建一个index.vue
和index.js
的文件,js是我们组件的入出口也是用来导出方法被调用的主体。
二、编写组件模板
我们先写一个基础的样式,然后通过js调用渲染出来,之后我们在对组件进行细节优化
index.vue
内容
<template>
<div class="message">
<p>这是一条消息提示</p>
</div>
</template>
<script>
export default {
name: 'Message'
}
</script>
<style scoped lang="stylus">
.message
position fixed
top 3vh
left 50vw
transform translateX(-50%)
border 1px solid #EBEEF5
background-color #edf2fc
min-width 340px
min-height 50px
display flex
align-items center
box-sizing border-box
padding 0 15px
border-radius 5px
</style>
复制代码
index.js
内容
import Vue from 'vue';
import Message from './index.vue';
const MessageConstructor = Vue.extend(Message);
export const $message = () => {
const instance = new MessageConstructor().$mount();
document.body.appendChild(instance.$el);
}
复制代码
- 在页面中引入
$message
方法使用
<script>
import { $message } from '@/components/Message/index';
export default {
name: 'home',
mounted() {
// 正常应该在点击按钮或者某些操作执行后调用,我这里为了直观显示就在生命周期内调用了
$message();
}
}
</script>
复制代码
- 效果
- 详解
index.vue
中是我们编写组件的代码,和我们正常编写Vue组件使一毛一样的。我们之所以可以通过调用js方法来使用组件,最关键的代码是在index.js
中。
index.js
中只有7行代码,看一眼,很容易猜到最核心的肯定就是extend
、$mount
和appendChild
三个api,那我们就看下这三个API到底做了什么
- extend是Vue的一个全局api,它接收一个包含组件选项的对象,例如这个样子(官方示例)
Vue.extend({
template: '<p>{{firstName}} {{lastName}} aka {{alias}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
复制代码
然后extend会创建一个Vue‘子类’(猜测就是一个没有被实例化的Vue组件)
$mount
:如果我们对extend
创建的子类进行实例化的时候没有传入 el 选项,那此时这个组件就处于未挂载的状态,我们就需要调用$mount
方法,手动将其挂载,$mount
方法如果没有传入参数,那么它挂载后会自动关联此组件的顶层元素,如果传入参数(可以接收元素、元素选择器)则关联传入的元素。基于此其实我们也可以不调用$mount
方法,在实例化的时候传入el选项;
import Vue from 'vue';
import Message from './index.vue';
const MessageConstructor = Vue.extend(Message);
export const $message = () => {
const instance = new MessageConstructor({
el: document.createElement('div'),
});
document.body.appendChild(instance.$el);
}
复制代码
- appendChild: 至此就很容易理解了,最后将组件加入到body主体中渲染出来
- 最后使用的时候调用
$message
方法,没什么说的。
很关键的内容都在这里。那么接下来我们就再实现个东西,Element-UI的这个组件是可以传入自定义消息内容的,也可以传入不同的type
来显示成功或警告样式的消息,更进一步,比如我们需要在消息关闭的时候来做别的操作,又要如何处理呢?
三、组件完善
1. 自定义组件内容
- 修改
index.js
代码
import Vue from 'vue';
import Message from './index.vue';
const MessageConstructor = Vue.extend(Message);
// 方法接收个options参数,options必须是object类型
export const $message = (options) => {
const instance = new MessageConstructor({
el: document.createElement('div'),
// 组件实例生成的时候在给组件动态传入data
data: options
});
document.body.appendChild(instance.$el);
}
复制代码
- 修改
index.vue
代码
<template>
<div class="message">
// 内容改为可变的
<p>{{message}}</p>
</div>
</template>
<script>
export default {
name: 'Message',
// data是新增的
data() {
return {
message: '',
}
}
}
</script>
<style scoped lang="stylus">
.message
position fixed
top 3vh
left 50vw
transform translateX(-50%)
border 1px solid #EBEEF5
background-color #edf2fc
min-width 340px
min-height 50px
display flex
align-items center
box-sizing border-box
padding 0 15px
border-radius 5px
</style>
复制代码
- 调用时传入内容
$message({message: '对不起,注册失败'});
复制代码
2. 增加提示关闭按钮,提示被关闭后调用者可以感知
- 修改
index.vue
代码
<template>
<div class="message">
<p>{{message}}</p>
<i class="close" @click="handleClose">×</i>
</div>
</template>
<script>
export default {
name: 'Message',
data() {
return {
message: '',
}
},
methods: {
emitClose() {},
handleClose() {
this.$el.parentNode.removeChild(this.$el);
this.emitClose();
}
}
}
</script>
<style scoped lang="stylus">
.message
position fixed
top 3vh
left 50vw
transform translateX(-50%)
border 1px solid #EBEEF5
background-color #edf2fc
min-width 340px
max-width 500px
min-height 50px
display flex
align-items center
justify-content space-between
box-sizing border-box
padding 0 15px
border-radius 5px
.close
font-size 25px
align-self flex-start
margin-top -5px
margin-right -9px
cursor pointer
</style>
复制代码
- 修改
index.js
代码
import Vue from 'vue';
import Message from './index.vue';
const MessageConstructor = Vue.extend(Message);
export const $message = (options,methods = {}) => {
const instance = new MessageConstructor({
el: document.createElement('div'),
data: options,
methods
});
document.body.appendChild(instance.$el);
}
复制代码
- 调用
$message({message: '对不起,注册失败对不起'}, {
emitClose() {
console.log('组件被关闭了');
},
});
复制代码
TIP: 如果关闭的时候希望被调用者可以被感知,除了传methods,其实也可以直接传入data,不过传入的就是一个函数,类似于
$message({
message: '对不起,注册失败对不起',
onClose() {
console.log('组件被关闭了');
},
});
复制代码
四、补充
至此其实我们讲这个组件的目的已经完成了,就是告诉你如何通过js来使用”消息提示“这类的组件,其余的成功、失败、警告、定时关闭等功能,就不一一实现了,时间空闲的各位可以自行实现一下。
如果这篇文章对你有作用还望不吝点个赞,如果有其他疑问或内容有误可以在评论留言指正啊。拜拜!