如何封装一个vue3组件,以Toast弹框为例 Bertha 。 2022-11-12 01:40 439阅读 0赞 1、建一个components文件夹,里面建一个Toast.vue文件 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h5cGhm_size_16_color_FFFFFF_t_70][] <template> <div class="toast">{ {message}}</div> </template> <script> import { reactive } from 'vue' export default { props: ['message'] } export const useToastEffect = () => { const toastData = reactive({ showToast: false, toastMessage: '' }) const showToast = (message) => { toastData.showToast = true toastData.toastMessage = message setTimeout(() => { toastData.showToast = false toastData.toastMessage = '' }, 2000) } return { toastData, showToast } } </script> <style lang="scss" scoped> .toast { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); padding: .1rem; background: rgba(0, 0, 0, .35); border-radius: .05rem; color: #FFF; } </style> 调用Toast组件 <template> <div class="wrapper"> <img class="wrapper__img" src="http://www.dell-lee.com/imgs/vue3/user.png"/> <div class="wrapper__input"> <input class="wrapper__input__content" placeholder="用户名" v-model="data.username" /> </div> <div class="wrapper__input"> <input type="password" class="wrapper__input__content" placeholder="请输入密码" v-model="data.password" /> </div> <div class="wrapper__login-button" @click="handleLogin">登陆</div> <div class="wrapper__login-link" @click="handleRegisterClick">立即注册</div> <Toast v-if="toastData.showToast" :message="toastData.toastMessage" /> <!-- 2、页面中调用 --> </div> </template> <script> import { reactive } from 'vue' import { useRouter } from 'vue-router' import { post } from '../../utils/request' import Toast, { useToastEffect } from '../../components/Toast' // 1、在需要的页面引用 export default { name: 'Login', components: { Toast }, setup () { const router = useRouter() const data = reactive({ username: '', password: '' }) const { toastData, showToast } = useToastEffect() // 3、 const handleLogin = async () => { try { const result = await post('/api/user/login', { username: data.username, password: data.password }) if (result?.errno === 0) { localStorage.isLogin = true router.push({ name: 'Home' }) } else { showToast('登录失败') // 4、调用showToast组件 } } catch (e) { showToast('请求失败') // // 5、调用showToast组件 } } const handleRegisterClick = () => { router.push({ name: 'Register' }) } return { handleLogin, handleRegisterClick, data, toastData } // 6、返回toastData } } </script> <style lang="scss" scoped> @import '../../style/viriables.scss'; .wrapper { position: absolute; top: 50%; left: 0; right: 0; transform: translateY(-50%); &__img { display: block; margin: 0 auto .4rem auto; width: .66rem; height: .66rem; } &__input { height: .48rem; margin: 0 .4rem .16rem .4rem; padding: 0 .16rem; background: #F9F9F9; border: 1px solid rgba(0,0,0,0.10); border-radius: 6px; border-radius: 6px; &__content { line-height: .48rem; border: none; outline: none; width: 100%; background: none; font-size: .16rem; color: $content-notice-fontcolor; &::placeholder { color: $content-notice-fontcolor; } } } &__login-button { margin: .32rem .4rem .16rem .4rem; line-height: .48rem; background: #0091FF; box-shadow: 0 .04rem .08rem 0 rgba(0,145,255,0.32); border-radius: .04rem; border-radius: .04rem; color: #fff; font-size: .16rem; text-align: center; } &__login-link { text-align: center; font-size: .14rem; color: $content-notice-fontcolor; } } </style> [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3h5cGhm_size_16_color_FFFFFF_t_70]: /images/20221022/78a34fd7ff084d16a55aa3737979b6c6.png
还没有评论,来说两句吧...