基于Vue2的图书销售网站(HTML+CSS+JS)

功能描述 

  1. 商品分类展示;
  2. 商品详情
  3. 商品搜索
  4. 订单详情(购物车)
  5. 登录与注册

注意:登录状态可以将书籍加入购物车,为登录状态只能浏览书籍。页面布局设计大体仿的【孔夫子旧书网】。

使用到的技术

  1. 项目创建;
  2. Vue指令应用:插值、数据绑定、计算属性、方法、侦听器、事件监听等 ;
  3. Vue组件创建和应用;
  4. Vue路由使用;
  5. 全局状态管理Vuex的使用;
  6. 前端基础知识的综合应用。

数据来源及描述

书籍数据文件位置:../data/books.js,使用的是模拟数据,数组名称为books,数据属性包括:

  1. isbn(书籍ISBN码,作为主键);
  2. bookname(书名);
  3. author(作者);
  4. type(书籍类型);
  5. price(单价);
  6. stock(库存);
  7. pubfirm(出版社);
  8. bookbrief(书籍简介);
  9. authorbrief(作者简介);
  10. good(是否为推荐书籍)。

基于Vue2的图书销售网站(HTML+CSS+JS)_第1张图片

 全局状态变量设置(文件位置src>store>index.js):

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    carts:[],
    user:[],
    mess:'',
  },
  getters:{
    total:function(state){
      var t=0;
      state.carts.forEach(function(ele){
        t+=ele.price*ele.num
      });
      return t;
    },
    count:function(state){
      var c=0;
      state.carts.forEach(function(ele){
        c+=ele.num
      });
      return c;
    },
  },
  mutations: {
    queryuser:function(state,user){
      var ele=state.user.find(function(ele){
        return ele.name==user.name//是否存在用户
      })

      if(ele) state.mess=ele.pwd//存在则返回用户信息
      else{
        return state.mess="f"
      }
    },
    reg:function(state,user){//添加用户
        state.user.push({
          ...user
        })
    },
    addCart:function(state,book){
        var ele=state.carts.find(function(ele){
          return ele.isbn===book.isbn
        });

        if(ele) ele.num++
        else{
          state.carts.push({
            isbn:book.isbn,
            bookname:book.bookname,
            price:book.price,
            num:1
          })
        }
    },
    remove:function(state,index){
      state.carts.splice(index,1)
    }
  },
  actions: {
  },
  modules: {
  }
})

详细设计

为了读者能拥有良好的阅读体验,css代码统一放在文章结尾。

根页面

该页面包含三个子组件:Main.vue、PageShow.vue和ShopCart.vue。页面布局分为四个部分,登录通栏,显示一条语句和登录注册链接,登录后登录链接部分改为显示“书友+用户名”和退出登录链接。logo及搜索块,左边为logo图片,右边为书名搜索框和按钮。点击搜索按钮时若输入框不为空则跳转到“所有商品”页面展示搜索结果。导航块,显示三个子组件的路由链接,正在使用路由的链接变为绿色。下方则为路由视图部分,默认显示为首页子组件。

基于Vue2的图书销售网站(HTML+CSS+JS)_第2张图片 根页面路由路径

根页面

路由守卫,跳转除了首页和商品展示页以外的页面前判断是否登录。写在router下的index.js文件中。

基于Vue2的图书销售网站(HTML+CSS+JS)_第3张图片

 App.vue被注释掉,留下一个路由窗口。

基于Vue2的图书销售网站(HTML+CSS+JS)_第4张图片

Home.vue替代作为根页面



 首页

该页面为Main.vue,是Home.vue的子组件之一。主要布局包括横幅、广告活动、好书推荐。横幅为动态轮播图,好书推荐是书籍good属性值为1的书籍列表。点击好书推荐部分的书籍封面,将会跳转到“所有商品>书籍详情”页面。

基于Vue2的图书销售网站(HTML+CSS+JS)_第5张图片

 页面HTML代码如下:



登录注册

