在线商城项目02-展示商品列表页面并抽取公共组件

简介

本系列前期不过多关注样式,所以直接采用视频提供的重构。本篇主要进行如下工作:

  1. 展示商品列表页面
  2. 抽取公共组件

1. 展示商品列表页面

step1:新增存放重构资源的目录 视频提供的重构有点问题,大家可以使用我上传在github上的重构资源。 在根目录下新建一个resources文件夹,用来存放重构的资源文件。如果公司或者团队有专门的重构工程师,可以将这个文件夹交给他们管理。

如图,这里有红色和绿色,是因为有些文件我已经track了,而有的没有。使用webstorm你可以在新建文件的时候track,也可以自己过后手动track。我们打开goodsList.html,如下图:

step2:将重构页面资源引入src 在src下新增文件夹views,用来存放我们的页面文件。再在views下新建文件夹GoodsList,用来存放商品列表相关的文件。在GoodsList下新建一个GoodsList.vue文件。如图:

GoodsList.vue文件中放我们的重构内容:

<template>
  <div>
    <header class="header">
      <div class="navbar">
        <div class="navbar-left-container">
          <a href="/">
            <img class="navbar-brand-logo" src="../../assets/logo.png"></a>
        </div>
        <div class="navbar-right-container" style="display: flex;">
          <div class="navbar-menu-container">
            <!--<a href="/" class="navbar-link">我的账户</a>-->
            <span class="navbar-link"></span>
            <a href="javascript:void(0)" class="navbar-link">Login</a>
            <a href="javascript:void(0)" class="navbar-link">Logout</a>
            <div class="navbar-cart-container">
              <span class="navbar-cart-count"></span>
              <a class="navbar-link navbar-cart-link" href="/#/cart">
                <svg class="navbar-cart-logo">
                  <symbol id="icon-cart" viewBox="0 0 38 32">
                    <title>cart</title>
                    <path class="path1"
                          d="M37.759 0h-4.133c-0.733 0.004-1.337 0.549-1.434 1.255l-0.546 4.342c-0.081 0.484-0.496 0.849-0.997 0.849-0.005 0-0.009-0-0.014-0h-27.604c-0.003 0-0.007-0-0.011-0-1.674 0-3.031 1.357-3.031 3.031 0 0.34 0.056 0.666 0.159 0.971l2.52 8.062c0.385 1.194 1.486 2.043 2.785 2.043 0.126 0 0.25-0.008 0.372-0.023l22.983 0.002c0.515 0.131 0.626 0.768 0.626 1.283 0.005 0.044 0.009 0.095 0.009 0.146 0 0.501-0.294 0.933-0.718 1.134l-22.439 0.003c-0.354 0-0.642 0.287-0.642 0.642s0.287 0.642 0.642 0.642h22.745l0.131-0.071c0.919-0.392 1.551-1.287 1.551-2.33 0-0.058-0.002-0.116-0.006-0.173 0.021-0.108 0.033-0.24 0.033-0.376 0-1.072-0.732-1.973-1.724-2.23l-23.357-0.004c-0.063 0.008-0.135 0.013-0.209 0.013-0.719 0-1.332-0.455-1.566-1.093l-2.53-8.095c-0.048-0.154-0.076-0.332-0.076-0.515 0-0.973 0.782-1.764 1.752-1.778h27.657c1.159-0.004 2.112-0.883 2.232-2.011l0.547-4.345c0.010-0.083 0.078-0.147 0.161-0.152l4.133-0c0.354 0 0.642-0.287 0.642-0.642s-0.287-0.642-0.642-0.642z"></path>
                    <path class="path2"
                          d="M31.323 9.69c-0.022-0.003-0.048-0.004-0.074-0.004-0.328 0-0.598 0.248-0.633 0.567l-0.809 7.268c-0.003 0.022-0.004 0.048-0.004 0.074 0 0.328 0.248 0.598 0.567 0.633l0.074 0c0.001 0 0.003 0 0.004 0 0.327 0 0.596-0.246 0.632-0.563l0.809-7.268c0.003-0.022 0.004-0.048 0.004-0.074 0-0.328-0.248-0.598-0.567-0.633z"></path>
                    <path class="path3"
                          d="M27.514 25.594c-1.769 0-3.203 1.434-3.203 3.203s1.434 3.203 3.203 3.203c1.769 0 3.203-1.434 3.203-3.203s-1.434-3.203-3.203-3.203zM27.514 30.717c-1.060 0-1.92-0.86-1.92-1.92s0.86-1.92 1.92-1.92c1.060 0 1.92 0.86 1.92 1.92s-0.86 1.92-1.92 1.92z"></path>
                    <path class="path4"
                          d="M9.599 25.594c-1.769 0-3.203 1.434-3.203 3.203s1.434 3.203 3.203 3.203c1.769 0 3.203-1.434 3.203-3.203s-1.434-3.203-3.203-3.203zM9.599 30.717c-1.060 0-1.92-0.86-1.92-1.92s0.86-1.92 1.92-1.92c1.060 0 1.92 0.86 1.92 1.92s-0.86 1.92-1.92 1.92z"></path>
                  </symbol>
                  <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-cart"></use>
                </svg>
              </a>
            </div>
          </div>
        </div>
      </div>
    </header>
    <div class="nav-breadcrumb-wrap">
      <div class="container">
        <nav class="nav-breadcrumb">
          <a href="/">Home</a>
          <span>Goods</span>
        </nav>
      </div>
    </div>
    <div class="accessory-result-page accessory-page">
      <div class="container">
        <div class="filter-nav">
          <span class="sortby">Sort by:</span>
          <a href="javascript:void(0)" class="default cur">Default</a>
          <a href="javascript:void(0)" class="price">Price
            <svg class="icon icon-arrow-short">
              <use xlink:href="#icon-arrow-short"></use>
            </svg>
          </a>
          <a href="javascript:void(0)" class="filterby stopPop">Filter by</a>
        </div>
        <div class="accessory-result">
          <!-- filter -->
          <div class="filter stopPop" id="filter">
            <dl class="filter-price">
              <dt>Price:</dt>
              <dd><a href="javascript:void(0)">All</a></dd>
              <dd>
                <a href="javascript:void(0)">0 - 100</a>
              </dd>
              <dd>
                <a href="javascript:void(0)">100 - 500</a>
              </dd>
              <dd>
                <a href="javascript:void(0)">500 - 1000</a>
              </dd>
              <dd>
                <a href="javascript:void(0)">1000 - 2000</a>
              </dd>
            </dl>
          </div>

          <!-- search result accessories list -->
          <div class="accessory-list-wrap">
            <div class="accessory-list col-4">
              <ul>
                <li>
                  <div class="pic">
                    <a href="#"><img src="../../../static/1.jpg" alt=""></a>
                  </div>
                  <div class="main">
                    <div class="name">XX</div>
                    <div class="price">999</div>
                    <div class="btn-area">
                      <a href="javascript:;" class="btn btn--m">加入购物车</a>
                    </div>
                  </div>
                </li>
                <li>
                  <div class="pic">
                    <a href="#"><img src="../../../static/2.jpg" alt=""></a>
                  </div>
                  <div class="main">
                    <div class="name">XX</div>
                    <div class="price">1000</div>
                    <div class="btn-area">
                      <a href="javascript:;" class="btn btn--m">加入购物车</a>
                    </div>
                  </div>
                </li>
                <li>
                  <div class="pic">
                    <a href="#"><img src="../../../static/3.jpg" alt=""></a>
                  </div>
                  <div class="main">
                    <div class="name">XX</div>
                    <div class="price">500</div>
                    <div class="btn-area">
                      <a href="javascript:;" class="btn btn--m">加入购物车</a>
                    </div>
                  </div>
                </li>
                <li>
                  <div class="pic">
                    <a href="#"><img src="../../../static/4.jpg" alt=""></a>
                  </div>
                  <div class="main">
                    <div class="name">XX</div>
                    <div class="price">2499</div>
                    <div class="btn-area">
                      <a href="javascript:;" class="btn btn--m">加入购物车</a>
                    </div>
                  </div>
                </li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
    <footer class="footer">
      <div class="footer__wrap">
        <div class="footer__secondary">
          <div class="footer__inner">
            <div class="footer__region">
              <span>Region</span>
              <select class="footer__region__select">
                <option value="en-US">USA</option>
                <option value="zh-CN">China</option>
                <option value="in">India</option>
              </select>
            </div>
            <div class="footer__secondary__nav">
              <span>Copyright © 2017 IMooc All Rights Reserved.</span>
              <a href="http://us.lemall.com/us/aboutUs.html">
                About Us
              </a>
              <a href="http://us.lemall.com/us/termsofUse.html">
                Terms &amp; Conditions
              </a>
              <a href="http://us.lemall.com/us/privacyPolicy.html">
                Privacy Policy
              </a>
            </div>
          </div>
        </div>
      </div>
    </footer>
  </div>
