对询问框组件的封装....直接上代码吧
1. 封装
在src/components下新建my-confirm.vue组件
代码如下(示例):
<template>
<div class="my-confirm" :class="{ fade: fade }">
<div class="wrapper" :class="{ fade: fade }">
<div class="header">
<h3>{{ title }}</h3>
<a @click="cancelCallback" href="JavaScript:;" class="iconfont icon-close-new"></a>
</div>
<div class="body">
<i class="iconfont icon-warning"></i>
<span>{{ text }}</span>
</div>
<div class="footer">
<MyButton @click="cancelCallback" size="mini" type="gray">取消</MyButton>
<MyButton @click="submitCallback" size="mini" type="primary">确认</MyButton>
</div>
</div>
</div>
</template>
<script>
import MyButton from './my-button.vue'
import { onMounted, ref } from 'vue'
export default {
name: 'MyConfirm',
components: { MyButton },
props: {
title: {
type: String,
default: ''
},
text: {
type: String,
default: ''
},
cancelCallback: {
type: Function,
required: true
},
submitCallback: {
type: Function,
required: true
}
},
setup() {
const fade = ref(false)
onMounted(() => {
setTimeout(() => {
fade.value = true
}, 0)
})
return { fade }
}
}
</script>
<style scoped lang="less">
.my-confirm {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 8888;
background: rgba(0, 0, 0, 0);
&.fade {
transition: all 0.4s;
background: rgba(0, 0, 0, 0.5);
}
.wrapper {
width: 400px;
background: #fff;
border-radius: 4px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -60%);
opacity: 0;
&.fade {
transition: all 0.4s;
transform: translate(-50%, -50%);
opacity: 1;
}
.header,
.footer {
height: 50px;
line-height: 50px;
padding: 0 20px;
}
.body {
padding: 20px 40px;
font-size: 16px;
.icon-warning {
color: #cf4444;
margin-right: 3px;
font-size: 16px;
}
}
.footer {
text-align: right;
.xtx-button {
margin-left: 20px;
}
}
.header {
position: relative;
h3 {
font-weight: normal;
font-size: 18px;
}
a {
position: absolute;
right: 20px;
top: 10px;
font-size: 20px;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
text-decoration: none;
color: #999;
&:hover {
color: #666;
}
}
}
}
}
</style>
同级新建confirm.js文件,用于创建虚拟的DOM节点
// 封装一个方法,实现确认框提示效果
import { createVNode, render } from 'vue'
import MyConfirm from './my-confirm.vue'
// 动态创建一个DOM容器
const container = document.createElement('div')
container.setAttribute('class', 'my-confirm-container')
document.body.appendChild(container)
export default ({ title, text }) => {
return new Promise((resolve, reject) => {
// 如果想让then触发,需要调用resolve:点击确认按钮触发
// 如果想让catch触发,需要调用reject:点击取消按钮触发
// 点击确认按钮
const submitCallback = () => {
// 销毁确认框
render(null, container)
resolve()
}
// 点击取消按钮
const cancelCallback = () => {
// 销毁确认框
render(null, container)
reject(new Error('cancel'))
}
// 把组件渲染到页面中
const vnode = createVNode(MyConfirm, { title, text, cancelCallback, submitCallback })
// 把虚拟节点渲染DOM中
render(vnode, container)
})
}
同级中的index.js文件中,将其注册为全局组件,并在vue实例上扩展一个实例方法 批量注册为全局组件。
import Message from '@/components/message'
import Confirm from '@/components/confirm'
// 导入components文件夹下的所有组件,封装的全局组件必须有name值
// 批量导入需要使用一个函数 require.context(dir,deep,matching)
// 参数:1. 目录 2. 是否加载子目录 3. 加载的正则匹配
const importFn = require.context('./', true, /\.vue$/)
export default {
install(app) {
// 批量注册全局组件
importFn.keys().forEach(key => {
// 导入组件
const component = importFn(key).default
// 注册组件
app.component(component.name, component)
})
// 扩展一个实例方法
app.config.globalProperties.$message = Message
app.config.globalProperties.$confirm = Confirm
}
}
在main.js中以插件的方式使用我们封装好的全局组件和实例方法
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// 自己封装的组件库
import myUI from './components'
createApp(App).use(store).use(router).use(myUI).mount('#app')
2. 使用
任意.vue结尾的文件中使用,这里给大家演示一下,大家根据具体需求使用即可
代码如下(示例):
<template>
<div class="home-container">
<my-button type="plain" size="middle" @click="showConfirm">点击显示询问框</my-button>
</div>
</template>
<script>
import Message from '@/components/library/message.js'
import Confirm from '@/components/library/confirm.js'
export default {
name: 'App',
setup() {
const showConfirm = () => {
Confirm({ title: '警告', text: '是否继续操作?' })
.then(ret => {
Message({ text: '操作成功', type: 'success' })
})
.catch(err => {
// 点击取消按钮触发
if (err === 'cancel') return
Message({ text: '操作取消', type: 'error' })
})
}
return { showConfirm }
}
}
</script>
<style lang="less">
.home-container {
margin: 150px auto;
width: 240px;
height: 100px;
}
</style>