该页面Init.vue包含两个子组件,Login.vue和Reg.vue。该页面布局主要分为两部分,头部显示一条语句和首页组件链接,主要容器包含一个图片和两个子组件路由链接和路由视图。路由视图默认显示登录页面。

基于Vue2的图书销售网站(HTML+CSS+JS)_第6张图片 登录注册页面

路由路径代码如下:

基于Vue2的图书销售网站(HTML+CSS+JS)_第7张图片 登录注册路由路径

 登录注册初始页面init.vue代码如下:





Login组件负责登录,接收到用户输入的信息后查询用户,“用户不存在”或“用户名或密码错误”则弹出提示,登录成功则跳转到首页并将用户信息存储到sessionStorage.username.




Reg组件负责注册,接收到用户输入的信息后传送给$store的queryuser方法对全局状态变量user进行查找,若用户名已存在则弹出提示,否则将用户信息添加到全局变量user里,并自动登录跳转到首页。代码如下:



书籍页面显示

该页面为PageShow.vue,页面主要布局包括左边的分类筛选栏,和右边的组件显示块。页面PageShow.vue包含两个元素级子组件,Bookitems.vue和Detail.vue。

Bookitems负责显示书籍列表,默认显示所有书籍 。书名搜索和左边分类筛选功能都在pageshow页面查询后将的结果传送给该组件显示.点击该组件的书籍封面或书名即跳转到书籍详情。

Detail负责显示书籍详细信息,点击书籍封面可查看大图。

若未登录状态点击“加入购物车”按钮则会跳转到登录注册页面,子组件通过v-if 操控显示。

基于Vue2的图书销售网站(HTML+CSS+JS)_第8张图片 所有书籍展示

基于Vue2的图书销售网站(HTML+CSS+JS)_第9张图片 书籍详情展示

基于Vue2的图书销售网站(HTML+CSS+JS)_第10张图片 点击封面查看大图

 PageShow.vue页面代码如下:



书籍列表Bookitems.vue代码如下:



书籍详情Detail.vue代码如下:



点击封面查看大图代码如下写在src>main.js文件中():

// 引入查看大图插件
import Viewer from 'v-viewer'
import 'viewerjs/dist/viewer.css'

Vue.use(Viewer)
Viewer.setDefaults({
  Options: { // Options必须,否则会出现默认打开等等不可预知的错误
   'inline': true, 
   'button': true, // 显示右上角关闭按钮
   'navbar': false, // 缩略图导航
   'title': true, // 是否显示当前图片的标题
   'toolbar': false, // 显示工具栏
   'tooltip': true, // 显示缩放百分比
   'movable': false, // 图片是否可移动
   'zoomable': false, // 是否可缩放
   'rotatable': false, // 是否可旋转
   'scalable': false, // 是否可翻转
   'transition': true, // 是否使用 CSS3 过度
   'fullscreen': true, // 播放时是否全屏
   'keyboard': true, // 是否支持键盘
   'url': 'data-source' // 设置大图片的 url
  }
})

购物车

页面ShopCart.vue负责显示购物车信息。包括书籍封面、书名、单价、数量、小计和删除操作,最下方左边显示总金额和总商品数量,右边显示结算按钮。其中商品数量部分由元素级组件numbtn显示,提供按钮进行数量增减操作。购物车数据为全局状态变量。

基于Vue2的图书销售网站(HTML+CSS+JS)_第11张图片

 购物车页面ShopCart.vue代码如下:



元素级组件numbtn.vue代码如下:



css部分

home.css