</template>

<script>
export default {
  data () {
    return {}
  }
}
</script>

这里需要注意两点:

  1. template下面要有一个root element,所以我们加了一层div
  2. 图片的引用地址改变了,我们将自己的logo.png替换assets下vue的logo,将产品图片文件放到static下。这里关于static和assets的不同可以看assets 和static的区别以及 webpack 模板的文档 - Handing Static Assets来了解。简而言之的话,就是 static/ 目录下的文件并不会被 Webpack 处理。

step3 修改路由文件router/index.js,将默认路由指向商品列表页。

import Vue from 'vue'
import Router from 'vue-router'
import GoodsList from '@/views/GoodsList/GoodsList'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'GoodsList',
      component: GoodsList
    }
  ]
})

step4 修改APP.vue,去掉style内容和style标签,去掉style标签是防止在头部生成多余的空标签。

<template>
  <div id="app">
    <router-view/>
  </div>
</template>

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

step5 将resources/css文件夹copy到src/assets下,修改main.js,引入css文件。

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'

import './assets/css/base.css'
import './assets/css/login.css'
import './assets/css/product.css'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

step6:重新运行我们的项目。如下:

到这里,我们已经能够在项目中展示重构提供的页面了。注意审查logo和商品图片,会发现logo是base64引入,而商品图片是地址引入。因为static/ 目录下的文件并不会被 Webpack 处理。

