由于项目中经常会用到alert这种组件,平常都是全局注册标签,使用时引入,比较繁琐;
<!–more–>
借鉴别人这种组件一般是在js中被调用,vue中组件主要是使用了标签的形式,
现记录通过Vue.extend实现的动态组件;
Vue-extend官方文档
项目预览
<iframe src=”https://codesandbox.io/embed/…; title=”弹窗组件” allow=”geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media” style=”width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;” sandbox=”allow-modals allow-forms allow-popups allow-scripts allow-same-origin”></iframe>
Alert开发
项目目录
components
alert
- alert.vue
- index.js
- HelloWord.vue
- main.js
alert.vue
- template部分
<template>
<div class="shade">
<div class="mian">
<div class="content">
<span>{{ message }}</span>
</div>
<div class="btns">
<div class="btn"
v-for="(btn,index) in btns"
:key="index"
@click="(e)=>clickFn(e,btn)">{{btn.text}}</div>
</div>
</div>
</div>
</template>
- JavaScript部分
export default {
name: "alert",
data () {
return {
message: "this a alert",
btns: [
{
text: "yes",
click: () => console.log('yes')
},
{
text: "no",
click: () => console.log('yes')
}
]
};
},
methods: {
clickFn (event, btn) {
this.$el.remove(); // 移除DOM
const {
click = () => console.warn("请传入回调函数")
} = btn;
click(event, btn); // 传递回去
}
}
};
- css部分
.shade {
user-select: none;
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.03);
z-index: 998;
display: flex;
align-items: center;
justify-content: center;
}
.shade .mian {
background: white;
width: 80%;
border-radius: 5px;
overflow: hidden;
box-shadow: 0px 0px 5px 3px rgba(0, 0, 0, 0.04);
box-sizing: border-box;
animation: open 0.1s;
}
.shade .mian .content {
box-sizing: border-box;
width: 100%;
padding: 30px 20px;
}
.shade .mian .btns {
height: 45px;
box-sizing: border-box;
border-top: 1px solid rgba(0, 0, 0, 0.1);
display: flex;
justify-content: space-around;
align-items: center;
}
.shade .mian .btns .btn {
flex: 1 0 auto;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
border-right: 1px solid rgba(0, 0, 0, 0.1);
}
.shade .mian .btns .btn:last-child {
border-right: none;
}
.shade .mian .btns .btn:active {
color: white;
background-color: rgb(64, 169, 243);
}
@keyframes open {
0%,
100% {
transform: scale(1);
}
25%,
75% {
transform: scale(1.04);
}
50% {
transform: scale(1.06);
}
}
index.js
import Vue from 'vue';
import alert from './alert.vue';
let MyAlertConstructor = Vue.extend(alert);
let instance;
const MyAlert = (option) => {
// 创建实例并且过滤参数
instance = new MyAlertConstructor({
data: { ...option }
})
// 挂载实例
instance.$mount();
document.body.appendChild(instance.$el);
return instance;
}
// 挂载到Vue原型上
Vue.prototype.$alert = MyAlert;
main.js
import './components/alert'; // 引入注册一下
到这里我们的Alert组件就配置完成了;
如何使用
这里我在 Helloword.vue 中测试使用;
export default {
name: "HelloWorld",
props: {
msg: String
},
methods: {
Alert() {
// 使用直之前绑定到原型上的方法
this.$alert({
message: "你今天开心吗?",
btns: [
{
text: "开心",
click: () => {
// 测试是否可以拿到这边的this
console.log(this.msg);
}
},
{
text: "不开心",
click: (e, btn) => {
// 这里的event target 可能没用 因为已经移除DOM了
// 返回btn原来本身
console.log("不开心", e, btn);
}
},
{
text: "无回调"
// 测试一下没有回调函数的时候
},
{
text: "帮助",
click: this.isOK
}
]
});
},
isOK() {
console.log("输出帮助");
}
}};