#head{
    width:100%;
    height:36px;
    background: #8c222c;
    float: left;
}
#head-left{
    width:157px;
    left: 280px;
    position:absolute;
    line-height: 36px;
    font-size: 12px;
    color: #e2c8ca;
}
ul{
    margin: 0px;
    padding: 0px;
}
.head-right{
    width:570px;
    right:280px;
    font-size: 14px;
    position: absolute;
    line-height: 36px;
    z-index: 1;
}
.head-right ul li{
    height:100%;
    list-style: none;
    float: left;
    display: inline;
    text-align: center;
    color: #e2d5d6;
}
#a{
    color: #e2d5d6;
    font-size: 13px;
    text-decoration: none;
    padding-left: 5px;
}
#a:hover{
    color: #ffffff;
}
#logo{
    height:130px;
    background: #f2f1ea;
}
#logo img{
    width:18%;
    margin-left: 275px;
    float: left;
    position: relative;
    top: 18px;
}
#logo form{
    height:35px;
    width:588px;
    font-size: 12px;
    right: 280px;
    position: absolute;
    top:65px;
}
#searchinput{
    height:32px;
    width:486px;
    border:none;
    line-height: 14px;
    border: 2px solid #8c222c;
    margin: 0px;
    position: relative;
    float: left;
}
#formbutton{
    width:76px;
    height:37px;
    margin-right: 0px;
    color: #fff;
    background-color: #8c222c;
    float: left;
}
#nav{
    height:50px;
    font-size: 18px;
    background: #fff;
}
#nav table{
    width:278px;
    height:50px;
    position: relative;
    left:275px;
    text-align: center;
    margin: 0px;

}
#nav a:link,#nav a{
    text-decoration: none;
    color: black;
}
#nav a:hover{
    border-bottom: 2px solid rgb(151, 141, 141);
}
/* 使用样式 */
#nav a.router-link-exact-active {
    color: #42b983;
  }

init.css

/* 样式文件名:init.css
应用:登录注册页面
应用对象:init.vue
 */
 #head{
    width:100%;
    height:36px;
    background: #8c222c;
    float: left;
}
#head-left{
    width:157px;
    left: 280px;
    position:absolute;
    line-height: 36px;
    font-size: 12px;
    color: #e2c8ca;
}
ul{
    margin: 0px;
    padding: 0px;
}
#head-right{
    width:570px;
    right:280px;
    font-size: 14px;
    position: absolute;
    line-height: 36px;
    z-index: 1;
}
#head-right ul li{
    height:100%;
    width:95px;
    list-style: none;
    float: left;
    display: inline;
    text-align: center;
}
#head-right ul li a{
    color: #e2d5d6;
    text-decoration: none;
    display: block;
}
#logo{
    height:130px;
    background: #f2f1ea;
}
#logo img{
    width:18%;
    margin-left: 275px;
    float: left;
    position: relative;
    top: 18px;
}
 #main{
     width:100%;
     height:530px;
     text-align: center;
     background-color:rgb(253, 252, 247);
     padding: 0px;
    }
 #w{
     width:897px;
     height:100%;
     margin:0 auto;
    } 
 #loginimg{
     float:left;
     position:relative;
     top: 70px;
    }
 #loginimg img{
     width:400px;
     padding: 0px 50px;
    }
 #view{
     width:389px;
     height:340px;
     position:relative;
     float:left;
     top:95px;
     border: 3px solid rgba(137,153,169,.2);
     border-radius: 19px;
     background-color: rgb(253, 253, 253);
    }/*border-radius设置圆角*/
 #title{
     height:24px;
     padding: 28px 37px;
    }
#title a{
    font:bold 24px 行楷;
    text-decoration: none;
    color:rgb(167, 197, 221);
}/*设置字体大小样式、取消下划线*/
#title a:hover{
    color: rgb(62, 116, 233);
}
#title_left{
    width:155px;
    border-right: 1px solid #ccc;
    text-align: center;float: left;
}
#title_right{
    width:155px;
    float: left;
    text-align: center;
}
#title a.router-link-exact-active {
    color:rgb(62, 116, 233);
  }
#form{
    width:335px;
    height:230px;
    position:relative;
    float:left;
    padding:0px 25px;
}
#form input{
    width:208px;
    height:23px;
    margin: 10px;
}

