• Vue实现音乐播放器(七):轮播图组件(二)


    轮播图组件

    <template>
        <div class="slider" ref="slider">
            <div class="slider-group" ref="sliderGroup">
        //这里的<slot></slot>插槽表示里面的内容可以由引用这个轮播图组件的推荐组件来插入  只需要在<slider></slider>标签里面插入内容就可以把slot标签替换掉
                <slot></slot>
            </div>
            <div class="dots">
               
            </div>
        </div>
    </template>

    推荐页面组件

    <template>
        <div class="recommend">
            <div class="recommend-content">
                <!-- 因为我们的recommend是通过异步拿到的 可能会有延时 但是如果不加上v-if的话 我们可能在没有拿到数据的情况下就
                    把插槽插入进去了 那么slider.vue里面的mounted()也就执行了
                -->
                <div class="slider-wrapper" v-if="recommend.length">
                    <slider>
                        <!-- 填写插槽 -->
                        <div v-for="(item,index) in recommend" :key="index">
                            <a :href="item.linkUrl">
                                <img :src="item.picUrl">
                            </a>
                        </div>
                    </slider>
                </div>
                <div class="recommend-list">
                    <h1 class="list-title">热门歌单推荐</h1>
                    <ul></ul>
                </div>
            </div>
        </div>
    </template>
    <script>
    
        import Slider from '../../base/slider/slider.vue'
        import {getRecommend} from '../../api/recommend.js'
        import { ERR_OK } from '../../api/config.js'
    
    export default {
        data(){//为了将实例里面的轮播图数据与dom相关  要有一个data()方法
            return {
                recommend:[]
            }
    
        },
        created(){//一般在这个生命钩子里面加载数据
            this._getRecommend()
        },
        methods:{
            _getRecommend(){
                getRecommend().then((res)=>{//这个res就是我们抓取到的数据对象 因为getRecommend()方法返回的是一个promise对象  如果promise对象里面执行resolve()成功了 那么就会执行then里面的方法
                    if(res.code===ERR_OK){
                        // console.log(res.data.slider)
                        this.recommend=res.data.slider
                    }
                })
    
                }
            },
        components:{
         //注册轮播图组件
            Slider
        }
    }
    </script>

    轮播图组件

    <script>
    
     
    
    //引入better-scroll插件
    import BScroll from 'better-scroll'
    
    //引入的这个方法是判断元素有没有传入该方法的类名  如果有的话就直接返回 如果没有的话就加上该类名 在轮播图组件中  添加的类名是.slider-item 这个类名的作用是让轮播图浮动 在一行显示    
    import {addClass} from '../../common/js/dom.js'
    
    export default {
        data(){
            return {
               dots:[],//页面上的小点  将实例里面的dots数据与dom相关 需要有data方法  
    
                //定义当前是第几页
                currentPageIndex:0    
            }
        },
        props:{
            loop:{
                type:Boolean,
                default:true
            },
            autoPlsy:{
                type:Boolean,
                default:true
            },
            interval:{//设置轮播时间间隔
                type:Number,
                default:4000
            }
        },
    
        //什么时候初始化better-scroll呢?
        //如果better-scroll插件有问题可能是渲染时间(如数据还没加载完页面就渲染了)或者页面高度和宽度不对
        //所以我们要在mouted()中调用获取轮播图
    
        mounted(){
    
            //知识点:通常我们要保证dom成功渲染的时候可以加个延时 
            //可以用this.nextstick()
            //也可以用setTineout()
    
            setTimeout(()=>{//可以延迟20ms 因为一般浏览器加载需要17ms
                this._setSliderWidth(); //设置轮播图的宽高等数据
    
                // 这里要在前面渲染好  不然后面获取到的小圆点的数量就是已经经过better-scroll插件复制过的数目
    
                this._initDots();
                this._initSlider();
                
            },20)
    
            //因为上面有个插槽slot在recommend.vue中插入数据 能够在slider.vue组件中渲染出来
            //因为我们mouted()里面的方法是异步的 所以可能在操作dom的时候还没有渲染出来  浏览器就操作了
            //所以我们在这里加个延时 就可避免此问题
    
            //我们还要思考一个问题:就是我们mounted()的时候 slot里面的元素有没有 在推荐组件里面判断一下v-if="recommend.length"即可
        
    },
        methods:{
            _setSliderWidth(){
           
            //获取页面的dom元素的方法  this.$refs.名字
    
                this.children=this.$refs.sliderGroup.children
                let width=0
                let sliderWidth=this.$refs.slider.clientWidth
                console.log('sliderWidth',sliderWidth);//375
                for(let i=0;i<this.children.length;i++){
                    let child=this.children[i];
                    //给每一个dom元素添加类名为slider-item
                    addClass(child,'slider-item')
    
                    //设置每一个child的宽度  每个child的宽度就等于总容器的宽度
                    child.style.width=sliderWidth+'px'
    
                    //总的图片的宽度 这里后面一定不能加上'px'了  否则就是字符串的相加了
                    //就拿不到正确的数值了
                    width+=sliderWidth
        
                    // console.log('width',width)
                     
                }
    
                if(this.loop){//如果要做到无缝滚动的话 其实是在两侧加上了两张图片的宽度
                            //所以总的宽度就等于width+=2*sliderWidth  因为这里是用
                            //let 声明的child  考虑到作用域问题  所以在{}用2倍的sliderWidth比较合适
                            //sliderWidth就等于每张图片的宽度
    
                    width+=2*sliderWidth;
                   
                }
    
                this.$refs.sliderGroup.style.width=width+'px'
                // console.log(this.$refs.sliderGroup)
                console.log('width....',width)
                
            },
            //初始化轮播图
            _initSlider(){
                this.slider=new BScroll(this.$refs.slider,{
                   scrollX:true,
                   scrollY:false,
                   momentum:false,
                   snap: {
                        loop: this.loop,
                        threshold: 0.3,
                        speed: 400
                   }
                })
            },
    
            //初始化dots
            _initDots(){
                this.dots=new Array(this.$refs.sliderGroup.children.length)
            }
        }
    }
    </script>
  • 相关阅读:
    基础理论:多线程、多进程、并行、并发
    Node: 使用nvm切换node版本
    python: is 和 == 的区别
    React:TypeError: Cannot read properties of undefined (reading 'map')
    pycharm: 注释自动生成
    前端包管理工具概览
    UE4蓝图学习
    mysql kill process解决死锁
    【分享】VCK190 PCIe QDMA 通用数据传输参考设计
    对Linux kernel代码格式重排后编译失败
  • 原文地址:https://www.cnblogs.com/catbrother/p/9180870.html
Copyright © 2020-2023  润新知