华泰官网--华泰观点底部轮播组件仿写

125 阅读1分钟

学习vue的过程中,用vue仿写一个华泰官网的轮播组件当作业

先分析仿写对象

上一个仿写对象的链接

www.htsc.com.cn/insights

华泰官网👆就是他👆

观察一下他的效果,首先确认的是他是有3个显示的组件,1个隐藏的组件

每个组件构成是上面一长图片,下面一个1行的类型,一个2行的标题,2行的日期,3行的内容,超出显示...

在动画过程的时候最左边的移动移出盒子,右边开始移进来。

整体一个平移的效果大概半秒不到,5秒循环一次

那么接下来开始动手

先把盒子的组件写出来

<template>
    <div class="swiperItem">
        <div class="swiperItemPicture">
            <slot name="img"></slot>
        </div>
        <div class="swiperItemText">
            <div class="type">
                <slot name="type"></slot>
            </div>
            <div class="title">
                <slot name="title"></slot>
            </div>
            <div class="date">
                <slot name="date"></slot>
            </div>
            <div class="text">
                <slot name="text"></slot>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    name:'SwiperItem'
}
</script>

先把每个变量的内容预留出插槽,然后设定好样式

<style>
.swiperItem{
    margin-left: 25px;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    outline: none;    
    background: #fff;

}

.swiperItemPicture img{
    width: 381px;;
    height: 255px;
}         

.swiperItem .swiperItemText{
    -webkit-box-shadow: 0 0 60px 0 rgba(0,0,0,.1);
    box-shadow: 0 0 60px 0 rgba(0,0,0,.1);
    width: 316px;;
    margin-bottom: 35px;
    padding: 32px;

}

.swiperItem .title{
    font-size: 18px;
    font-weight: 400;
    color: #2d5fde;
    line-height: 27px;
    height: 27px;
    margin-bottom: 22px;
    font-weight: 700;
}

.swiperItem .stitle{
    font-size: 22px;
    font-weight: 700;
    color: #333;
    line-height: 40px;
    height: 80px;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -ms-line-clamp: 2;
    -ms-box-orient: vertical;
    -webkit-box-orient: vertical;
    margin-bottom: 13px;
}



.swiperItem .date{
    font-size: 16px;
    color: #999;
    margin-bottom: 13px;
}


.swiperItem .text{
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    overflow: hidden;
    height: 90px;
    line-height: 2;
    line-clamp: 3;
    -ms-line-clamp: 3;
    -ms-box-orient: vertical;
    -webkit-box-orient: vertical;
}
</style>

然后写装这个内容组件的盒子组件

<template>
    <div class="swiperBox">
        <div class="swiper">
            <slot></slot>
        </div>
    </div>
</template>

<script>
export default {

}
</script>

<style>
.swiperBox{
    display: flex;
    align-items:center;
    justify-content:center;
}

.swiper{
    position: relative;
    width: 1290px;
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-transition-property: -webkit-transform;
    transition-property: -webkit-transform;
    -o-transition-property: transform;
    transition-property: transform;
    transition-property: transform,-webkit-transform;
    -webkit-box-sizing: content-box;
    box-sizing: content-box;
    margin-left: 50px;
    overflow: hidden;
    list-style: none;
    margin-bottom: 25px;
    padding: 0;
    z-index: 0;
}
</style>

留一个插槽放内容组件

最后把他们组装起来,加上js效果

<template>
    <div>
        <div class="swiperTitle">
            <h4 class="swiperTitleText">每日一题</h4>
        </div>
        <Swiper-box>
            <div :style="transform">
                <Leetcode-box>
                    <img slot="img" :src="a.url" alt="">
                    <p slot="type">{{a.type}}</p>
                    <p slot="title">{{a.title}}</p>
                    <p slot="date">{{a.date}}</p>
                    <p slot="text">{{a.text}}</p>
                </Leetcode-box>
            </div>
            <div :style="transform">
                <Leetcode-box>
                    <img slot="img" :src="b.url" alt="">
                    <p slot="type">{{b.type}}</p>
                    <p slot="title">{{b.title}}</p>
                    <p slot="date">{{b.date}}</p>
                    <p slot="text">{{b.text}}</p>
                </Leetcode-box>
            </div>
            <div :style="transform">
                <Leetcode-box>
                    <img slot="img" :src="c.url" alt="">
                    <p slot="type">{{c.type}}</p>
                    <p slot="title">{{c.title}}</p>
                    <p slot="date">{{c.date}}</p>
                    <p slot="text">{{c.text}}</p>
                </Leetcode-box>
            </div>
            <div v-show="isShow" :style="transform">
                <Leetcode-box>
                    <img slot="img" :src="d.url" alt="">
                    <p slot="type">{{d.type}}</p>
                    <p slot="title">{{d.title}}</p>
                    <p slot="date">{{d.date}}</p>
                    <p slot="text">{{d.text}}</p>
                </Leetcode-box>
            </div>
        </Swiper-box>
    </div>
</template>

