首页开发

App.vue 作为入口组件,打开 App.vue,删掉系统创建的代码,只需要保留 router-view 即可,router-view 显示的内容由路由匹配规则决定,代码如下。

import Vue from 'vue';
import Router from 'vue-router';
// 1. 引入首页文件
import index from '../views/index';

Vue.use(Router);

export default new Router({
  routes: [
    {
      // 2. 当为根路径时,显示首页组件
      path: '/',
      name: 'index',
      component: index
    }
  ]
});

在 src 目录下创建 views 文件夹,用于存放网站页面,在 views 目录下新建 index 文件夹,存放首页文件,在 index 文件夹下新建 index.vue,如图 11-4 所示。

image 2025 02 11 19 43 40 968
Figure 1. 图11-4 创建index.vue

修改路由匹配规则,当路径为根路径时,显示 index.vue,代码如下。

<template>
  <div id="app">
    <!-- <router-view/> 中的内容是变化的,需要根据路由匹配规则显示-->
    <router-view />
  </div>
</template>

<script>
export default {
  name: 'App'
};
</script>

<style scoped>
</style>

进入 views/index/index.vue 进行页面布局。

布局分析:根据效果图发现,首页和全部产品页面的头部及导航菜单不变,变化的是导航菜单下方的内容,这种效果可以使用嵌套路由实现,先布局头部和导航菜单部分,代码如下。

<template>
  <div>
    <div class="header">
      <div class="content">
        <img src="../../assets/images/logo.jpg" class="logo" />
        <img src="../../assets/images/ad_top.jpg" class="ad_top" />
      </div>
    </div>
    <div class="menu">
      <div class="content">
        <ul>
          <li class="bg_active">首页</li>
          <li>全部产品</li>
        </ul>
      </div>
    </div>
    <!--导航以下使用嵌套路由-->
    <router-view></router-view>
  </div>
</template>

只展示视图层代码,CSS 样式代码可以到配套资源中下载。

代码解析如下。

因为要使用嵌套路由,所以在首页文件中预留 router-view。

下面讲解首页代码分离。

首页文件中的头部和导航部分可以抽离成一个单独的组件,在 components 目录下新建 header.vue,把头部和导航菜单的视图层整体复制到 header.vue。

index.vue 首页文件引用 header 组件,代码如下。

<template>
  <div>
    //3.使用组件
    <myHeader></myHeader>
    //导航以下使用嵌套路由
    <router-view></router-view>
  </div>
</template>

<script>
//1.引入header组件
import myHeader from '../../components/header';

export default {
  components: {
    //2.注册组件
    myHeader
  }
};
</script>

最终运行结果如图 11-5 所示。

image 2025 02 11 19 59 34 285
Figure 2. 图11-5 头部区域

布局首页静态页面

本节完成整个首页布局,导航菜单以下所有内容都应该通过路由匹配规则,在 index/index.vue 的 router-view 中展现。

在 components 目录新建 home.vue,home.vue 为首页的其他内容,下面先通过匹配规则把 home.vue 中的内容在首页中显示出来,代码如下。

import Vue from 'vue';
import Router from 'vue-router';
import index from '../views/index';
// 1. 引入 home 组件
import home from '../components/home.vue';

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: '/',
      name: 'index',
      component: index,
      // 2. 创建嵌套路由匹配规则
      children: [
        {
          path: '/', // 注意:子路由的 path 不要以 / 开头
          name: 'home',
          component: home
        }
      ]
    }
  ]
});

运行代码,home.vue 组件的内容可以在首页中正常显示,最后布局 home.vue 组件即可,代码如下(注:此处只有视图代码,样式代码可在资源中下载)。

