基于Vue框架的图书销售网站(HTML+CSS+JS)

news/2024/5/13 1:27:54/文章来源:https://blog.csdn.net/llssdshiyi/article/details/122560429

功能描述 

  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(是否为推荐书籍)。

 全局状态变量设置(文件位置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图片,右边为书名搜索框和按钮。点击搜索按钮时若输入框不为空则跳转到“所有商品”页面展示搜索结果。导航块,显示三个子组件的路由链接,正在使用路由的链接变为绿色。下方则为路由视图部分,默认显示为首页子组件。

根页面路由路径
根页面路由路径

根页面

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

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

Home.vue替代作为根页面

<template>
<div id="Home"><!-- 登录通栏 --><div id="head"><div id="head-left">网罗天下图书&nbsp;&nbsp;传承中华文明</div><div class="head-right"><ul> <li >{{username}}<span id="a" @click="init()">{{message}}</span></li></ul></div></div><!-- logo及搜索 --><div id="logo"><img alt="booklogo" src="../assets/logo.png"><form action=""><input v-model="bookname" type="text" id="searchinput" placeholder="请输入书名"><input @click="query()" type="button" value="搜索" id="formbutton"></form></div><!--导航  --><div id="nav"><table><tr><td><router-link to="/">首页</router-link></td><td><router-link to="pageshow">所有商品</router-link></td><td><router-link to="shopcart">购物车</router-link></td></tr></table></div><router-view/>
</div>
</template>
<style src="../style/home.css" scoped></style>
<script>
export default {data:function(){return{username:'',bookname:'',message:'登录/注册',}},mounted:function(){if(sessionStorage.username){this.username="书友"+sessionStorage.username+" /"this.message="退出登录"}},methods:{query:function(){if(this.bookname.trim()){this.$router.push({name:'pageshow',params:{bookname:this.bookname}})}},init:function(){if(sessionStorage.username){//已登录sessionStorage.removeItem("username")//注销登录}this.$router.push({path:'/init'})}},
}
</script>

 首页

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

 页面HTML代码如下:

<template><div ><!--横幅  --><div id="banner"><div id="photo"><a href=""><img src="../assets/lb1.jpg"></a><a href=""><img src="../assets/lb2.jpg"></a><a href=""><img src="../assets/lb3.jpeg"></a><a href=""><img src="../assets/lb4.jpg"></a><a href=""><img src="../assets/lb5.jpg"></a></div></div><!-- 广告活动 --><div id="adver"><table><tr><td><a href=""><img src="../assets/pm1.png" class="pm"></a></td><td><a href=""><img src="../assets/pm2.png" class="pm"></a></td></tr><tr><td><a href=""><img src="../assets/pm3.png" class="pm"></a></td><td><a href=""><img src="../assets/pm4.png" class="pm"></a></td></tr><tr><td><a href=""><img src="../assets/pm5.png" class="pm"></a></td><td><a href=""><img src="../assets/pm6.jpg" class="pm"></a></td></tr></table></div><div id="gallery"><p><b>好书推荐</b></p><ul><li v-for="book in books1" :key="book.isbn"><span class="hlimg" @click="detail(book.isbn)"><img :src="require(`../assets/bookimg/${book.isbn}.jpg`)"></span><span class="title" >{{book.bookname}}</span><span class="writer">{{book.author}} 著</span><span class="price">¥{{book.price}}</span></li></ul></div><!--底部  --><div id="footer"><p>CSDN:由一说一&nbsp;&nbsp;&nbsp;图书销售网站<br/>参考网站:<a href="https://www.kongfz.com/">孔夫子旧书网</a></p></div></div>
</template>
<script>
import {books} from "../data/books";
export default {data:function(){return{books1:[]}},computed:{books:() => books,},mounted:function(){this.goodshow()},methods:{detail:function(val){this.$router.push({name:'pageshow',params:{isbn:val}})},goodshow:function(){books.filter(item =>{if (item.good==1){this.books1.push({...item})}})}},
}
</script>
<style src="../style/main.css" scoped></style>

登录注册

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

登录注册页面

路由路径代码如下:

登录注册路由路径

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

<!--init.vue-->
<template><div id="init"><div id="head"><div id="head-left">网罗天下图书&nbsp;&nbsp;传承中华文明</div><div id="head-right"><ul> <li ><router-link to="/">首页</router-link></li></ul></div></div><div id="logo"><img src="../assets/logo.png"/></div><div id="main"><div id="w"><div id="loginimg"><img src="../assets/init2.png" alt=""></div><div id="view"><div id=title><div id=title_left><router-link to="/init/">用户登录</router-link></div><div id=title_right><router-link to="/init/reg">用户注册</router-link></div></div><router-view/></div></div></div><div id="footer"><p>CSDN:由一说一&nbsp;&nbsp;&nbsp;图书销售网站<br></p></div></div>
</template>
<style src="../style/init.css" scoped></style>

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

<!--Login.vue-->
<template><div id=form><span>用户名</span><input v-model="name"  placeholder="请输入用户名" required autofocus><br><span>密码</span><input v-model="pwd" type="password"  placeholder="请输入密码" required><br><button @click="login()" >登录</button><br><img class="ftimg" src="../assets/登录.png" alt=""></div>
</template>
<style src="../style/init.css" scoped></style>
<script>
export default {data:function(){return{name:"",pwd:"",}},methods:{login:function(){var user={name:this.name,pwd:this.pwd}this.$store.commit('queryuser',user)var mess=this.$store.state.messif(mess=='f'){alert("用户不存在")return}else if(this.pwd==mess){sessionStorage.username=this.namealert("欢迎━(*`∀´*)ノ亻!")this.$router.replace("/");//避免后退}else{alert("用户名或密码错误")}},},
}
</script>

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

<template><div id=form><span>手机号码</span><input v-model="name" type="tel" title="请输入用户名"  placeholder="请输入用户名" required autofocus><br/><span>密码</span><input v-model="pwd" type="password" placeholder="请输入密码"  required><br/><button @click="register" >同意协议并注册</button><br/><img class="ftimg" src="../assets/注册.png"></div>
</template>
<style src="../style/init.css" scoped></style>
<script>
export default {data:function(){return{name:"",pwd:"",}},methods:{register:function(){var user={name:this.name,pwd:this.pwd}this.$store.commit('queryuser',user)var mess=this.$store.state.messif(mess=='f'){this.$store.commit('reg',user)alert("注册成功,将为你自动登录")sessionStorage.username=this.namethis.$router.replace("/");//避免后退}else{alert("用户名已存在")}},}
}
</script>

书籍页面显示

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

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

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

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

所有书籍展示

书籍详情展示

点击封面查看大图

 PageShow.vue页面代码如下:

<template><div id="page"><div id="query">{{num}}条结果</div><div id="main"><div id="left"><span>分类筛选:</span><div class="typeitem"><button   @click="querytype('文学')">文学</button><button   @click="querytype('历史')">历史</button><button   @click="querytype('工学')">工学</button><button   @click="querytype('理学')">理学</button><button   @click="querytype('哲学')">哲学</button><button   @click="querytype('小说')">小说</button><button   @click="querytype('社会文化')">社会文化</button><button   @click="querytype('自然科学')">自然科学</button></div></div><div id="right"><!-- 若搜索内容为空则输出全部书籍 --><template v-if="tf"><Bookitems :books="books1==null?books:books1" :mess="mess" @change="onchange"></Bookitems></template><template v-if="!tf"><Detail  :book="book" @change="onchange"></Detail></template></div></div></div>
</template>
<style src="../style/pageshow.css" scoped>
</style>
<script>
import {books} from "../data/books";
import Bookitems from '../components/Bookitems.vue';
import Detail from '../components/Detail.vue'
export default {name: 'PageShow',components: {//组件Bookitems,Detail,},data:function(){return{bookname:this.$route.params.bookname?this.$route.params.bookname:null,mess:'',book:{},tf:true,books1:null,}},computed:{books:() => books,num(){return this.books1==null?this.books.length:this.books1.length}},mounted:function(){this.query()},methods:{querytype:function(type){this.tf=truethis.books1=[]books.forEach(item =>{if (item.type===type){this.books1.push({...item})}})},query:function(){if(this.$route.params.bookname){//Home查询书名结果this.bookname=this.$route.params.booknamethis.books1=[]books.filter(item =>{if (item.bookname.indexOf(this.bookname)>-1){this.books1.push({...item})}})if(this.books1.length==0) return this.mess="该书籍暂未入库"this.tf=true}if(this.$route.params.isbn){//Main点击书籍图片跳转详情books.filter(item =>{if (item.isbn==this.$route.params.isbn){this.book=item}})this.tf=false}},onchange:function(book){this.book=book,this.tf=!this.tf},},
}
</script>

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

<template><div><div id="bookresult"><div class="item" v-for="book in books" :key="book.isbn"><span id="img-div"><img :src="require(`../assets/bookimg/${book.isbn}.jpg`)" @click="$emit('change',book)"></span><div class="bookmess"><span id="bookname" @click="$emit('change',book)">{{book.bookname}}</span><span>作者:{{book.author}}</span><span>出版社:{{book.pubfirm}}</span><span>类型:{{book.type}}</span></div><div class="money"><span id="num">¥{{book.price}}</span><span>库存:{{book.stock}}</span><button @click="addCart(book)">加入购物车</button></div></div><h3>{{mess}}</h3></div><!--底部  --><div id="footer"><p>CSDN:由一说一&nbsp;&nbsp;&nbsp;图书销售网站<br/>参考网站:<a href="https://www.kongfz.com/">孔夫子旧书网</a></p></div></div>
</template>
<script>
export default {name: 'Bookitems',props: {books: [],mess:null,},methods:{addCart:function(book){if(sessionStorage.username){this.$store.commit('addCart',book)}else{this.$router.push({path:'/init'})}}},
}
</script>
<style src="../style/bookresult.css" scoped></style>

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

<template><div><div class="detail"><span class="title">书籍详细信息</span><span id="link" @click="$emit('change','')">&#60;&nbsp;返回书籍列表</span><div class="info-main"><span id="img-div"><viewer><img :src="require(`../assets/bookimg/${book.isbn}.jpg`)"></viewer></span><div class="info-text"><p>{{book.bookname}}</p><div class="list-left"><span>作者:{{book.author}}</span><span>出版社:{{book.pubfirm}}</span><span>ISBN:{{book.isbn}}</span></div><div class="list-right"><span>类型:{{book.type}}</span><span>价格:{{book.price}}</span><button @click="addCart(book)">加入购物车</button></div></div></div><div class="brief"><dl><dt>内容简介:</dt><dd>{{book.bookbrief}}</dd></dl><dl><dt>作者简介:</dt><dd>{{book.authorbrief}}</dd></dl></div></div><!--底部  --><div id="footer"><p>CSDN:由一说一&nbsp;&nbsp;&nbsp;图书销售网站<br/>参考网站:<a href="https://www.kongfz.com/">孔夫子旧书网</a></p></div></div>
</template>
<script>
export default {name:"Detail",props:{book:{},},methods:{addCart:function(book){if(sessionStorage.username){this.$store.commit('addCart',book)}else{this.$router.push({path:'/init'})}}},
}
</script>
<style src="../style/detail.css" scoped></style>

点击封面查看大图代码如下写在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显示,提供按钮进行数量增减操作。购物车数据为全局状态变量。

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

<template><div class="shopcart"><table id="tb" v-><tr id="tr1"><td colspan="2">商品</td><td>单价</td><td>数量</td><td>小计</td><td>操作</td></tr><tr v-for="cart,index in carts" :key="cart.id" id="items"><td><img :src="require(`../assets/bookimg/${cart.isbn}.jpg`)"></td><td><span>{{cart.bookname}}</span></td><td>{{cart.price}}</td><td><Numbtn :sp="cart"></Numbtn></td><td><span>{{cart.price*cart.num}}</span></td><td><button @click="remove(index)">删除</button></td></tr></table><div id="bottom"> 总价:{{total}},数量:{{count}}<button>结算</button></div></div>
</template>
<style src="../style/shopcart.css" scoped></style>
<script>
import { mapGetters, mapMutations, mapState } from 'vuex'
import Numbtn from '../components/numbtn.vue'
export default {components: {//组件Numbtn},computed:{ ...mapState(['carts']),...mapGetters(['total','count']),},methods:{...mapMutations(['remove'])},
}
</script>

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

<template><div><button @click="num(sp,-1)">-</button><span>{{sp.num}}</span><button @click="num(sp,1)">+</button></div>
</template>
<script>
export default {name:'numbtn',props:{sp:{},},methods:{num:function(sp,x){if(x==-1){if(sp.num<=0) return sp.num=0;else return sp.num--;}if(x==1){if(sp.num>=sp.stock) return sp.num=sp.stock;else return sp.num++;}},},}
</script>
<style scoped>
span{width: 30px;display: inline-block;
}
</style>

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 行楷;
}

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

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

【因为这个是用到vue的,所以运行前先打开终端输入(npm i),等相关资源下载完成再运行】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_876130.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前后端分离的音乐网站vue3+jsp+mysql

基本描述 前端&#xff1a; 使用vue.js前端技术框架&#xff0c;结合动态web开发技术&#xff0c;设计了一个前后端分离的音乐网站。项目主要包含登录注册页面&#xff0c;音乐分类展示页面、音乐选择列表&#xff0c;页面数据部分从网易云服务器端口获取&#xff0c;部分从汤…

投票排行榜网站(HTML+CSS+JS)

前端基础练习小项目 【已上传该项目完整资源至我的资源区&#xff0c;目前为0积分的免费资源】 初始页面 用户注册 上面为登录和注册的初始页面&#xff0c;登录注册为浮动窗口 以下是相关代码 <!DOCTYPE html> <!-- 初始页面 init.html--> <html lang"e…

打开浏览器默认打开hao123网站的主页怎么取消设置?

一般这种情况都是如果不是因为有病毒劫持&#xff0c;就是因为病毒软件的设置问题。 解决方式1&#xff1a; 先看杀毒软件&#xff0c;例如电脑管家和鲁大师的浏览器设置。 这里不做过多解释。 解决方式二&#xff1a; 一些用户的下载了安装包&#xff0c;会强制绑定一些流…

【新手教程】从零搭建php动态网站

PHP环境搭建 需要准备好三个软件&#xff1a;MySQL、PHPstudy、Dreamweaver 这里我用的版本是 mysql8.0.20、phpstudy_x64_8.1.0.5 和 Dreamweaver CC 2018 因为我按照老师给的文档做&#xff0c;先卸载了MySQL后安装的phpstudy&#xff0c;然后用phpstudy提供的mysql安装后…

制作一个餐饮网站的头部

样式如下&#xff1a; 代码如下&#xff1a; <!DOCTYPE html> <html> <head><title>餐饮网站header部分</title><meta charset"UTF-8"><meta http-equiv"x-ua-compatible" content"IEedge"><me…

分享文档浏览网站 Docs4dev

作为一个程序员&#xff0c;每天最多打交道的肯定是代码&#xff0c;其次就是各种开源框架的文档了&#xff0c;但是各个框架的文档都有它们自己的风格&#xff0c;在国内某些网站的打开速度也是堪忧&#xff0c;最重要的是&#xff1a;大部分文档都不支持搜索&#xff0c;也不…

网站美化:网站底部右侧悬浮菜单,客服菜单,一键联系配置教程

以wordpress举例 操作步骤&#xff1a; 1&#xff0c;代码共分为两部分&#xff0c;一部分是css&#xff0c;css部分建议加到主题的style.css里面&#xff01; 另一部分是html代码&#xff0c;加到可以加到主题文件夹下footer.php里面&#xff0c;至于里面的位置放到前面&am…

【苹果CMS技术教程】苹果CMSV10基础安装过程,如何拥有自己的视频网站

第一步&#xff0c;下载程序 http://www.dungei.net/6334.html 第二步:将下载的程序上传至网站根目录&#xff0c;然后解压&#xff0c;如下图所示: 第三步:打开浏览器&#xff0c;输入你的域名则会弹出如下图所示页面&#xff0c;点击同意协议并安装 第四步:同意安装后&…

Chrome浏览器插件第三方下载网站[创意网站,有趣网址]

国内大多数浏览器都是基于Chromium开源项目制作的&#xff0c;如&#xff1a;360浏览器、QQ浏览器等&#xff0c;理论上都支持安装Chrome 网上应用店内的插件&#xff0c;但是因为某些客观原因&#xff0c;国内无法正常访问Chrome 网上应用店&#xff0c;浏览器自带的插件商店往…

网传分享的Wordpressripro主题4.8版本后门分析_盾给网下载修复文件[建站教程]

关于最近网传的日主题ripro4.8版本破解版的后门问题&#xff0c;源码分享源头不清楚&#xff0c;盾给网也是转载免费分享&#xff0c;没想到中了套路。所有在网络上&#xff08;无论是盾给源码下载网或是其他网站&#xff09;下载到ripro4.8源码的朋友请好好阅读此文章&#xf…

网站有CDN怎么查询源ip?源站开启邮件通知后,分分钟拿到[运维教程]

网站有CDN怎么查询源ip&#xff1f;源站开启邮件通知后&#xff0c;分分钟拿到[运维教程] 有很多站长为了保护自己的没有防御的服务器&#xff0c;都套上了CDN。虽然套CDN可以让网站不被轻易攻击拿下&#xff0c;但是稍有疏忽&#xff0c;就暴露了自己源站服务器的IP地址。为了…

大型网站的 HTTPS 实践(一)—— HTTPS 协议和原理

声明&#xff1a;本系列文章&#xff08;共约4篇&#xff09;转发自酷勤网&#xff0c;中间有我个人的修改或者注释。 前言 百度已经于近日上线了全站 HTTPS 的安全搜索&#xff0c;默认会将 HTTP请求跳转成HTTPS。本文重点介绍HTTPS协议, 并简单介绍部署全站HTTPS的意义。 …

大型网站的 HTTPS 实践(二)——HTTPS 对性能的影响

前言 HTTPS在保护用户隐私&#xff0c;防止流量劫持方面发挥着非常关键的作用&#xff0c;但与此同时&#xff0c;HTTPS 也会降低用户访问速度&#xff0c;增加网站服务器的计算资源消耗。 本文主要介绍 https 对用户体验的影响。 HTTPS 对访问速度的影响 在介绍速度优化策…

从零开始搭建自己的VueJS2.0+ElementUI单页面网站(一、环境搭建)

前言 VueJS可以说是近些年来最火的前端框架之一&#xff0c;越来越多的网站开始使用vuejs作为前端框架&#xff0c;vuejs轻量、简单的特性使得前端开发变得更加简易&#xff0c;而基于vuejs的前端组件库也越来越多。我们今天使用的ElementUI&#xff0c;是饿了么团队开发的一款…

从零开始搭建自己的VueJS2.0+ElementUI单页面网站(二、编写导航页)

前言 在从零开始搭建自己的VueJS2.0ElementUI单页面网站&#xff08;一、环境搭建&#xff09;一文中我们已经配置好了开发所需要的各种环境&#xff0c;在这一篇博文中我们正式进入开发。对于一个单页面应用来说&#xff0c;导航页是至关重要的一个页面&#xff0c;所有的组件…

从零开始搭建自己的VueJS2.0+ElementUI单页面网站(三、组件编写及通信)

前言 本文是本系列的第三篇文章。在前两篇文章中我们介绍了关于搭建vueelementUI开发环境的方法和编写导航页的方法。关于前两篇文章的内容&#xff0c;若读者有些记不清楚&#xff0c;可以点击下方链接快速查看&#xff1a; 从零开始搭建自己的VueJS2.0ElementUI单页面网站&…

搭建个人网站之一:在windows10上利用wampserver+wordpress搭建网站环境

1.安装wampserver&#xff0c;首先下载好wapserver.exe文件&#xff0c;以管理员身份运行如图1所示&#xff0c;记得选择安装mysql数据库。安装成功后启动wampserver&#xff0c;如图2显示 all services running&#xff0c;即表示安装成功&#xff0c;如果显示部分服务打开&am…

如何解决Chrome “无法从该网站添加应用,扩展程序和用户脚本”提示?

如何解决Chrome “无法从该网站添加应用&#xff0c;扩展程序和用户脚本”提示&#xff1f; Chrome最新版已经禁止安装本地插件&#xff0c;也就是说&#xff0c;禁止离线安装扩展crx。 如图&#xff1a; 使用破解工具——Chrome插件伴侣&#xff0c;可保证无损&#xff0c;轻…

飞鸽传书2009绿色版 官方网站下载地址

飞鸽传书2009绿色版 如何使用 本教程演示如何使用 OpenLaszlo 平台和 飞鸽传书2009绿色版 Web 服务来开发、打包和部署一个已编写好的富 Internet 客户机。富客户端利用了后端的服务&#xff08;这些后端服务是通过使用 SOAP Web 服务的通用 SOA 方法提供&#xff09;。还将了解…

ZFAKA网站搬家注意事项

如果是搬家请确保两边环境相同&#xff0c;PHP版本相同、mysql版本相同 PHP7.2安装yaf扩展 修改配置文件 最下面填写 yaf.use_namespace1 1.nginx下rewrite规则 location / {if (!-e $request_filename) {rewrite ^/(.*)$ /index.php?$1 last;}} 2.apache下rewrite规则 #.h…