一.菜单组件的封装
使用element-ui
来掌握菜单组件的使用
npm install element-ui
1.1 静态菜单
使用element-ui构建静态菜单
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
<el-menu default-active="2" class="el-menu-vertical-demo">
<el-submenu index="1">
<template slot="title">导航一</template>
<el-submenu index="1-1">
<template slot="title">选项1-1</template>
<el-menu-item index="1-1-1">选项1-1-1</el-menu-item>
<el-menu-item index="1-1-2">选项1-1-2</el-menu-item>
</el-submenu>
<el-menu-item index="1-2">选项1-2</el-menu-item>
</el-submenu>
<el-menu-item index="2">
导航二
</el-menu-item>
<el-menu-item index="3">
导航三
</el-menu-item>
<el-menu-item index="4">
导航四
</el-menu-item>
</el-menu>
1.2 自定义菜单
<my-menu>
<my-submenu>
<template slot="title">导航1</template>
<my-menu-item>选项1.1</my-menu-item>
<my-menu-item>选项1.2</my-menu-item>
<my-submenu>
<template slot="title">导航1.3</template>
<my-menu-item>选项1.3.1</my-menu-item>
<my-menu-item>选项1.3.2</my-menu-item>
</my-submenu>
</my-submenu>
<my-menu-item>导航2</my-menu-item>
<my-menu-item>导航3</my-menu-item>
<my-menu-item>导航4</my-menu-item>
</my-menu>
分别编写三个组件
1.my-menu
<template>
<ul><slot></slot></ul>
</template>
2.my-menu-item
<template>
<li><slot></slot></li>
</template>
3.my-submenu
<template>
<div>
<span @click="changeShow()"><slot name="title" ></slot></span>
<ul v-if="isShow"><slot></slot></ul>
</div>
</template>
<script>
export default {
methods:{
changeShow(){
this.isShow = !this.isShow
}
},
data(){
return {isShow:true}
}
}
</script>
1.3 组件的动态渲染
{
menus: [
{
name: "选项1",
children: [
{
name: "选项1.1",
children: [{ name: "选项1.1.1" }, { name: "选项1.1.2" }]
},
{ name: "选项2" }
]
},
{ name: "选项2" },
{ name: "选项3" }
]
}
组件的封装
<my-menu>
<template v-for="menu in menus">
<my-menu-item :key="menu.name" v-if="!menu.children">{{menu.name}}</my-menu-item>
<resub v-else :key="menu.name" :menu="menu"></resub>
</template>
</my-menu>
<!-- 将重复的内容单独进行抽离 -->
<my-submenu >
<template slot="title">{{menu.name}}</template>
<template v-for="child in menu.children">
<resub v-if="child.children" :menu="child" :key="child.name"></resub>
<my-menu-item v-else :key="child.name">{{child.name}}</my-menu-item>
</template>
</my-submenu>
二.Message组件
Message组件的调用方式
<template>
<button @click="showMessage">点我啊</button>
</template>
<script>
export default {
methods:{
showMessage(){
Message.info({ // 直接调用
message:'hello 我帅不帅',
duration:3000
});
this.$message.info({ // 通过实例调用
message:'hello 你很帅',
duration:3000
});
}
}
}
</script>
2.1 编写Message组件
要考虑数据驱动视图,多次点击显示多个弹层,给每个层增加 id号,延迟时间和内容
<template>
<div class="messages">
<!-- 显示在数组中的层 -->
<div v-for="message in messages" :key="message.id">
{{message.message}}
</div>
</div>
</template>
<script>
export default {
data(){
return {messages:[]}
},
mounted(){
// 给所有弹层增加唯一标示 方便弹层的卸载
this.id = 0;
},
methods:{
add(option){
let id = this.id++; // id号
let layer = {...option,id}
this.messages.push(layer); // 将层存储起来
layer.timer = setTimeout(()=>{
this.remove(layer);
},option.duration)
},
remove(layer){
clearTimeout(layer.timer); // 清除定时器
// 移除层
this.messages = this.messages.filter(message=>layer.id !== message.id);
}
}
}
</script>
通过js文件控制显示Message弹层
步骤一:暴露调用方法
// 暴露 不同类型的弹层方法
const Message = {
info(options){
// 调用增加弹层方法
getInstance(options).add(options);
},
warn(){},
danger(){},
success(){}
}
export {
Message
}
步骤二:生产实例
import Vue from 'vue';
import MessageComponent from './Message.vue';
let getInstance = () =>{
let vm = new Vue({
render:h=>h(MessageComponent)
}).$mount();
let messageComponent = vm.$children[0];
// 获取真实dom元素,将其挂在页面上
document.body.appendChild(vm.$el);
return {
add(options){ // 调用组件的add方法
messageComponent.add(options);
}
}
}
const Message = {
info(options){
// 调用增加弹层方法
getInstance().add(options);
},
warn(){},
danger(){},
success(){}
}
// 暴露 不同类型的弹层方法
export {
Message
}
步骤三:实现单例
let instance;
let inst = () => {
instance = instance || getInstance();
return instance;
}
const Message = {
info(options){
// 调用增加弹层方法
inst().add(options);
},
warn(){},
danger(){},
success(){}
}
// 暴露 不同类型的弹层方法
export {
Message
}
2.2 封装插件
install方法和use方法的应用
let _Vue;
export default {
install(Vue,options){
if(!_Vue){
_Vue = Vue;
let $message = {}
Object.keys(Message).forEach(type => {
$message[type] = Message[type]
});
Vue.prototype.$message = $message
}
}
}
// 组件中使用插件
import {Message} from './components/Message';
this.$message.info({
content:'hello 你很帅',
duration:3000
})
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。