在vue3项目中teleport的具体使用是怎样的
Admin 2022-06-20 群英技术资讯 269 次浏览
有时组件模板的一部分逻辑上属于该组件,而从技术角度来看,最好将模板的这一部分移动到 DOM 中 Vue app 之外的其他位置。
这两个组件都是在父元素里的,是父组件的子级,但是从技术角度来看,他们是应该是挂载在body下面的
未修改版
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue3</title> <script src="./vue.js"></script> </head> <body> <div id="hello-vue" class="box"> <div>我是父组件</div> <div>我是父组件</div> <div>我是父组件</div> <div>我是父组件</div> <div>我是父组件</div> <div>我是父组件</div> <button @click="handleClick">点我显示子组件</button> <cpn ref="compRef" @show-confirm="showConfirm"></cpn> <confirm ref="confirmRef" @confirm="handleConfirm" @cancel="handleCancel" text="确定退出吗"></confirm> </div> <!--点击按钮后显示的那个组件--> <template id="mycpn"> <transition name="list-fade"> <div class="cpnContainer" v-show="isshow" @click.stop="handleClose()"> <div class="inner-wrapper" @click.stop> 用到了transition <div class="text"> <div>我是inner-text</div> <div>我是inner-text</div> <div>我是inner-text</div> <div>我是inner-text</div> <div>我是inner-text</div> </div> <div class="close" @click="handleClose()">close</div> </div> </div> </transition> </template> <!--确认关闭confirm组件--> <template id="confirm"> <transition name="confirm-fade"> <div v-show="isshow" class="confirm"> <div class="confirm-wrapper"> <div class="confirm-content"> <p>{{text}}</p> <div class="btnContainer"> <button style="background-color: darkseagreen;margin-right: 40px" @click="confirm">{{confirmBtnText}}</button> <button @click="cancel">{{cancelBtnText}}</button> </div> </div> </div> </div> </transition> </template> <script> const cpn = { template: "#mycpn", props: {}, data() { return { // bbb: 145612 isshow: false } }, methods: { show() { this.isshow = true }, hide() { // console.log("hide") this.isshow = false }, handleClose() { // console.log("hide") this.$emit("show-confirm") }, } } const confirm = { template: "#confirm", props: { text: { type: String, default: 'fdsafdasfdas' }, confirmBtnText: { type: String, default: '确定' }, cancelBtnText: { type: String, default: '取消' } }, data() { return { // bbb: 145612 isshow: false } }, methods: { show() { this.isshow = true }, hide() { this.isshow = false // 控制子组件的显示 }, // 点击按钮后向父组件派发事件 confirm() { this.hide(); this.$emit("confirm") }, cancel() { this.hide() this.$emit('cancel') } } } const HelloVueApp = Vue.createApp({ data() { return { message: 'Hello Vue!!' } }, components: { cpn, confirm }, methods: { handleClick() { // 父组件调用子组件的方法 // this.$refs.compRef.show() this.$refs.compRef.show() }, showConfirm() { console.log("fdsa") this.$refs.confirmRef.show() }, // 点击取消或确定以后的逻辑 handleConfirm() { this.$refs.compRef.hide() }, handleCancel() { } } }).mount("#hello-vue") </script> </body> <style> * { font-size: 50px; } /*vue内置transition*/ .list-fade-enter-active, .list-fade-leave-active { transition: opacity .3s; } .list-fade-enter-active .inner-wrapper, .list-fade-leave-active .inner-wrapper { transition: all .3s; } .list-fade-enter-from, .list-fade-leave-to { opacity: 0; } .list-fade-enter-from .inner-wrapper, .list-fade-leave-to .inner-wrapper { transform: translate3d(0, 100%, 0); } /*子组件样式*/ .cpnContainer { position: fixed; top: 0; bottom: 0; left: 0; right: 0; background: rgba(0, 0, 0, .3); } .inner-wrapper { padding: 70px; background-color: darkcyan; position: fixed; bottom: 0; width: 100%; box-sizing: border-box; } .close { position: absolute; top: 50px; right: 50px; } /*confirm组件样式*/ .confirm { position: fixed; top: 0; bottom: 0; left: 0; right: 0; background-color: rgba(0, 0, 0, 0.14); } .btnContainer { padding: 0 70px; } .confirm-wrapper{ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 999; box-shadow: 0px 0px 80px 3px rgba(0, 0, 0, 0.2); } .confirm-content{ overflow: hidden; width: 600px; border-radius: 13px; background: white } .confirm-content p { display: block; padding-left: 40px; } /*.confirm-content {*/ /* border-radius: 8px;*/ /* box-shadow: 0px 0px 80px 3px rgba(0, 0, 0, 0.2);*/ /* position: absolute;*/ /* top: 50%;*/ /* left: 50%;*/ /* transform: translate(-50%, -50%);*/ /* !*p标签的margin top影响到了父元素 bfc*!*/ /* !*overflow: hidden;*!*/ /* background-color: white;*/ /*}*/ .confirm-content button { border: 1px solid cornflowerblue; background-color: transparent; padding: 25px 50px; margin-bottom: 30px; border-radius: 5px; } .confirm-fade-enter-active ,.confirm-fade-leave-active{ transition: all .3s; } .confirm-fade-enter-from ,.confirm-fade-leave-to{ opacity: 0; } .confirm-fade-enter-active .confirm-content { animation: confirm-zoom-in .3s; transform-origin: center; } .confirm-fade-leave-active .confirm-content { animation: confirm-zoom-out .3s; transform-origin: center; } @keyframes confirm-zoom-in { 0% { transform: scale(0); } 60% { transform: scale(1.1); } 100% { transform: scale(1); } } @keyframes confirm-zoom-out { 0% { transform: scale(1); } 30% { transform: scale(0.4); } 100% { transform: scale(0); } } </style> </html>
布局
修改版
布局
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Vue3</title> <script src="./vue.js"></script> </head> <body> <div id="hello-vue" class="box"> <div>我是父组件</div> <div>我是父组件</div> <div>我是父组件</div> <div>我是父组件</div> <div>我是父组件</div> <div>我是父组件</div> <button @click="handleClick">点我显示子组件</button> <cpn ref="compRef" @show-confirm="showConfirm"></cpn> <confirm ref="confirmRef" @confirm="handleConfirm" @cancel="handleCancel" text="确定退出吗"></confirm> </div> <!--点击按钮后显示的那个组件--> <template id="mycpn"> <teleport to="body"> <transition name="list-fade"> <div class="cpnContainer" v-show="isshow" @click.stop="handleClose()"> <div class="inner-wrapper" @click.stop> 用到了transition <div class="text"> <div>我是inner-text</div> <div>我是inner-text</div> <div>我是inner-text</div> <div>我是inner-text</div> <div>我是inner-text</div> </div> <div class="close" @click="handleClose()">close</div> </div> </div> </transition> </teleport> </template> <!--确认关闭confirm组件--> <template id="confirm"> <teleport to="body"> <transition name="confirm-fade"> <div v-show="isshow" class="confirm"> <div class="confirm-wrapper"> <div class="confirm-content"> <p>{{text}}</p> <div class="btnContainer"> <button style="background-color: darkseagreen;margin-right: 40px" @click="confirm">{{confirmBtnText}}</button> <button @click="cancel">{{cancelBtnText}}</button> </div> </div> </div> </div> </transition> </teleport> </template> <script> const cpn = { template: "#mycpn", props: {}, data() { return { // bbb: 145612 isshow: false } }, methods: { show() { this.isshow = true }, hide() { // console.log("hide") this.isshow = false }, handleClose() { // console.log("hide") this.$emit("show-confirm") }, } } const confirm = { template: "#confirm", props: { text: { type: String, default: 'fdsafdasfdas' }, confirmBtnText: { type: String, default: '确定' }, cancelBtnText: { type: String, default: '取消' } }, data() { return { // bbb: 145612 isshow: false } }, methods: { show() { this.isshow = true }, hide() { this.isshow = false // 控制子组件的显示 }, // 点击按钮后向父组件派发事件 confirm() { this.hide(); this.$emit("confirm") }, cancel() { this.hide() this.$emit('cancel') } } } const HelloVueApp = Vue.createApp({ data() { return { message: 'Hello Vue!!' } }, components: { cpn, confirm }, methods: { handleClick() { // 父组件调用子组件的方法 // this.$refs.compRef.show() this.$refs.compRef.show() }, showConfirm() { console.log("fdsa") this.$refs.confirmRef.show() }, // 点击取消或确定以后的逻辑 handleConfirm() { this.$refs.compRef.hide() }, handleCancel() { } } }).mount("#hello-vue") </script> </body> <style> * { font-size: 50px; } /*vue内置transition*/ .list-fade-enter-active, .list-fade-leave-active { transition: opacity .3s; } .list-fade-enter-active .inner-wrapper, .list-fade-leave-active .inner-wrapper { transition: all .3s; } .list-fade-enter-from, .list-fade-leave-to { opacity: 0; } .list-fade-enter-from .inner-wrapper, .list-fade-leave-to .inner-wrapper { transform: translate3d(0, 100%, 0); } /*子组件样式*/ .cpnContainer { position: fixed; top: 0; bottom: 0; left: 0; right: 0; background: rgba(0, 0, 0, .3); } .inner-wrapper { padding: 70px; background-color: darkcyan; position: fixed; bottom: 0; width: 100%; box-sizing: border-box; } .close { position: absolute; top: 50px; right: 50px; } /*confirm组件样式*/ .confirm { position: fixed; top: 0; bottom: 0; left: 0; right: 0; background-color: rgba(0, 0, 0, 0.14); } .btnContainer { padding: 0 70px; } .confirm-wrapper{ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 999; box-shadow: 0px 0px 80px 3px rgba(0, 0, 0, 0.2); } .confirm-content{ overflow: hidden; width: 600px; border-radius: 13px; background: white } .confirm-content p { display: block; padding-left: 40px; } /*.confirm-content {*/ /* border-radius: 8px;*/ /* box-shadow: 0px 0px 80px 3px rgba(0, 0, 0, 0.2);*/ /* position: absolute;*/ /* top: 50%;*/ /* left: 50%;*/ /* transform: translate(-50%, -50%);*/ /* !*p标签的margin top影响到了父元素 bfc*!*/ /* !*overflow: hidden;*!*/ /* background-color: white;*/ /*}*/ .confirm-content button { border: 1px solid cornflowerblue; background-color: transparent; padding: 25px 50px; margin-bottom: 30px; border-radius: 5px; } .confirm-fade-enter-active ,.confirm-fade-leave-active{ transition: all .3s; } .confirm-fade-enter-from ,.confirm-fade-leave-to{ opacity: 0; } .confirm-fade-enter-active .confirm-content { animation: confirm-zoom-in .3s; transform-origin: center; } .confirm-fade-leave-active .confirm-content { animation: confirm-zoom-out .3s; transform-origin: center; } @keyframes confirm-zoom-in { 0% { transform: scale(0); } 60% { transform: scale(1.1); } 100% { transform: scale(1); } } @keyframes confirm-zoom-out { 0% { transform: scale(1); } 30% { transform: scale(0.4); } 100% { transform: scale(0); } } </style> </html>
父组件如何调用子组件方法 用ref拿到组件 调用组件里的方法就ok
关于事件阻止冒泡
子组件向父组件通信 派发事件(emit)
boxshadow
vue transition动画
疑问 confirm-zoom动画为什么不能放在container上 只能放在content上
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
本文主要介绍了vue前端RSA加密java后端解密的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
这篇文章主要介绍了uni-app 的生命周期,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
目录一、字符串 split 方法二、使用 URLSearchParams 方法1、解析搜索字符串2、生成搜索字符串3、Node.js 代码三、使用正则匹配方法四、使用第三方库 qs一、字符串 split 方法url地址是字符串形式的,所以利用split方法将参数提取出来,该方法比较常用,而且容易理解(无关正则)let
在本篇文章里小编给大家整理了一篇关于js数组forEach实例用法详解内容,有需要的朋友们可以跟着学习参考下。
在开发后台管理系统的时候,很多地方都要用到导出excel 表格,比如将table中的数据导出到本地,这篇文章主要给大家介绍了关于Vue导出Excel功能的相关资料,需要的朋友可以参考下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008