<template>
  <div>
    <div class="banner">
      <img src="../assets/images/banner.jpg" />
    </div>
    <div class="content">
      <div class="ad_product_menu">
        <img src="../assets/images/ad_product.jpg" />
      </div>
      <div class="ad_product_main">
        <ul>
          <li>
            <img src="../assets/images/ad_a.jpg" />
          </li>
          <li>
            <img src="../assets/images/ad_a.jpg" />
          </li>
          <li>
            <img src="../assets/images/ad_a.jpg" />
          </li>
        </ul>
      </div>
    </div>
    <div class="content">
      <div class="index_hot">
        <div class="index_hot_menu">精品推荐</div>
        <div class="index_hot_main">
          <ul>
            <li>
              <img src="../assets/images/p1.jpg" />
            </li>
            <li>
              <img src="../assets/images/p1.jpg" />
            </li>
            <li>
              <img src="../assets/images/p1.jpg" />
            </li>
          </ul>
        </div>
      </div>
    </div>
    <div class="content">
      <div class="index_hot_menu">精品推荐</div>
      <div class="index_productlist">
        <div class="index_productlist_left">
          <img src="../assets/images/p2.jpg" />
        </div>
        <div class="index_productlist_right">
          <ul>
            <li>
              <img src="../assets/images/p2.jpg" />
            </li>
            <li>
              <img src="../assets/images/p2.jpg" />
            </li>
            <li>
              <img src="../assets/images/p2.jpg" />
            </li>
            <li>
              <img src="../assets/images/p2.jpg" />
            </li>
          </ul>
        </div>
      </div>
    </div>
    <div class="content">
      <div class="index_hot_menu">精品推荐</div>
      <div class="index_productlist">
        <div class="index_productlist_left">
          <img src="../assets/images/p2.jpg" />
        </div>
        <div class="index_productlist_right">
          <ul>
            <li>
              <img src="../assets/images/p2.jpg" />
            </li>
            <li>
              <img src="../assets/images/p2.jpg" />
            </li>
            <li>
              <img src="../assets/images/p2.jpg" />
            </li>
            <li>
              <img src="../assets/images/p2.jpg" />
            </li>
          </ul>
        </div>
      </div>
    </div>
    <div class="content">
      <div class="ad_product_menu">
        <img src="../assets/images/ad_product.jpg" />
      </div>
      <div class="ad_product_main">
        <ul>
          <li>
            <img src="../assets/images/ad_a.jpg" />
          </li>
          <li>
            <img src="../assets/images/ad_a.jpg" />
          </li>
          <li>
            <img src="../assets/images/ad_a.jpg" />
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>

运行结果如图 11-6 所示。

image 2025 02 11 20 03 08 934
Figure 3. 图11-6 首页效果图

使用axios获取轮播图

本节先使用 element-ui 实现轮播图功能,再使用 axios 获取服务器端真实数据,最终把数据渲染到 HTML 视图,步骤如下。

(1)安装 element-ui。在终端中运行以下命令。

npm i element-ui -S

(2)选择使用方式。使用方式分为全局使用和按需使用,为保证页面的加载速度,选择按需使用的方式,在终端中执行以下命令。

npm install babel-plugin-component -D

(3)修改 .babelrc。 代码如下。

"plugins": [
  "transform-vue-jsx",
  "transform-runtime",
  [
    "component",
    {
      "libraryName": "element-ui",
      "styleLibraryName": "theme-chalk"
    }
  ]
]

(4)在 main.js 全局引入轮播图组件,在 home 组件中使用轮播图。

main.js 引用代码,代码如下。

import {carousel,carouselItem} from 'element-ui'
Vue.use(carousel)
Vue.use(carouselItem)

home.vue 轮播图代码(element-ui 默认代码)如下。

<div class="banner">
  <el-carousel height="600px">
    <el-carousel-item v-for="item in 4":key="item">
      <h3 class="small">{{ item }}</h3>
    </el-carousel-item>
  </el-carousel>
</div>

下面讲解 axios 调用轮播图接口,步骤如下。

(1)安装 axios。在终端执行以下命令。

npm install axios -S

(2)打开 main.js,把 axios 挂载到 Vue 原型对象中,实现数据共享,节省内存空间,代码如下。

import Axios from 'axios'
Vue.prototype.$axios = Axios

此时可以全局使用 axios,打开 home.vue 组件,调用轮播图接口。

请求方式为 get 请求,代码如下。

export default {
  data() {
    return {
      // 1. 声明 banner 属性,用于接收 axios 获取到的数据
      banner: []
    };
  },
  methods: {
    // 2. 声明 getBanner 方法,把获取到的数据赋值给 banner 属性
    getBanner() {
      this.$axios.get("http://api.mm2018.com:8095/api/goods/home")
        .then(res => {
          // console.log(res.data.result)
          this.banner = res.data.result[0].contents;
        });
    }
  },
  // 3. 在 created 生命周期函数中调用 getBanner 方法
  created() {
    this.getBanner();
  }
};

代码解析如下。

通过 axios 调用接口,data 中的 banner 属性已经获取到图片数据,使用 v-for 指令把 banner 图片渲染到 HTML 页面即可,代码如下。