<script>
import LeetcodeBox from '../study/LeetcodeBox';
import SwiperBox from '../study/SwiperBox.vue';
export default {
  components: { SwiperBox, LeetcodeBox },
    data(){
        return {
            a:{},
            b:{},
            c:{},
            d:{},
            list:[
                {
                url:require('../../assets/pbg/TB1.png'),
                type:'每日温度,解题思路:栈,难度:中等',
                title:'请根据每日气温列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。',
                date:'2021-01-24',
                text:`维护一个存储下标的单调栈,从栈底到栈顶的下标对应的温度列表中的温度依次递减。如果一个下标在单调栈里,则表示尚未找到下一次温度更高的下标。正向遍历温度列表。对于温度列表中的每个元素 T[i],如果栈为空,则直接将 i 进栈,如果栈不为空,则比较栈顶元素 prevIndex 对应的温度 T[prevIndex] 和当前温度 T[i],如果 T[i] > T[prevIndex],则将 prevIndex 移除,并将 prevIndex 对应的等待天数赋为 i - prevIndex,重复上述操作直到栈为空或者栈顶元素对应的温度小于等于当前温度,然后将 i 进栈。为什么可以在弹栈的时候更新 ans[prevIndex] 呢?因为在这种情况下,即将进栈的 i 对应的 T[i] 一定是 T[prevIndex] 右边第一个比它大的元素,试想如果 prevIndex 和 i 有比它大的元素,假设下标为 j,那么 prevIndex 一定会在下标 j 的那一轮被弹掉。由于单调栈满足从栈底到栈顶元素对应的温度递减,因此每次有元素进栈时,会将温度更低的元素全部移除,并更新出栈元素对应的等待天数,这样可以确保等待天数一定是最小的。`
                },
                {
                url:require('../../assets/pbg/TB2.png'),
                type:'整数拆分,解题思路:动态规划,数学,难度:中等',
                title:'给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。',
                date:'2021-01-22',
                text:``
                },
                {
                url:require('../../assets/pbg/TB3.png'),
                type:'合并二叉树,解题思路:深度优先搜索,广度优先搜索,难度:简单',
                title:'给定两个二叉树,想象当你将它们中的一个覆盖到另一个上时,两个二叉树的一些节点便会重叠。你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠,那么将他们的值相加作为节点合并后的新值,否则不为 NULL 的节点将直接作为新二叉树的节点。',
                date:'2021-01-23',
                text:'深度优先搜索,广度优先搜索'
                },
                {
                url:require('../../assets/pbg/TB4.png'),
                type:' 二叉树的最小深度,解题思路:广度优先搜索,难度:简单',
                title:'给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的最短路径上的节点数量。说明:叶子节点是指没有子节点的节点。',
                date:'2021-1-22',
                text:`广度优先搜索,遍历整棵树。当我们找到一个叶子节点时,直接返回这个叶子节点的深度。广度优先搜索的性质保证了最先搜索到的叶子节点的深度一定最小。`
                },
            ],
            transform:'',
            //控制是否需要动画的css变量,在隐藏和交换内容的时候不需要过度,在平移的时候需要设置内容
            isShow:false
            //在动画开始之前和动画结束之后,让第四个组件隐藏,调整动画效果需要
        }
    },
    methods:{
        swipe(){            
            setTimeout(() => {
                this.a = this.list[0]
                this.b = this.list[1]
                this.c = this.list[2]
                this.d = this.list[3]
                this.isShow = false
                this.transform = ''
            },);
            setTimeout(() => {
                this.isShow = true
            },4640); 
            setTimeout(() => {
                this.transform = 'transform: translate(-406px, 0px); transition: all 0.3s'
            },4660);
            setTimeout(() => {
                this.a = this.list[1]
                this.b = this.list[2]
                this.c = this.list[3]
                this.d = this.list[0]
                this.isShow = false
                this.transform = ''
            },5000);
            setTimeout(() => {
                this.isShow = true
            },9640); 
            setTimeout(() => {
                this.transform = 'transform: translate(-406px, 0px); transition: all 0.3s'
            },9660);
            setTimeout(() => {
                this.a = this.list[2]
                this.b = this.list[3]
                this.c = this.list[0]
                this.d = this.list[1]
                this.isShow = false
                this.transform = ''
            },10000);
            setTimeout(() => {
                this.isShow = true
            },14640); 
            setTimeout(() => {
                this.transform = 'transform: translate(-406px, 0px); transition: all 0.3s'
            },14660);
            setTimeout(() => {
                this.a = this.list[3]
                this.b = this.list[0]
                this.c = this.list[1]
                this.d = this.list[2]
                this.isShow = false
                this.transform = ''
            },15000);
            setTimeout(() => {
                this.isShow = true
            },19640); 
            setTimeout(() => {
                this.transform = 'transform: translate(-406px, 0px); transition: all 0.3s'
            },19660);
        },

    },
    mounted(){
        this.swipe()
        setInterval(() => {
            this.swipe()},20000)
    }
}
</script>

<style>
.swiperTitle{
    font-size: 36px;
    font-weight: 700;
    line-height: 1;
    text-align: center;
    margin-bottom: 75px;
    -webkit-tap-highlight-color: rgba(0,0,0,0);
}
</style>

这样就写完了

还有跳转的方法和链接,和调接口获取内容的,补上就可以放到自己的博客上用了