您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax | jQuery | 小程序 |

vue3 teleport的使用案例详解

51自学网 2022-02-21 13:38:31
  javascript

官网

https://cli.vuejs.org/zh/guide/

有时组件模板的一部分逻辑上属于该组件,而从技术角度来看,最好将模板的这一部分移动到 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上

到此这篇关于vue3 teleport的使用demo的文章就介绍到这了,更多相关vue3 teleport使用内容请搜索51zixue.net以前的文章或继续浏览下面的相关文章希望大家以后多多支持51zixue.net!


下载地址:
node连接mysql查询事务处理的实现
JavaScript面试之如何实现数组拍平(扁平化)方法
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。