【学习笔记05】动态组件和插槽


一、动态组件

  • 动态组件就是根据组件的名字来渲染组件
  • 动态组件在切换的时候会引起组件的挂载和卸载
  • keep-alive:缓存组件,用这个进行缓存数据,而且动态组件在在切换时就不在挂载和卸载了

1、发布评论和评论列表的切换

    <div id="box">
        <!-- 动态组件在切换的时候会引起组件的挂载和卸载 -->
        <button @click="cname='List'">评论列表</button>
        <button @click="cname='PublicComments'">发布评论</button>
        <!-- keep-alive 缓存组件   用这个进行缓存数据,而且动态组件在在切换时就不在挂载和卸载了 -->
        <keep-alive>
            <component :is="cname"></component>
        </keep-alive>
    </div>
    <script>
        let List = {
            template: "<div>列表组件</div>",
            created() {
                console.log("list created")
            },
            unmounted() {
                console.log("list unmounted")
            },
            activated() {
                console.log("list activated")
            },
            deactivated() {
                console.log("list deactivated")
            }

        }
        let PublicComments = {
            template: `<div>发布评论组件
                    <input type='text' />
                </div>`,
            activated() {
                console.log("PublicComments activated")
            },
            deactivated() {
                console.log("PublicComments deactivated")
            },
            created() {
                console.log("PublicComments created")
            },
            unmounted() {
                console.log("PublicComments unmounted")
            }
        }
        Vue.createApp({
            components: {
                List, PublicComments
            },
            data() {
                return {
                    cname: "List" //组件的名字,动态组件就是根据组件的名字来渲染组件
                }
            },
        }).mount("#box")
    </script>

在这里插入图片描述

2、后台管理系统

方法一:
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            background-color: #dcdedd;
        }

        #app {
            width: 1200px;
            height: 700px;
            margin: 0 auto;
            display: flex;
        }

        li {
            list-style: none;
        }

        .right {
            flex: 1;
        }

        ul {
            height: 700px;
            width: 250px;
            background-color: #00152a;
            color: #fff;
            font-size: 20px;
        }

        ul>li {
            width: 250px;
            height: 60px;
            text-align: center;
            line-height: 60px;
            margin: 10px 0;
            cursor: pointer;
        }

        .active {
            background-color: #006fb1;
        }

        .top {
            width: 100%;
            height: 80px;
            background-color: #fff;
            font-size: 30px;
            line-height: 80px;
            text-align: center;
        }

        .bottom>li {
            height: 530px;
            font-size: 30px;
            line-height: 530px;
            text-align: center;
            background-color: #fff;
            margin: 10px 0 10px 10px;
        }

        .Copyright {
            width: 950px;
            height: 70px;
            font-size: 18px;
            line-height: 70px;
            text-align: center;
            color: rgb(104, 103, 103);
            background-color: #fff;
        }
    </style>
    <div id="app">
        <ul>
            <li v-for="(item, index) in list" :key="item.id" @click="tab(index)" :class="{active:index === type}">
                {{item.name}}
            </li>
        </ul>
        <div class="right">
            <Top></Top>
            <ol class="bottom">
                <li v-for="(item, index) in list" :key="item.id" v-show="index === type">
                    {{item.name}}
                </li>
            </ol>
            <Bottom></Bottom>
        </div>
    </div>
    <script>
        const Top = {
            template: `<div class="top">头部</div>`
        }
        const Bottom = {
            template: `<div class="Copyright">&copy xxx公司版权所有</div>`
        }
        Vue.createApp({
            components: {
                Top, Bottom
            },
            data() {
                return {
                    type: 1,
                    list: [
                        { id: 1, name: '管理中心' },
                        { id: 2, name: '商品管理' },
                        { id: 3, name: '会员管理' },
                        { id: 4, name: '订单管理' },
                    ]
                }
            },
            methods: {
                tab(index) {
                    this.type = index
                }
            },
        }).mount("#app")
    </script>

在这里插入图片描述

方法二:动态组件
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        html,
        body,
        #box {
            height: 100%;
        }

        .layout {
            display: flex;
            height: 100%;
            background: #ccc;
        }

        .nav {
            text-align: center;
            height: 100%;
            background: #00152a;
            color: white;
            width: 200px;
            font-size: 20px;
        }

        .nav li {
            line-height: 50px;
            height: 50px;
            cursor: pointer;
        }

        li:hover {
            background-color: #006fb1;
        }

        .header {
            width: 100%;
            height: 80px;
            font-size: 20px;
            line-height: 80px;
            text-align: center;
            font-weight: 600;
            background-color: #fff;
        }

        .main {
            flex: 1;
        }

        .footer {
            height: 60px;
            text-align: center;
            line-height: 60px;
            background-color: #fff;
        }

        .center {
            background-color: #fff;
            margin: 10px;
            text-align: center;
            font-size: 30px;
            height: calc(100% - 80px - 60px);
        }
    </style>
    <div id="box">
        <Main-layout></Main-layout>
    </div>
    <script>
        let ManageCenter = {
            template: "<div class='center'>管理中心</div>"
        }
        let GoodsManage = {
            template: "<div class='center'>商品管理</div>"
        }
        let MemberManage = {
            template: "<div class='center'>会员管理</div>"
        }
        let OrderManage = {
            template: "<div class='center'>订单管理</div>"
        }
        let MainLayout = {
            components: {
                ManageCenter, GoodsManage, MemberManage, OrderManage
            },
            data() {
                return {
                    cname: "ManageCenter"
                }
            },
            template: `<div class="layout">
                        <div class="nav">
                            <ul>
                                <li @click='cname="ManageCenter"'>管理中心</li>
                                <li @click='cname="GoodsManage"'>商品管理</li>
                                <li @click='cname="MemberManage"'>会员管理</li>
                                <li @click='cname="OrderManage"'>订单管理</li>
                            </ul>
                        </div>
                        <div class="main">
                                <div class="header">头部</div>
                                <component :is="cname"></component>
                                <div class="footer"> 版权 &copy; 2022 </div>
                        </div>
                
                </div>`
        }
        Vue.createApp({
            components: {
                MainLayout
            }

        }).mount("#box")
    </script>

在这里插入图片描述

二、插槽

  • 没有名字的插槽叫匿名插槽
  • 有名字的插槽叫具名插槽
  • 可以携带数据的插槽叫作用域插槽或数据插槽
    <div id="box">
        {{str}}
        <Com>
            <!-- 组件开始和结束标记中间是插槽的内容  -->
            <template v-slot:default>
                <span>用户名</span>
            </template>
            <!-- <template #btn> -->
            <template v-slot:btn="props">
                <button @click="receive(props.n)">添加 </button>
            </template>
        </Com>
    </div>
    <script>
        let Com = {
            data() {
                return {
                    txt: ""
                }
            },
            // 没有名字的插槽叫匿名插槽  
            // 有名字的插槽叫具名插槽 
            // 可以携带数据的插槽叫作用域插槽或数据插槽
            template: `
            <div>
                <slot></slot>
                <input type="text" v-model="txt" />
                <slot name="btn" :n="txt"></slot>
            </div>`
        }
        Vue.createApp({
            components: {
                Com
            },
            data() {
                return {
                    str: ""
                }
            },
            methods: {
                receive(n) {  //n通过插槽传过来的值
                    this.str = n;
                }
            }
        }).mount("#box")
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值