• vue(插槽slot、keep-alive、动画transition、transition-group)


    插槽

    占位符<slot></slot>,这是vue封装的标签,在<组件名></组件名>中间写内容,就会显示在slot标签中

    普通插槽

    <div id="App">
            <a-comp>
                <div>这是普通插槽</div>
            </a-comp>
     </div>
     <script>
             Vue.component("aComp", {
                template: `<div>这是组件a<slot></slot><slot></slot></div>`
            })
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    出现几个slot标签,就会出现几次子组件的内容

    具名插槽/命名插槽

    在slot标签上添加name属性,在template标签上对应使用v-slot,注意templat标签我们写在组件标签之中,另外代码不全,看个格式就好了

    <div id="App">
            <b-comp>
            <!-- 给template标签使用v-slot -->
                <template v-slot:names>
                    <div>
                        这是具名插槽/命名插槽
                    </div>
                </template>
            </b-comp>
     </div>
     <script>
            Vue.component("bComp", {
                template: `<div>这是组件b<slot name="names"></slot></div>` // 给slot添加name属性
            })
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    作用域插槽

    作用域插槽其实与具名插槽是相对比较接近的,同样是要给slot标签添加name属性,并且在template标签中通过v-slot找到相应的占位符,但是作用域插槽,在创建组件的时候,将一些变量绑定在了组件上(类似父组件变量传递给子组件),给v-slot再添加一个参数,而这个参数能够找到这个组件的绑定的所有变量(使用这些变量时不需要props去接收变量,直接调用就可以),能够以对象的形式将所有变量呈现出来,当然也可以只让自己需要的变量呈现出来

    <div id="App">
            <c-comp>
                <template v-slot:names2="items">
                    作用域插槽
                    <div>
                        {{items}}
                        <br>
                        {{items.name1}}--{{items.sex1}}--{{items.age1}}    
                    </div>
                </template>
            </c-comp>
     </div>
     <script>
            Vue.component("cComp", {
                template: `<div>这是组件c<slot name="names2" :name1="name" :sex1="sex" :age1="age"></slot></div>`,   // 将变量传递给子组件
                data() {
                    return{
                        name:"李太白",
                        sex:"男",
                        age:"几百岁"
                    }
                }
            })
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    keep-alive

    keep-alive也是vue封装的标签,当我们从一个组件跳转到另一个组件时,要经历六个钩子(六个生命周期),前一个组件的销毁前后,以及后一个组件的创建前后和挂载前后。跳转以后,数据会被重置,。keep-alive就能够实现多次进入组件,不触发销毁和渲染的钩子,也就是说,keep-alive可以解决组件重复执行,就会重置数据的问题,从而提高渲染的效率,解决缓存问题

    使用方法:使用<keep-alive></keep-alive>将动态组件包起来,这样无论多少次重复切换组件,都不会销毁它们留下来的数据了,案例如下:

        <div id="app">
            <button @click="vehicle='acomp'">火箭</button>
            <button @click="vehicle='bcomp'">轮船</button>
            <!-- 使用keep-alive包着,多次进入组件,不会触发销毁和渲染的钩子函数 -->
            <keep-alive>    
                <component :is="vehicle"></component>
            </keep-alive>
    
        </div>
        <script>
            new Vue({
                el: '#app',
                data() {
                    return {
                        vehicle:'acomp'
                    }
                },
                methods: {
    
                },
                components:{
                    acomp:{
                        template:`<div>火箭上升{{meter}}米 <button @click="meter++">点击发射</button></div>`,
                        data(){
                            return{
                                meter:10
                            }
                        },
                    },
                    bcomp:{
                        template:`<div>轮船向前{{meter}}米 <button @click="meter++">点击前进</button></div>`,
                        data(){
                            return{
                                meter:20
                            }
                        }
                    },
                }
            });
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    总结,如果不使用keepalive标签将动态组件进行一个包裹,我们每一次切换,到火箭组件时总是会显示10米,到轮船组件时总是会显示20米,而通过keepalive可以将数据放入到缓存中,这样每次再进行切换时,都是会显示你刚刚设置的数字


    在keepalive标签上还有两个属性:include和exclude

    • include 当动态组件中包含了很多的组件时,而你只想让某一个或几个组件的数据能进行缓存,那么就可以使用include属性了,只要将你希望缓存数据的组件名写在include后(include=“组件名,组件名2”),该组件的数据就会进入缓存,而其他的组件不会进行缓存了
    • exclude 当动态组件中包含了很多的组件,而你只想让某一个或者几个组件的数据不进行缓存,那么就可以将这些组件名写在exclude后,这些组件就不会进行缓存,而其他的组件会进行缓存
            <keep-alive include="acomp">    
                <component :is="vehicle"></component>
            </keep-alive>
    
    • 1
    • 2
    • 3

    keepalive还有两个钩子函数:activated和deactivated

    • activated 单独设置某个变量,手动初始一个变量,相当于替代created(创建后)和mounted(挂载后)两个钩子
    • deactivated 手动修改需要修改的值,相当于替代destroyed(销毁后)

    通俗易懂地来说就是,activated是在页面加载前进行操作,这时我们可以将一个变量进行赋值,等到页面加载完了,这个变量显示的就是我们设置的值。deactivated是在我们切换组件后或者要销毁数据后进行的操作,我们此时也可以将变量设置一个值,这也相当于初始化一个值,当我们下次再进入这个组件时,就会显示我们设置的值

    案例,我们可以在刚刚的火箭和轮船的案例中添加一段代码

               components:{
                    acomp:{
                        template:`<div>火箭上升{{meter}}米 <button @click="meter++">点击发射</button></div>`,
                        data(){
                            return{
                                meter:10
                            }
                        },
                        // 离开此组件,对meter变量进行设置
                        deactivated() {
                            this.meter=50
                            alert("离开"+this.meter)
                        },
                    },
                    bcomp:{
                        template:`<div>轮船向前{{meter}}米 <button @click="meter++">点击前进</button></div>`,
                        data(){
                            return{
                                meter:20
                            }
                        },
                        // 进入该组件对meter变量进行设置
                        activated() {
                            this.meter=30
                            alert("进入"+this.meter)
                        },
                    },
                }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    vue动画

    vue动画是通过css,赋予动画效果
    我们有两组动画,一组是进入页面的动画enter,还有一种是离开页面的动画leave
    enter中分为了

    • v-enter 元素进入页面前的初始状态
    • v-enter-active 元素正在进入页面,一般这里我们写动画时间,可以使用transition过渡效果来设置
    • v-enter-to 元素进入页面后进行的动画
      leave中分为了
    • v-leave 元素离开页面前的初始状态
    • v-leave-active元素正在离开页面,一般这里我们写动画时间,可以使用transition过渡效果来设置
    • v-leave-to 元素开始离开页面进行的动画

    这些属性不是写在js中,而是以类名的方式写在css中

            .v-enter{
                /* 初始状态 */
                transform: translateX(200px);
            }
            .v-enter-active{
                /* 动画时间 */
                transition: all 1s;
                /* 开始动画时的背景色 */
                background-color: yellowgreen;
            }
            .v-enter-to{
                /* 进行的动画 */
                background-color: antiquewhite;
            }
            .v-leave{
                /* 离开时的状态 */
            }
            .v-leave-active{
                transition: all 1s;
            }
            .v-leave-to{
                opacity: 0;
                transform: translateX(-200px);
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    vue中动画也封装了相应的标签transition,只要用transition标签将需要设置动画的元素包起来,就可以了

    <div id="app">
            <button @click="flag=!flag">点击</button>
            <transition>
                <div class="box" v-show="flag"></div>
            </transition>
        </div>
        <script>
            new Vue({
                el: '#app',
                data() {
                    return {
                        flag:true
                    }
                },
                methods: {
    
                },
                components:{
                    box:{
                        template:`<div class="box"></div>`
                    }
                }
            });
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    注意,这个案例在使用前,要先将box设置一个样式

    自定义动画

    自定义动画与之前的基本没有区别,只是自定义动画,要给transition标签添加一个name属性,为这个动画设置一个自定义名称标识,然后设置动画时,以这种格式来写即可

    .自定义名称标识-enter{
                /* 初始状态 */
                transform: translateX(200px);
            }
    
    • 1
    • 2
    • 3
    • 4

    列表动画

    列表动画与之前的动画差别也不大,只是使用transition-group标签替代了transition标签,而其他的动画设置没有改动。另外transition-group标签默认渲染为span标签,我们可以通过tag属性来修改transition-group渲染出来的标签。
    css代码

                    .v-enter{
                /* 初始状态 */
                transform: translateX(200px);
            }
            .v-enter-active{
                /* 动画时间 */
                transition: all 1s;
            }
            .v-leave-active{
                transition: all 1s;
            }
            .v-leave-to{
                opacity: 0;
                transform: translateX(-200px);
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    js代码

    <div id="app">
            <button @click="add" style="width:200px">添加</button>
            <transition-group tag="ul">
            <li v-for="(r,i) in dataList" :key="r.id">{{i+1}}-- {{r.name}}--{{r.sex}} <button @click="del(i)">删除</button></li>
            </transition-group>
        </div>
        <script>
            new Vue({
                el: '#app',
                data() {
                    return {
                        dataList : [
                            {
                                name:"李白",
                                sex:"男",
                                id:1
                            },
                            {
                                name:"李清照",
                                sex:"女",
                                id:2
                            },
                            {
                                name:"李商隐",
                                sex:"男",
                                id:3
                            },
                        ]
                    }
                },
                methods: {
                    del(e){
                        this.dataList.splice(e,1)
                    },
                    add(){
                        this.dataList.push({name:"李白",
                                sex:"男",
                                id:1})
                    }
                }
            });
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    我们还可以给transition标签和transition-group标签添加一个appear属性,这样我们刚进入页面时,就会默认执行一次动画

    半场动画

    我们完整的一个动画是,入场加上出场动画,而半场动画就是指单独的入场或者离场动画,我们要实现半场动画就要使用钩子函数。

    • 入场的钩子
      - before-enter 进场之前
      - enter 过渡中
      - after-enter 过渡之后
      - enter-cancelled 过渡打断

    • 出场的钩子
      - before-leave 离开之前
      - leave 过渡中
      - after-leave 离开之后
      - leave-cancelled 过渡打断

    这些钩子的使用方法类似于组件通信中子组件传递变量给父组件的操作,要在transition标签上使用@绑定这些钩子,然后在methods中进行声明
    css代码

            .box{
                width: 100px;
                height: 100px;
                background-color: #f0f;
                border-radius: 50%;
            }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    html、js代码

    <div id="app">
            <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter" appear>
            <div class="box"></div>
            </transition>
        </div>
        <script>
            new Vue({
                el: '#app',
                data() {
                    return {
    
                    }
                },
                methods: {
                    beforeEnter(el) {
                        console.log(el);   // 获取到.box元素,我们就可以对.box元素进行操作了
                        el.style.transform="translate(100px,100px)"    // 设置初始的状态
                    },
                    enter(el,done){
                        el.offsetWidth;   // 刷新动画 没有实际作用但是必须要加这个代码
                        el.style.transform="translate(200px,200px)";
                        el.style.transition="all 1s";
                        done()    // 必须要加上这一步,afterEnter才会执行
                    },
                    afterEnter(el){
                        el.style.opacity=0   // 元素最终的状态
                    },
                }
            });
        </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    总结

    今天学习了四个vue封装的标签:slot、keep-alive、transition、transition-group
    slot是一个占位符,是我们插槽时使用的,当组件加入到#App的div中,正常我们在组件标签中添加内容是不会显示的,但如果组件的template中有slot标签,那么我们在组件标签中添加的内容就可以显示了。这就是插槽,插槽还分为了具名插槽和作用域插槽
    keep-alive是用于处理组件跳转时,管理组件数据的标签,可以让组件的变量进入缓存,也可以让组件的变量不要进入缓存
    transition是进行动画的标签,谁要进行动画,谁就放在transition标签中
    transition-group是表格动画的标签,而且transition-group是可以通过tag属性,修改成其他标签的

  • 相关阅读:
    PLC模拟量输入 模拟量转换FB S_ITR(三菱FX3U)
    Cobalt Strike 注入msf会话
    【STL】容器遍历:std::for_each例子
    洛谷P4213 杜教筛模板
    Windows服务器获取本地文件夹文件
    Java真的不难(四十六)Spring Boot的入门
    开源相机管理库Aravis例程学习(四)——multiple-acquisition-signal
    Session的使用
    Docker-微服务项目部署
    python 文件操作
  • 原文地址:https://blog.csdn.net/m0_66970189/article/details/125503614