第09课:开发进行时之组件开发首页

第09课:开发进行时之组件开发首页

作为一个网站的首页,一般都比较吸引人,内容比较丰富,层次感明显。而一个电商类的网站首页,则是由大量商品内容 + 分类导航 + 各种轮播 + 各种触发显示内容构成。

本篇将告诉你,如何通过 Vue.js 来实现这些功能,你会发现,原来可以这么简单。

案例内容为模仿天猫首页的导航部分结构内容,大家可以对照天猫首页来进行学习。

轮播的实现

轮播是一个网站必备的元素之一,它可以通过控制在一个区域里展示多倍于区域的内容。

轮播的样式有很多,实现也是千差万别,但是核心都是一样的,通过 setInterval 函数来实现周期切换内容。

在原生 JavaScript 中,我们都是提前把轮播图片渲染为多个元素,为每个元素添加跳转,然后通过控制来在这些元素中切换展示内容。

通过 Vue.js,我们来实现一个轮播。

首先我们需要将轮播的样式写好,代码如下。

<div class="carousel_box">//最外层的元素
      <div class="carousel_one">//其中一个轮播图的所在元素
        <img :src="bgImg" alt="" class="carousel_one">//为图片设置样式
      </div>
      <div class="carousel_li_box">//切换按钮区域
        <div v-bind:class="{'carousel_li1': counter==index, 'carousel_li2': counter!=index}" v-for="(item,index) in carouselData"></div>//一个按钮
      </div>
    </div>

然后我们需要一个轮播数据,里面包含轮播的名称、链接的跳转地址、展示的图片路径,除去这些,我们再定义两个数据,一个叫做 bgImg,就是当前展示的图片路径,一个叫做 Counter,充当计数器。 数据结构如下。

data() {
      return {
        bgImg:'../image/index/csdn.jpg',//当前背景图片
        carouselData:[{//轮播数据源
          name:'CSDN',
          url:'https://www.csdn.net',
          img: '../image/index/csdn.jpg',
        },{
          name:'GitHub',
          url:'https://github.com/',
          img:'../image/index/github.jpg',
        },{
          name:'GitChat',
          url:'http://gitbook.cn/',
          img:'../image/index/gitchat.png',
        }],
        counter:0//计数器
      }
    }

当样式与数据都有了,我们就要写方法来实现这个轮播功能了,我们通过 setInterval 函数,来实现周期循环,再利用定义的 counter 计时器来控制当前的内容,我演示的方法就是简单的替换图片内容。因为在 HTML 中,我们使用 :src,为图片绑定了一个变量bgImg,所以我们只需要改变 bgImg 的值就可以实现背景图片的切换。

在之前的代码中, HTML 会根据 carouselData 的数据来渲染出相对应个数的按钮。我们为 bgImg 设置的初识值为 carouselData 数组的第一个,所以对应的 counter 初识值就该是第一个的下标0。当我们点击图片的时候会根据图片对应的地址进行跳转(注意:如果项目采用的是路由跳转,则需要区分你的跳转是站内跳转还是站外跳转,案例中的地址均为站外地址),而当你点击小按钮的时候,则会将图片更改为对应的内容。所以功能将由三个函数实现,分别是循环轮播、页面跳转、手动切换轮播。

runCarousel:function () {//循环轮播
        var that=this;
        setInterval(function () {
          that.counter ++;
          var dataLen=that.carouselData.length;
          if(that.counter==dataLen){//判断如果计数器记录了一个周期之后重置为0
            that.counter=0
          }
          that.bgImg=that.carouselData[that.counter].img;//通过更改bgImg变量来实现图片的更改
        },2000)//每2000毫米执行一次
      },
      pageJump:function () {
        var url=this.carouselData[this.counter].url;
        window.location.href=url//外部链接的跳转(路由跳转的方法将在后面为大家讲解)
      },
      liBtn:function (index) {//小按钮的点击事件,index为渲染数据对应的下标
        this.counter=index;//将计数器的值设置为选中的下标
        this.bgImg=this.carouselData[this.counter].img;//将当前的图片地址设置为数据源中对应的图片
      }

通过上面的代码,你就可以实现一个简单的轮播。你可以根据你的需求,对实现的内容进行修改。

实现轮播的方法可以控制背景图片,也可以控制元素层级,还可以控制元素的位置,选择你需要的方法,加上 CSS 样式,再通过 Vue.js 的做法,你就可以完成一个属于你的轮播。

分页导航

如同天猫首页一般,除去一个大大的轮播,在第一屏的位置还有很多分页导航,如商品分类导航,卖场分类导航,还有顶部的网站导航。

其中头部导航,是整个网站的导航,分别跳转到网站的各个模块。而商品分类导航,则是一个商品分类列表,在鼠标悬浮在某一类的时候为你展示一个更加详细的分类页面,你可以通过这个页面中详细的分类跳转至对应的页面。

