updated钩子函数实例化多次的问题

标签: vue

继上篇文章继续补充一下

上一篇:添加链接描述

  • 当我们的轮播需要添加 swiper-pagination 时,并且 添加一个数据双向绑定的 input 时, 我们会发现在我们改变 input 框里面的 value 时,我们的 swiper-pagination 按钮就不起作用了,原因是 updated 钩子函数被实例化多次
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./base/swiper.min.css">
</head>
<body>
    <div id="app">
        
        <my-banner></my-banner>
    </div>

    <!--创建模板-->
    <template id="my-banner">
        <div class="swiper-container">
            <div class="swiper-wrapper">
                <div 
                    class="swiper-slide"
                    v-for="banner in banners"
                >
                    <img width="100%" :src="banner.image" alt="">
                </div>
            </div>
			<div class="swiper-pagination"></div>
			<input type="text" v-model="msg">
			<p id="p">我是p标签 {{msg}}</p>
        </div>
    </template>

    <script src="./base/swiper.min.js"></script>
    <script src="./base/vue.js"></script>
    <script src="https://cdn.bootcss.com/vue-resource/1.5.0/vue-resource.min.js"></script>
    <script>

        
        Vue.component("my-banner",{
            template:"#my-banner",
            data(){
                return {
                    banners:[],
					 msg:""
                }
            },
            created(){
                this.$http.get("./banners.json").then(res=>{ //1000s之后
                    // console.log(res.data.bannerList)
                    this.banners = res.data.bannerList
                })
            },
    
               updated(){
                    new Swiper(".swiper-container",{
                        loop:true ,
						pagination:{
						    el:".swiper-pagination"
						}
                    })
                }


        })

        new Vue({
            el:"#app"
        })
    </script>


</body>
</html>
  • 当我们不改变 input 里的 value 时 ,我们的轮播图还是能正常滑动的
    在这里插入图片描述
  • 当我们改变 input 的 value 时,我们 swiper-pagination 就不起作用了
    在这里插入图片描述

所以我们可以让 updated 钩子函数只实例化一次就可以了

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!--引入swiper的样式结构-->
    <link rel="stylesheet" href="./base/swiper.min.css">
</head>
<body>
    
    <div id="app">
        <!--调用my-banner组件-->
        <my-banner></my-banner>
    </div>

    <!--创建模板-->
    <template id="my-banner">
        <div class="swiper-container">  
            <div class="swiper-wrapper">
                <div 
                    class="swiper-slide"
                    v-for="banner in banners"
                >
                    <img width="100%" :src="banner.image" alt="">
                </div>
            </div>
            <div class="swiper-pagination"></div>
            <input type="text" v-model="msg">
            <p id="p">我是p标签 {{msg}}</p>
        </div>
    </template>

    <!--Swiper-->
    <script src="./base/swiper.min.js"></script>
    <script src="./base/vue.js"></script>
    <script src="https://cdn.bootcss.com/vue-resource/1.5.0/vue-resource.min.js"></script>
    <script>

        //创建组件
        Vue.component("my-banner",{
            template:"#my-banner",  
            data(){
                return {
                    banners:[],
                    msg:""
                }
            },
           
            created(){
                console.log("created.....")
                this.$http.get("./banners.json").then(res=>{ 
                   
                    this.banners = res.data.bannerList
         })
            },
 updated(){
                if(!this.swiper){
                    this.swiper = new Swiper(".swiper-container",{
                        loop:true,
                        pagination:{
                            el:".swiper-pagination"
                        }
                    })
                }
            }
        })

        new Vue({
            el:"#app"
        })
    </script>
</body>
</html>

关于这个问题 Vue 中提供了 Vue.nextTick / this.$nextTick 解决方案

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./base/swiper.min.css">
</head>
<body>
    <div id="app">
        
        <my-banner></my-banner>
    </div>

    <!--创建模板-->
    <template id="my-banner">
        <div class="swiper-container">
            <div class="swiper-wrapper">
                <div 
                    class="swiper-slide"
                    v-for="banner in banners"
                >
                    <img width="100%" :src="banner.image" alt="">
                </div>
            </div>
			<div class="swiper-pagination"></div>
			<input type="text" v-model="msg">
			<p id="p">我是p标签 {{msg}}</p>
        </div>
    </template>

    <script src="./base/swiper.min.js"></script>
    <script src="./base/vue.js"></script>
    <script src="https://cdn.bootcss.com/vue-resource/1.5.0/vue-resource.min.js"></script>
    <script>

        
        Vue.component("my-banner",{
            template:"#my-banner",
            data(){
                return {
                    banners:[],
					 msg:""
                }
            },
            created(){
                this.$http.get("./banners.json").then(res=>{ 
                   
                    this.banners = res.data.bannerList
					
					
					
					this.$nextTick(()=>{
					   
					    new Swiper(".swiper-container",{
					        loop:true,
					        pagination:{
					            el:".swiper-pagination"
					        }
					    })
					})
                  
                })
            },
     })

        new Vue({
            el:"#app"
        })
    </script>


</body>
</html>

在这里插入图片描述

版权声明:本文为html_996原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/html_996/article/details/105103343