span{
    display: inline-block;
    text-align: center;
    width:66px;
    height:23px;
}
#form button{
    width:218px;
    height:36px;
    border-radius: 3px;
    line-height: 34px;
    font-size: 16px;
    margin:10px 10px 10px 77px;
    background-color: rgb(147, 181, 224);
    color: rgb(255, 255, 255);
    border-color:rgb(162, 194, 235) ;
}
.ftimg{
    position: relative;
    top:0px;
    display: block;
    max-width: 70%;/* 控制图片大小 */
    max-height:80px;
    min-width: 30%;
    min-height: 80px;}
#footer{
    width:100%;
    height:32px;
    font-size: 10px;
    text-align: center;
    background-color:rgb(255, 255, 255);
    vertical-align: middle;
    position: absolute;
    top:678px;
}

 main.css

#banner{
    width:810px;
    height:270px;
    position: relative;
    overflow: hidden;
    left:350px;
}
#photo{
    width:4050px;
    height:270px;
    animation: switch 10s ease-out infinite;
}
#photo img{
    float: left;
    width:810px;
    height:270px;
}
@keyframes switch {
	0%, 20% {margin-left: 0;}
	21%, 40% {margin-left: -810px;}
	41%, 60% {margin-left: -1620px;}
    61%,80%{margin-left:-2430px}
    81%,100%{margin-left:-3240px} 
}
#adver{
    width:1150px;
    height:107px;
    margin-top: 8px;
    position: relative;
    left:350px;
}
#adver table img{
    width:404px;
    height:35px;
    margin: 0px;
}
#gallery{
    background-color: #fcf9f9;
    height:570px;
    margin: 0 340px;
    border-bottom: 1px solid #ccc;
}
#gallery p{
    /* width:810px; */
    height: 22px;
    margin-bottom: 18px;
    border-bottom: 1px solid #ccc;
    margin-top: 20px;
    padding:10px 0px 10px 5px;

}
#gallery ul{
    width:810px;
    text-align: justify;
    list-style: none;
}
#gallery ul li{
    width:140px;
    height:220px;
    position: relative;
    float: left;
    margin-bottom: 35px;
    margin-right: 20px;
}
#gallery span{
    display:block;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;/*用省略号替代多余文字*/
}
.hlimg{
    height:150px;
}
.hlimg img{
    width:100%;
}
.title{
    font-size: 15px;
}
.writer{
    font-size: 8px;
    color: rgb(114, 114, 112);
    line-height: 20px;
    margin-bottom: 5px;
}
.price{
    font-size: 16px;
    color: rgb(230, 152, 64);
}
#footer{
    width:100%;
    height:60px;
    text-align: center;
    position: relative;
    bottom: 5px;
    border-top: #ccc 2px;
}

pageshow.css

#page{
    height:100%;
    margin:0px 270px;
    position: relative;
}
#query{
    height:20px;
    /* border: 2px solid #e90fe9; */
    padding: 10px 0px;
    font-size: 14px;
}
#left{
    width: 180px;
    height: 100%;
    background: #f7f7f6;
    border-top: 1px solid #e5e5e5;
    border-right: 1px solid #e5e5e5;
    padding: 0 10px 16px 15px;
    position: relative;
}
#left span{
    margin-top: 18px;
    padding-bottom: 1px;
    font-size: 18px;
    color: #999;
    line-height: 20px;
}
/* #type1{
    padding: 10px;
    font-weight: 600;
} */
.typeitem button{
    display: block;
    margin: 10px;
    border: 0px;
    background-color: #f7f7f6;
    font-size: 15px;
    color: black;
    line-height: 25px;
}
.typeitem button:hover{
    border-bottom: 1px solid #999;
}
#right{
    border-top: 1px solid #e5e5e5;
    width:740px;
    height: 100%;
    position: absolute;
    left: 206px;
    top: 40px;
    padding-left: 30px;
}

bookresult.css

.item{
    padding: 20px 0;
    position: relative;
    border-bottom: 1px solid #e5e5e5;
    font:caption 13px 宋体;
    color:#000000;
}
#img-div{
    width: 130px;
    height: 130px;
    display: inline-block;
    text-align: center;
    border: 2px solid #e5e5e5;
}
.item img{
    max-width: 130px;
    max-height:130px;
}