2. 抽取公共组件

vue很重要的思想就是组件化,对于网站的大多数页面而言,都会有头部,底部和面包屑。那么我们不妨把这三个部分抽取成项目的公共组件。

step1:抽取公共组件。在components文件夹下删除Hello.vue,新建三个vue文件如下:

将GoodList.vue文件中的header,footer和nav-breadcrumb-wrap分别剪切粘贴到对应的组件中。这里要注意,由于文件地址改变,对一些资源的引入地址也要相应改变,比如头部引入的logo.png。

step2: 引入公共组件 抽取出公共组建以后,如果页面需要这些组件,需要引入,注册以后使用。此时的GoodsList.vue代码如下:

<template>
  <div>
    <PageHeader></PageHeader>
    <PageBread></PageBread>
    <div class="accessory-result-page accessory-page">
      <div class="container">
        <div class="filter-nav">
          <span class="sortby">Sort by:</span>
          <a href="javascript:void(0)" class="default cur">Default</a>
          <a href="javascript:void(0)" class="price">Price
            <svg class="icon icon-arrow-short">
              <use xlink:href="#icon-arrow-short"></use>
            </svg>
          </a>
          <a href="javascript:void(0)" class="filterby stopPop">Filter by</a>
        </div>
        <div class="accessory-result">
          <!-- filter -->
          <div class="filter stopPop" id="filter">
            <dl class="filter-price">
              <dt>Price:</dt>
              <dd><a href="javascript:void(0)">All</a></dd>
              <dd>
                <a href="javascript:void(0)">0 - 100</a>
              </dd>
              <dd>
                <a href="javascript:void(0)">100 - 500</a>
              </dd>
              <dd>
                <a href="javascript:void(0)">500 - 1000</a>
              </dd>
              <dd>
                <a href="javascript:void(0)">1000 - 2000</a>
              </dd>
            </dl>
          </div>

          <!-- search result accessories list -->
          <div class="accessory-list-wrap">
            <div class="accessory-list col-4">
              <ul>
                <li>
                  <div class="pic">
                    <a href="#"><img src="../../../static/1.jpg" alt=""></a>
                  </div>
                  <div class="main">
                    <div class="name">XX</div>
                    <div class="price">999</div>
                    <div class="btn-area">
                      <a href="javascript:;" class="btn btn--m">加入购物车</a>
                    </div>
                  </div>
                </li>
                <li>
                  <div class="pic">
                    <a href="#"><img src="../../../static/2.jpg" alt=""></a>
                  </div>
                  <div class="main">
                    <div class="name">XX</div>
                    <div class="price">1000</div>
                    <div class="btn-area">
                      <a href="javascript:;" class="btn btn--m">加入购物车</a>
                    </div>
                  </div>
                </li>
                <li>
                  <div class="pic">
                    <a href="#"><img src="../../../static/3.jpg" alt=""></a>
                  </div>
                  <div class="main">
                    <div class="name">XX</div>
                    <div class="price">500</div>
                    <div class="btn-area">
                      <a href="javascript:;" class="btn btn--m">加入购物车</a>
                    </div>
                  </div>
                </li>
                <li>
                  <div class="pic">
                    <a href="#"><img src="../../../static/4.jpg" alt=""></a>
                  </div>
                  <div class="main">
                    <div class="name">XX</div>
                    <div class="price">2499</div>
                    <div class="btn-area">
                      <a href="javascript:;" class="btn btn--m">加入购物车</a>
                    </div>
                  </div>
                </li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
    <PageFooter></PageFooter>
  </div>
