marqueeCom.vue 6.69 KB
<template>
    <div class="marquee-com" v-if="lists && lists.length">
        <div class="box" ref="marqueesBox">

            <!-- 判断是否有Clone数组 -->
            <template v-if="listsClone && listsClone.length">

                <!-- 循环输出列表 -->
                <div class="item" ref="items" v-for="(item, index) in listsClone" :key="index">

                    <!--
                        com=1:goodsItem_1组件,pid:1、3,固定不滚动;2、4,滚动
                            事件:
                                @jump:整个点击跳转事件
                                @addCart:右下角加入购物车按钮事件,已阻止事件冒泡

                        com=2:goodsItem_2组件,pid: 1,带标题,不显示附加信息;2、不带标题,显示附加信息
                            事件:
                                @jump:整个点击跳转事件

                        com=3:goodsItem_3组件,无pid参数
                            事件:
                                @jump:整个点击跳转事件
                                @primary:右下角红色主按钮点击事件,已阻止事件冒泡

                        com=10:goodsItem_10组件,pid: 1,价格,原价;2、积分信息
                            事件:
                                @jump:整个点击跳转事件
                        
                        -->

                    <!-- 商品展示样式 1 -->
                    <goods-item-1 v-if="com == '1'" @jump="jump" @addCart="addCart"
                        :item="item"
                        :pid="pid">
                    </goods-item-1>

                    <!-- 商品展示样式 2 -->
                    <goods-item-2 v-if="com == '2'" @jump="jump"
                        :item="item"
                        :pid="pid">
                    </goods-item-2>

                    <!-- 商品展示样式 3 -->
                    <goods-item-3 v-if="com == '3'" @jump="jump" @primary="primary"
                        :item="item">
                    </goods-item-3>

                    <!-- 商品展示样式 10 -->
                    <goods-item-10 v-if="com == '10'" @jump="jump"
                        :item="item"
                        :pid="pid">
                    </goods-item-10>
                </div>
            </template>
        </div>
    </div>
</template>

<script>

    // 引入组件
	import goodsItem1 from "@/components/goodsItem_1/goodsItem_1";
	import goodsItem2 from "@/components/goodsItem_2/goodsItem_2";
	import goodsItem3 from "@/components/goodsItem_3/goodsItem_3";
	import goodsItem10 from '@/components/goodsItem_10/goodsItem_10';

    export default {
        name : 'marqueeCom',
        props: ['lists', 'com', 'pid', 'options'],
        data () {
            return {
                listsClone: []      // lists深度拷贝对象
            }
        },
        components: {
            goodsItem1,
			goodsItem2,
			goodsItem3,
			goodsItem10
        },
        methods: {

            /**
             * 跑马灯无限循环移动函数
             * @param {Object} itemWidth [元素宽度,用户处理添加/删除元素逻辑]
             * @param {Object} marqueesBox [列表元素DOM对象]
             */
            move(itemWidth, marqueesBox) {
                
                // 位移量
                let distance = 0;

                // 追加第几个数组数据下标
                let sub = null;

                // 检查配置选项,设置轮训时间
                let timer = (this.options && this.options.timer && this.options.timer > 0) ? this.options.timer : 30;

                // 设置位移
                let interval = setInterval(() => {
                
                    // 计算位移量
                    distance = distance - 1;

                    // 向左移动
                    marqueesBox.style.transform = 'translateX(' + distance + 'px)';

                    // 判断添加/删除元素
                    if (!(distance % itemWidth)) {

                        // 判断应该追加第几个数组数据下标
                        if (!sub) {
                            sub = 0;
                        }

                        // 追加数据到listsClone数组
                        this.$set(this, 'listsClone', [...this.listsClone, ...[this.lists[sub]]]);

                        // 判断数组下标是否越界
                        if (sub < this.lists.length - 1) {
                            sub++;
                        } else {
                            sub = 0;
                        }
                    }
                }, timer);
            },

			/**
			 * 点击跳转
			 * @param {object} item [数据对象]
			 */
			jump(item) {
				this.$emit("jump", item);
			},
			
			/**
			 * 加入购物车
			 * @param {object} item [数据对象]
			 */
			addCart(item) {
				this.$emit("addCart", item);
			},

			/**
			 * 主按钮点击事件
			 * @param {object} item [数据对象]
			 */
			primary(item) {
				this.$emit("primary", item);
			}
        },
        mounted() {
            
            // 下一周期执行
            this.$nextTick(() => {

                // 深度拷贝数组
                this.$set(this, 'listsClone', this.lists.slice(0)); 

                // 检查配置选项
                let minCount = (this.options && this.options.minCount && this.options.minCount > 0) ? this.options.minCount : 5;

                // 判断列表项目是否 >= 5项,如果不足,不全列表项
                while(true) {

                    if (this.listsClone && this.listsClone.length >= minCount) {
                        break;
                    }

                    // 向尾部追加数据(克隆数据,prop数据不能追加数组)
                    this.$set(this, 'listsClone', [...this.listsClone, ...this.listsClone]);
                }

                // 下一周期执行
                this.$nextTick(() => {

                    // 获取item宽度
                    let itemWidth = this.$refs.items[0].clientWidth;

                    // 判断是否获取到item宽度
                    if (itemWidth) {

                        // 延时2秒再开始滚动
                        setTimeout(() => {
                            
                            // 跑马灯无限循环移动函数
                            this.move(itemWidth, this.$refs.marqueesBox);
                        }, 2000);
                    }
                });
            });
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style rel="stylesheet/less" lang='less' scoped>
    @import "marqueeCom";
</style>