.bookmess{
    width: 460px;
    height:130px;
    display: inline-block;/* 换为行内块级元素 */
    padding: 0 15px;
    position: absolute;

}
.bookmess span{
    display: block;/* 换为块级元素 */
    padding: 6px 0;
}
#bookname{
    font: 450 18px 行楷;
    color: #8c222c;
}
.money{
    display: inline-block;
    position: absolute;
    left: 630px;
}
.money span{
    display: block;
    padding: 5px 0;

}
#num{
    font: 700 20px 宋体;
    color: #8c222c;
}
.money button{
    display:block;
    padding: 2px 5px;
    margin-top: 38px;
    border: 1px solid #f55212;
    background-color: #ffffff;
    color: #f55212;
}
#footer{
    width:100%;
    height:60px;
    text-align: center;
    position: relative;
    bottom: 5px;
    border-top: #ccc 2px;
}

detail.css

.detail{
    position: relative;
    border: 2px solid rgba(137,153,169,.2);
    width: 740px;
    height: auto;
    padding: 15px;
    margin-top: 15px;
}
.title{
    position: absolute;
    top:-10px;
    right: 20px;
    padding: 0 10px;
    background-color: rgb(255, 255, 255);
    font-size: 15px;
    font-weight: bolder;
    color: rgba(137,153,169,.5);
}
#link{
    display: block;
    text-align: left;
    font-size: 14px;
    color: rgb(99, 170, 236);
}
.info-main{
    padding-top: 15px;
}
#img-div{
    width: 150px;
    height: 150px;
    display: inline-block;
    text-align: center;
}
.info-main img{
    max-width: 150px;
    max-height:150px;

}
.info-text{
    float: right;
    width: 570px;
}
.info-text p{
    margin: 0;
    margin-bottom: 10px;
    font: 600 18px 宋体;
}
.info-text span{
    display: block;
    padding: 5px;
    font: 400 15px 楷体;
}
.list-left{
    float: left;
    width: 300px;
}
.list-right{
    float: left;
}
.list-right button{
    padding: 2px 5px;
    border: 1px solid #f55212;
    background-color: #ffffff;
    color: #f55212;
}
dl,dt,dd{
    margin: 0;
    padding: 0;
    list-style: none;
    line-height: 22px;
}
.brief dl{
    padding-top: 20px;
}
.brief dt{
    font-weight: bolder;
    padding-bottom: 5px;
}
.brief dd{
    font-size: 14px;
    font-weight: 400;
}
#footer{
    width:100%;
    height:60px;
    text-align: center;
    position: relative;
    bottom: 5px;
    border-top: #ccc 2px;
}

shopcart.css

.shopcart{
    height:100%;
    margin:0px 270px;
    position: relative;
}
table{
    border-collapse: collapse;/* 两条边框合并为一条 */
    width: 980px;
}
table,tr{
    text-align: center;
    font: 200 17px 宋体;
}
table td{
    border-bottom: 2px solid #d8d8d8;
    padding: 20px;
}
tr img{
    max-width: 100px;
    max-height: 100px;
    border: 2px solid #e5e5e5;
}
span{
    color: #8c222c;
}
#bottom button{
    float: right;
    margin: 0px;
    width: 100px;
    height: 40px;
    background-color: #8c222c;
    color: aliceblue;
    font: 400 18px 行楷;
}

如果对你有帮助的话给我一个赞吧,这个作品是我的期末作业,时间比较紧很多地方写的粗糙,见谅。

以上是该网站的完整代码,如果懒得复制的话我也有打包完整资源在我的个人主页>资源区有分享。

【使用vscode打开,新建终端后输入输入(npm i),等相关资源下载完成再输入npm run serve运行】

你可能感兴趣的:(项目,vue.js,前端,javascript,前端框架,html)