<div class="banner">
  <el-carousel height="600px">
    <el-carousel-item v-for="(item, i) in banner" :key="i">
      <img :src="item.picUrl">
    </el-carousel-item>
  </el-carousel>
</div>

运行结果如图 11-7 所示。

image 2025 02 11 20 10 15 183
Figure 4. 图11-7 渲染首页轮播图

首页广告版块数据渲染

本节完成首页数据渲染,banner 下面还有 6 个版块,这 6 个版块的渲染方法有两种。

第一种方法比较简单,和 banner 的获取方法一样,即使用下标的形式获取,例如第一个版块是 res.data.result[0],那么第二个版块的下标为 1,第三个版块的下标为 2,以此类推,这样虽然可以获取到各个版块的数据,但是有些烦琐。

第二种方法是循环遍历整个 res.data.result 数组,根据数组的 type 属性显示不同版块。下面使用第二种方法实现首页数据渲染。

首先获取整个首页版块数据,代码如下。

export default {
  data() {
    return {
      banner: [],
      // 1. 声明 allList 属性接收首页所有版块数据
      allList: []
    };
  },
  methods: {
    getBanner() {
      this.$axios.get("http://api.mm2018.com:8095/api/goods/home")
        .then(res => {
          // console.log(res.data.result)
          this.banner = res.data.result[0].contents;
          // 2. 把所有版块数据赋值给 allList 数组
          this.allList = res.data.result; //  直接将 result 赋值给 allList
        })
        .catch(error => {
          console.error("获取首页数据失败:", error);
          // 处理错误,例如显示错误信息
        });
    }
  },
  //3.在created生命周期函数中调用getBanner方法
  created() {
    this.getBanner();
  }
};

然后循环遍历 allList 属性,视图层代码如下。

<div v-for="(item,i) in allList" :key="i"></div>

代码解析如下。

此时 div 标签中,不管是什么内容都会遍历 7 次,要根据 type 属性判断是否显示,先把广告模块放到 div 标签中,代码如下。

<div v-for="(item, i) in allList" :key="i">
  <div class="content" v-if="item.type == 1">
    <div class="ad_product_menu">
      <img src="../assets/images/ad_product.jpg" />
    </div>
    <div class="ad_product_main">
      <ul>
        <li v-for="(ad, i) in item.contents" :key="i">
          <img :src="ad.picUrl" />
        </li>
      </ul>
    </div>
  </div>
</div>

运行结果如图 11-8 所示。

image 2025 02 11 20 14 10 812
Figure 5. 图11-8 渲染首页广告

因为整个首页中有两个版块的 type 值为 1,所以前端显示两次广告。

首页商家推荐版块数据渲染

本节讲解商家推荐版块,代码如下。

<!--商家推荐的type值为2-->
<div class="content" v-if="item.type == 2">
  <div class="index_hot">
    <div class="index_hot_menu">{{ item.name }}</div>
    <div class="index_hot_main">
      <ul>
        <!--循环遍历商家推荐产品-->
        <li v-for="(hotdetail, i) in item.contents" :key="hotdetail.id">
          <img :src="hotdetail.picUrl" />
        </li>
      </ul>
    </div>
  </div>
</div>

运行结果如图 11-9 所示。

image 2025 02 11 20 16 01 611
Figure 6. 图11-9 渲染首页商家推荐版块

首页其他版块数据渲染

西瓜子、原味瓜子、五香瓜子这 3 个版块的 type 值都等于 3,因此它们的页面布局也是一样的,代码如下。

<div class="content" v-if="item.type == 3">
  <div class="index_hot_menu">{{ item.name }}</div>
  <div class="index_productlist">
    <div class="index_productlist_left" v-for="(bigImg, i) in item.contents" :key="bigImg.id" v-if="bigImg.type == 2">
      <img :src="bigImg.picUrl" :alt="bigImg.altText" v-if="bigImg.picUrl" />
    </div>
    <div class="index_productlist_right">
      <ul>
        <li v-for="(smallImg, i) in item.contents" :key="smallImg.id" v-if="smallImg.type == 0">
          <img :src="smallImg.picUrl" :alt="smallImg.altText" v-if="smallImg.picUrl" />
        </li>
      </ul>
    </div>
  </div>
</div>

运行结果如图 11-10 所示。

image 2025 02 11 20 17 20 685
Figure 7. 图11-10 完成首页所有版块渲染