</template>

<script>
import PageHeader from '../../components/PageHeader'
import PageBread from '../../components/PageBread'
import PageFooter from '../../components/PageFooter'

export default {
  data () {
    return {}
  },
  components: {
    PageHeader,
    PageBread,
    PageFooter
  }
}
</script>

step3:修改面包屑组件 之前我们的面包屑的二级目录固定写死为Goods,作为公共组件肯定是不可以的。所以我们需要使用插槽slot。 PageBread.vue作如下修改:

<nav class="nav-breadcrumb">
  <a href="/">Home</a>
  <slot></slot>
</nav>

GoodsList.vue作如下修改:

<PageBread>
      <span>Goods</span>
    </PageBread>

提交代码

好的,本篇的任务完成,我们添加文件并提交到github。步骤如下:

git status
git diff
git add .
git commit -am 'add views GoodsList and Components head foot bread'
git push

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

现代Web页面开发流程

通常来说,Web页面开发的流程大致是这样的:设计师(设计师不是美工,就像程序员不是码农一样)提供设计稿,通常是图片格式。然后前端的开发人员 (在ThoughtW...

35012
来自专栏腾讯移动品质中心TMQ的专栏

H5前端性能测试快速入门

说到H5测试,对于做WEB测试的同学来说再熟悉不过了,它包括页H5功能测试,前端性能测试,浏览器兼容性能测试,以及服务端性能测试。

6857
来自专栏微信小程序开发

微信小程序开发常见问题(四)

知晓程序员,专注微信小程序开发的程序员! 一、小程序不同页面之间的传值方式 a、URL传值 这种方式最常用,比如: wx.navigateTo({ url...

4275
来自专栏微信小程序开发

微信小程序开发常见问题(七)

知晓程序员,专注微信小程序开发的程序员! 一、判断小程序版本号 小程序的API是不断更新的,你可能使用某个API时,文档里会说明,此API在1.x.x版本开始...

6365
来自专栏古时的风筝

如何应用Font Awesome矢量字体图标

Font Awesome 是一套专门为 Twitter Boostrap 设计的图标字体库。这套图标字体集几乎囊括了网页中可能用到的所有图标,除了包括 Twit...

2416
来自专栏腾讯移动品质中心TMQ的专栏

H5前端性能测试快速入门

前言 说到H5测试,对于做WEB测试的同学来说再熟悉不过了,它包括页H5功能测试,前端性能测试,浏览器兼容性能测试,以及服务端性能测试。那本文谈到...

2916
来自专栏WindCoder

2014-2015插件整理

主要作用:Protect your WordPress site by hiding vital areas of your site, protecting ...

842
来自专栏菩提树下的杨过

Silverlight中也玩屏幕截图

先上演示地址:http://images.24city.com/jimmy/QQCapture/ 注:首次点击,会提示未安装ActiveX插件,下载安装成功后...

1987
来自专栏杨逸轩 ' sBlog

什么是静态和动态网页?

3417
来自专栏腾讯大讲堂的专栏

ReactJS 服务端同构实践【QQ音乐web团队】

作者:calvin 腾讯 QQ音乐 数字音乐部 工程师 最近在项目中接入了 ReactJS 并在服务端做了同构直出。关于 ReactJS 服务端同构业界已经有...

2635

扫码关注云+社区

领取腾讯云代金券