说到导航,就涉及到页面跳转,在之前的内容中我们有介绍过,在 Vue.js 中采用脚手架搭建项目,并安装路由模块 vue-router,如果你使用的文件引入的开发方式,那么你则需要通过单独引入 vue-router.js 文件,我们使用 vue-router 来代替传统的页面 a 标签跳转。

我们通过 npm 安装 vue-router 模块之后建立一个 router 文件夹,在其中新建一个 index.js,配置你的路由。

在使用路由的时候我们先需要创建一个 Router 实例,然后在 routes 中对路由进行配置,如下。

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router);
export default new Router({
    // mode: 'history',
    routes: [
        {
            path: '/',
            component: resolve => require(['@/page/index'], resolve),
        },
        {
            path: '/vipmore',
            component: resolve => require(['@/page/vipmore'], resolve)
        },
        {
            path: '/banner',
            component: resolve => require(['@/components/banner'], resolve)
        } 
        ]
})

routes 是一个数组,里面就是你的路由列表,path 是你的访问路径(带/表示根路径),component 则是这条路由映射的组件。

然后你就可以通过路由访问你的组件。比如,通过 router-link 跳转页面。

<router-link to="/">去首页</router-link>
<router-link to="/login">前往登录</router-link>
<router-link to="/product">产品中心</router-link>

或者通过方法来跳转页面。

this.$router.push({path: "/login"});

接下来我们就用 vue-router+组件来完成这个商品分类导航。

首先,我们的商品分类导航是一个列表,所以我们要在 data 中定义一个变量来存放这些分类列表。

data: {
            navList:[{
                name:'女装',
                component:'woman'
            },{
                name:'男装',
                component:'man'
            },{
                name:'鞋子',
                component:'shoes'
            },{
                name:'手表',
                component:'watchs'
            },{
                name:'零食',
                component:'snacks'
            },{
                name:'汽车',
                component:'car'
            }]
        }

然后,我们在路由列表中定义这些分类对应的路由及映射组件。

        routes: [
            {
                path: '/',
                name: 'index',
                component: index
            }, {
                path: '/woman',
                name: 'woman',
                component: woman
            }, {
                path: '/man',
                name: 'man',
                component: man
            }, {
                path: '/man',
                name: 'man',
                component: man
            }, {
                path: '/shoes',
                name: 'shoes',
                component: shoes
            }, {
                path: '/watchs',
                name: 'watchs',
                component: watchs
            }, {
                path: '/snacks',
                name: 'snacks',
                component: snacks
            }, {
                path: '/car',
                name: 'car',
                component: car
            }
        ]

接着,我们在完成对应的组件内容。每一个组件我们都新建一个 vue 页面来完成。

<template>
    <div>

    </div>
</template>
<script>
    export default {
        name: '女装专区',
        ready: function () {
        },
        data () {
            return {

            }
        },
        methods: {

        },
        mounted(){
        }
    }
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

除去跳转的新页面之外,在鼠标悬浮在商品菜单的时候旁边还会跟着悬浮一个详细菜单,对于这样的悬浮内容,我们可以根据需求选择在本页面写,或者用一个独立的组件来完成,再引入到本页面。

对于在一个页面引用的另一个组件,你不需要经过路由列表,只需要在本页面中通过 components 引入就可以了。

    import foot from '../components/foot.vue'
    import headnav from '../components/headnav.vue'
    import rightnav from '../components/rightnav.vue'
    export default {
        name: 'index',
        components: {
            headnav,
            foot,
            rightnav
        }
    }

通过上面的方法引入之后,你就可以在 HTML 代码中直接以标签的形式使用该组件。

<headnav></headnav>

而在这个菜单中隐藏的部分都是具有一定规则,所以即使有多个隐藏模块,但实际上我们只需要写一个模块就可以了。隐藏模块的结构都是一致的,左边菜单,中间对应的是该菜单的内容,右边则是一些品牌的图片。 同样的,我们只需要写一个模块,然后改变其中的填充内容即可。HTML 结构大概长这样:

<div class="nav_box">
    <!--这是整个隐藏模块-->
    <div class="nav_left">
        <!--这是左边的文字区域-->
        <div class="nav_level1">
            <!--这是第一行的菜单-->
            <div class="nav_level1_title"></div>
            <!--这是第一行菜单的标题-->
            <div class="nav_level1_content">
                <!--这是第一行菜单的内容区域-->
                <span class="nav_word">
                    <!--这里就是具体的每一个菜单-->
                </span>
            </div>
        </div>
    </div>
    <div class="nav_right">
        <!--这里是右边的图片区域-->
            <img src="" alt="" class="nav_image">
            <!--这里面就是具体的每一张图片-->
    </div>
</div>

然后我们再来准备这些菜单的数据,一般都是通过交互从后台获取的,在这里我们就直接定义了。

        data: {

            hideNavData:[
                {
                    leftData:[
                        {
                            title:'当季流行',
                            navWord:[
                                {
                                    name:'春季新品',
                                    url:'router1'
                                },
                                {
                                    name:'夏季新品',
                                    url:'router2'
                                },
                                {
                                    name:'秋季新品',
                                    url:'router3'
                                },
                                {
                                    name:'冬季新品',
                                    url:'router4'
                                }
                            ]
                        },
                        {
                            title:'当季流行',
                            navWord:[
                                {
                                    name:'春季新品',
                                    url:'router1'
                                },
                                {
                                    name:'夏季新品',
                                    url:'router2'
                                },
                                {
                                    name:'秋季新品',
                                    url:'router3'
                                },
                                {
                                    name:'冬季新品',
                                    url:'router4'
                                }
                            ]
                        },
                        {
                            title:'当季流行',
                            navWord:[
                                {
                                    name:'春季新品',
                                    url:'router1'
                                },
                                {
                                    name:'夏季新品',
                                    url:'router2'
                                },
                                {
                                    name:'秋季新品',
                                    url:'router3'
                                },
                                {
                                    name:'冬季新品',
                                    url:'router4'
                                }
                            ]
                        }
                    ],
                    rightData:[
                        {
                            img:'https://img.alicdn.com/bao/uploaded/TB1wNJAHFXXXXc7XpXXSutbFXXX.jpg_170x120q30.jpg',
                            url:'shop1'
                        },{
                            img:'https://img.alicdn.com/bao/uploaded/TB1wNJAHFXXXXc7XpXXSutbFXXX.jpg_170x120q30.jpg',
                            url:'shop2'
                        },{
                            img:'https://img.alicdn.com/bao/uploaded/TB1wNJAHFXXXXc7XpXXSutbFXXX.jpg_170x120q30.jpg',
                            url:'shop3'
                        },{
                            img:'https://img.alicdn.com/bao/uploaded/TB1wNJAHFXXXXc7XpXXSutbFXXX.jpg_170x120q30.jpg',
                            url:'shop4'
                        }
                    ]
                }
            ]
        }

上面是其中一组数据,你的菜单有多少列就需要多少组这样的数据。

注意:Vue.js 采用数据驱动,所以很多数据会有多层结构,要使用 Vue.js 就需要对你的数据足够清楚,很多时候都会由于数据的错误造成项目报错。

上面的内容准备好之后,我们就可以开始来完成我们的导航了。

HTML 结构如下代码所示。一个是菜单列表,另一个是隐藏的模块。首先我们通过 v-for 渲染出菜单列表,再将隐藏的模块通过 v-if 来控制。默认状态为不显示。

<div class="nav_list_box">
        <div class="nav_list" v-for="(item,index) in navList" @click="navListClick(index)">{{item.name}}</div>
    </div>
    <div class="hide_nav_box" v-if="hideNavBox=='show'">
        <!--这是整个隐藏模块-->
        <div class="nav_left">
            <!--这是左边的文字区域-->
            <div class="nav_level1" v-if="item in hideNavData.leftData">
                <!--这是第一行的菜单-->
                <div class="nav_level1_title">{{item.title}}</div>
                <!--这是第一行菜单的标题-->
                <div class="nav_level1_content">
                    <!--这是第一行菜单的内容区域-->
                    <span class="nav_word" v-for="words in item.navWord">
                    <!--这里就是具体的每一个菜单-->
                        <router-link :to="'words.url'">{{words.name}}</router-link>
                    </span>
                </div>
            </div>
        </div>
        <div class="nav_right">
            <!--这里是右边的图片区域-->
            <router-link :to="'item.url'" v-for="item in hideNavData.rightData"><img :src="item.img" alt="" class="nav_image"></router-link>
            <!--这里面就是具体的每一张图片-->
        </div>
    </div>

数据除了之前准备的数据再定义一个 hideNavBox,用来控制隐藏模块,默认值设置为 hide。

hideNavBox:'hide'

当你准备好之前的数据与代码并写好 CSS 之后,你会得到这样一个界面。

这时,鼠标悬浮或者点击是会出现隐藏的内容的,接下来我们需要为 nav_list 所在 div 将事件进行完善。

navListClick:function (index) {
    this.data.hideNavBox='show';
    this.hideNavData=this.allData[index]
}

这里的 allData 就是之前定义 hideNavData 的时候说的,你有多少个菜单列表你就需要定义多少个 hideNavData,然后以对象的形式存入 allData 这个数组。

这样当你点击菜单的时候就会将隐藏的模块显示出来,你点击隐藏模块中的菜单或者图片就可以跳往各个页面。

你也可以根据你的需求更改为获得焦点事件或者失去焦点事件。

这样一个菜单模块就完成了,在这个模块中我们已经运用了大多数的 Vue.js 技术,如果你理解通透这块内容,你就可以做完一个首页模块,哪怕我们没有说到的部分,也是通过相同的思路以及技术完成的。

接下来就该你根据我的案例写出你自己的首页了。

上一篇
下一篇
目录