惠州市 网站开发公司重庆建站免费模板
惠州市 网站开发公司,重庆建站免费模板,中太建设集团官方网站,杭州百度快照文章目录一、专题页1. 效果图2. 专题api2.Topic.vue 组件3. 专题源码二、分类页2.1. 效果图2.2. 分类api2.3. Category.vue 组件三、购物车页3.1. 效果图3.2. 购物车api3.3. 购物车页面四、我的页4.1. 效果图4.2. 定义api4.3. User.vue五、路由守卫和异常处理5.1. 编写路由守卫…
文章目录一、专题页1. 效果图2. 专题api2.Topic.vue 组件3. 专题源码二、分类页2.1. 效果图2.2. 分类api2.3. Category.vue 组件三、购物车页3.1. 效果图3.2. 购物车api3.3. 购物车页面四、我的页4.1. 效果图4.2. 定义api4.3. User.vue五、路由守卫和异常处理5.1. 编写路由守卫5.2. 异常处理技术选型组件版本说明vue^2.6.11数据处理框架vue-router^3.5.3动态路由vant^2.12.37移动端UIaxios^0.24.0前后端交互amfe-flexible^2.2.1Rem 布局适配postcss-pxtorem^5.1.1Rem 布局适配less^4.1.2css编译less-loader^5.0.0css编译vue/cli~4.5.0项目脚手架
vue-cli vant less axios 开发
一、专题页
1. 效果图 2. 专题api
在http.js文件中定义接口请求
//5. 专题页 Topic
//专题请求
export function GetTopicApi(params) {return instance({url: /topic/list,method: get,params})
}2.Topic.vue 组件 3. 专题源码
!-- 专题页 --
templatediv classzhuantidiv classbox v-foritem in data :keyitem.idimg :srcitem.scene_pic_url alt /div classtitle{{ item.title }}/divdiv classtip{{ item.subtitle }}/divdiv classprice{{ item.price_info | moneyFlrmat }}/div/div!-- 分页器 --van-paginationv-modelcurrentPage:page-counttotalPagesmodesimplechangeChangeFn//div
/templatescript
import { getTopicList } from /https/http.js;export default {data() {return {currentPage: 1, //当前页pageSize: 10, // 每页的条数data: [], //数据totalPages: 2, //总页数};},methods: {getPage() {getTopicList({page: this.currentPage,size: this.pageSize,}).then((res) {console.log(res555, this.currentPage);console.log(res555, res);let { count, currentPage, data, pageSize, totalPages } res.data;this.currentPage currentPage; //当前页this.data data; //数据this.totalPages totalPages; //总页数this.pageSize pageSize; // 每页的条数// 返回顶部document.documentElement.scrollTop 0;});},ChangeFn() {// 会直接改变currentPageconsole.log(this.currentPage);this.getPage();},},created() {this.getPage();},
};
/script
style langless scoped
/deep/.van-pagination__page-desc {display: none;
}
.zhuanti {padding-bottom: 100px;box-sizing: border-box;.box {width: 100%;font-size: 14px;line-height: 40px;text-align: center;img {width: 100%;}.title {font-size: 18px;}.price {color: red;}}
}
/style二、分类页
2.1. 效果图 点击左侧导航更换数据
2.2. 分类api
在http.js 文件中定义接口请求
//6. 分类页 Category
// 全部分类数据接口
export function GetChannelDataApi(params) {return instance({url: /catalog/index,method: get,params})
}
// 获取当前分类数据
export function GetFenleiDataApi(params) {return instance({url: /catalog/current,method: get,params})
}2.3. Category.vue 组件 !-- 分类页 --
templatediv classcategory-box!--搜索框 --van-search v-modelvalue show-action placeholder请输入搜索关键词 /div classfenlei!-- 左侧导航 --van-sidebar v-modelactiveKey changeonChangevan-sidebar-item:titleitem.namev-foritem in categoryList:keyitem.id//van-sidebar!-- 右侧主体 --main!-- 上方图片 --div classpic-areaimg :srccurrentCategory.banner_url alt /p classdesc{{ currentCategory.front_desc }}/p/div!-- 标题 --div classmytitlespan/spanh3{{ currentCategory.name }}/h3/div!-- 图文混排 --van-grid :column-num3 van-grid-itemv-foritem in subCategoryList:keyitem.id:iconitem.wap_banner_url:textitem.name//van-grid/main/div/div
/templatescript
import { GetChannelDataApi, GetFenleiDataApi } from /https/http;export default {data() {return {activeKey: 0,value: ,categoryList: [], //导航数据currentCategory: {}, //选中的类别数据,currentId: 0, subCategoryList:[] //子类数组};},methods: {// 左侧导航被点击index为选中的类别的索引值更换类别onChange(index) {this.activeKey index;this.currentCategory this.categoryList[this.activeKey] this.currentId this.categoryList[this.activeKey].id; //选中的类别的id// 获取当前分类数据this.GetCurrentCategory()},// 获取全部分类数据GetcategoryList() {GetChannelDataApi().then((res) {// console.log(res1, res);this.categoryList res.data.categoryList; //左侧导航数据//选中的类别的id默认第一个类别被选中this.currentId this.categoryList[0].id; // 当前显示的类别数据图片和标题使用this.currentCategory res.data.currentCategory; //当前显示的类别数据 图文混排区域使用this.subCategoryList res.data.currentCategory.subCategoryList; });},// 获取当前分类数据GetCurrentCategory() {GetFenleiDataApi({ id: this.currentId }).then((res) {// console.log(res12, res);// 当前显示的类别数据图片和标题使用this.currentCategory res.data.currentCategory; //当前显示的类别数据 图文混排区域使用this.subCategoryList res.data.currentCategory.subCategoryList;});},},created() {this.GetcategoryList(); // 获取全部分类数据}
};
/script
style scoped langless
/* import url(); 引入css类 */
.fenlei {display: flex;main {flex: 1;.pic-area {text-align: center;position: relative;height: 100px;font-size: 15px;img {width: 98%;border-radius: 5px;display: block;}.desc {position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);}}.mytitle {text-align: center;font-size: 16px;margin-top: 20px;position: relative;height: 50px;span {width: 50%;height: 2px;background-color: #ccc;display: inline-block;position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);}h3 {width: 30%;background-color: #fff;position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);}}}
}
/style三、购物车页
3.1. 效果图 3.2. 购物车api
在http.js 文件中定义接口
//7.购物车页 Cart
// 购物车列表
export function GetCartData(params) {return instance({url: /cart/index,method: get,params})
}3.3. 购物车页面
Cart.vue 在views/cart目录下.Cart.vue新建 组件代码如下
!-- 购物车页 --
templatediv classcart-boxdiv v-foritem in cartList :keyitem.id classcart-item!-- 每个商品前的按钮 --van-checkbox:nameitemclickonchxClickFn(item)classcheckbox-btnv-modelitem.checked/van-checkbox!-- 商品信息 --van-card :priceitem.retail_price :thumbitem.list_pic_urltemplate #numvan-stepperv-modelitem.numberchangeonChange(item.number, item.id)//template!-- 自定义标题删除按钮 --template #titlespan{{ item.goods_name }}/spanvan-iconnamedelete-oclassdelete-iconclickonDelete(item)//template/van-card/div!-- 按钮 --!-- 下方结算 --!-- vant显示的数字不对9999元会显示成99.99元所以需要乘以100 --van-submit-bar:pricecheckedGoodsAmount * 100button-text提交订单submitonSubmitvan-checkbox clickonClickCheckAll v-modelcheckedAll全选/van-checkboxtemplate #tip你的收货地址不支持同城送,span clickonClickEditAddress修改地址/span/template/van-submit-bar/div
/templatescript
import {GetCartData, UpdateCartData, DeleteCartData,ToggleCartCheckedData, DeleteCartData2
} from /https/http;export default {name: cart,data() {return {cartList: [], //商品总列表cartTotal: {}, //购物车数据// price: 0,goodsId: ,number: ,productId: ,id_: ,isChecked: 1,// productIdsList:[],productIds: ,checkedGoodsAmount: 0, //选中的商品的总金额checkedAll: 0,};},methods: {// 获取数据getData() {// 发送请求获取当前购物车的数据GetCartData().then((res) {console.log(11111, res);this.cartList res.data.cartList; //商品总列表this.cartTotal res.data.cartTotal; //购物车数据//选中的商品的总金额this.checkedGoodsAmount res.data.cartTotal.checkedGoodsAmount // 如果有选中的商品if (this.cartTotal.checkedGoodsCount 0) {// 选中的商品数量购物车内的所有商品总数量 时候全选按钮就会被选中if (this.cartTotal.checkedGoodsCount this.cartTotal.goodsCount) {this.checkedAll true} else { //不相等的时候全选按钮就不会被选中this.checkedAll false}} else { // 如果没有选中的商品全选按钮就不会被选中this.checkedAll false}});},// 删除单个商品的时候发送删除商品的请求onDelete(item) {DeleteCartData2({ productIds: item.product_id.toString() }).then((res) {if (res.errno 0) {this.getData() //重新请求购物车商品数据渲染}})},// 按下商品1或者-1按钮 购物车商品数量变化 ,onChange会接收变化的商品idonChange(value, id_) {this.cartList.forEach(item {// 找出对应的goods_id,numberif (item.id id_) {this.id_ id_this.goodsId item.goods_idthis.number item.numberthis.productId item.product_id}})// 发请求this.updateCartData()},// 购物车商品步进器功能接口 按下商品1或者-1按钮updateCartData() {// 直接发送更新数据请求将当前的商品数量带着UpdateCartData({goodsId: this.goodsId, id: this.id_,number: this.number, productId: this.productId}).then((res) {console.log(999, res);if (res.errno 0) {this.getData() //重新请求购物车商品数据渲染}})},// 点击商品单选按钮切换购物车商品选中状态发送请求onchxClickFn(item) {this.isChecked item.checked ? 1 : 0this.productIds item.product_id.toString()this.toggleCartCheckedData()},// 切换购物车商品选中状态发送请求toggleCartCheckedData() {console.log(this.isChecked);ToggleCartCheckedData({isChecked: this.isChecked,productIds: this.productIds}).then((res) {console.log(667, res);if (res.errno 0) {this.getData() //重新请求购物车商品数据渲染}})},// 点击全选切换购物车商品选中状态发送请求onClickCheckAll() {this.isChecked this.checkedAll ? 1 : 0let productIdAllList []this.cartList.forEach((item) {productIdAllList.push(item.product_id.toString())})this.productIds productIdAllList.join(,)this.toggleCartCheckedData()},// 提交onSubmit() { },// 编辑地址onClickEditAddress() { },},created() {this.getData();},
};
/script
style scoped langless
/deep/.van-checkbox__label {flex: 1;
}
/deep/.van-checkbox {margin-bottom: 2px;
}
/deep/.van-submit-bar {bottom: 50px;
}
.cart-box {padding-bottom: 150px;box-sizing: border-box;.van-card {position: relative;}.delete-icon {position: absolute;top: 5px;right: 5px;}.cart-item {position: relative;padding-left: 40px;.checkbox-btn {position: absolute;left: 20px;top: 50%;transform: translate(-50%, -50%);}}
}
/style发送获取购物车数据列表时的响应数据 购物车商品步进器功能接口 切换购物车商品选中状态功能接口含全选响应数据
四、我的页
4.1. 效果图 4.2. 定义api
在http.js文件中定义接口请求
//登陆
export function GoLogin(params) {return instance({url: /auth/loginByWeb,method: post,data: params})
}
4.3. User.vue 在views/user 目录下新建User.vue 组件代码如下
!-- 我的 --
templatediv classuser-boxdiv classuser-topimg :srcavatarSrc alt /!-- 如果登陆了就显示用户名否则显示立即登录 --h3 v-ififLogined{{ username }}/h3!-- 点击登录显示模态框 --h3 clickljdl v-else点击登录/h3van-icon :nameifLogined ? cross : arrow clickloginout //div!-- 九宫格部分 --van-grid :column-num3van-grid-itemv-foritem in gridArr:keyitem.id:iconitem.icon:textitem.type//van-grid!-- 模态框 --div classmodal v-ififShowModaldiv classmodal-bg clickifShowModal false/divdiv classmodal-contentvan-form submitonSubmitvan-fieldv-modelusernamename用户名label用户名placeholder用户名:rules[{ required: true, message: 请填写用户名 }]/van-fieldv-modelpwdtypepasswordname密码label密码placeholder密码:rules[{ required: true, message: 请填写密码 }]/div stylemargin: 16pxvan-button round block typedanger native-typesubmit提交/van-button/div/van-form/div/div/div
/templatescript
// 引入登录接口
import { GoLogin } from /https/http;
import headImg from /assets/images/touxiang.png; //默认头像export default {name: user,data() {return {username: ,pwd: ,avatarSrc: headImg, //头像ifLogined: false, // 登录状态ifShowModal: false, // 是否显示模态框gridArr: [// grid数组{ id: 0, icon: label-o, type: 我的订单 },{ id: 1, icon: bill-o, type: 优惠券 },{ id: 2, icon: goods-collect-o, type: 礼品卡 },{ id: 3, icon: location-o, type: 我的收藏 },{ id: 4, icon: flag-o, type: 我的足迹 },{ id: 5, icon: contact, type: 会员福利 },{ id: 6, icon: aim, type: 地址管理 },{ id: 7, icon: warn-o, type: 账号安全 },{ id: 8, icon: service-o, type: 联系客服 },{ id: 9, icon: question-o, type: 帮助中心 },{ id: 10, icon: smile-comment-o, type: 意见反馈 },],};},created() {// 登陆前先看本人是否登陆过let user JSON.parse(localStorage.getItem(userInfo));// 用户名存在if (user) {this.username user.username; //用户名this.avatarSrc user.avatar; //头像this.ifLogined true; // 显示用户名}},methods: {// 点击立即登录显示登录模态框ljdl() {this.ifShowModal true; },// 提交用户名密码信息onSubmit() {this.getloginData(); //发送数据请求},// 发送数据请求登录注册getloginData() {GoLogin({ username: this.username, pwd: this.pwd }).then((res) {console.log(res);if (res.errno 0) {console.log(登录成功);this.$toast.success(登录成功);localStorage.setItem(token, res.data.token);localStorage.setItem(userInfo, JSON.stringify(res.data.userInfo));this.ifShowModal false; //不显示模态框this.ifLogined true; // 显示用户名this.avatarSrc res.data.userInfo.avatar; //头像this.username res.data.userInfo.username;}});},// 退出登录loginout() {// 登录了if (this.ifLogined) {this.$dialog.confirm({title: 退出登录,message: 是否退出登录,}).then(() {// on confirmthis.ifLogined false; // 不显示用户名this.avatarSrc headImg; //头像// 清除tokenlocalStorage.removeItem(token);localStorage.removeItem(userInfo);// 刷新当前页this.$router.go(0);// 刷新当前页this.$router.go(0);}).catch(() {// on cancel});}},},
};
/script
style langless scoped
.van-grid-item {padding: 20px;
}
.user-box {.user-top {display: flex;align-items: center;font-size: 16px;padding: 20px 10px;box-sizing: border-box;background-color: #333;color: white;img {width: 70px;height: 70px;margin-right: 10px;border-radius: 50%;}h3 {flex: 1;}}.modal {width: 100%;height: 100%;position: fixed; //position: fixed让height:100%起作用left: 0;top: 0;.modal-bg {width: 100%;height: 100%;background-color: rgba(0, 0, 0, 0.5);}.modal-content {width: 90%;height: 200px;box-sizing: border-box;// height: 200px;background-color: #fff;padding: 20px;position: absolute;left: 50%;top: 50%;transform: translate(-50%, -50%);z-index: 100;}}
}
/style五、路由守卫和异常处理
在router 目录下的index.js 文件中设置路由前置守卫代码如下用来判断购物车页面只能在用户登录的情况下才能查看。
5.1. 编写路由守卫 // 路由前置守卫
router.beforeEach((to, from, next) {// 有token就表示已经登录// 想要进入购物车页面必须有登录标识token// console.log(to:, to)// console.log(from:, from)let token localStorage.getItem(token)if (to.path /cart) {// 此时必须要有tokenif (token) {next(); // next()去到to所对应的路由界面} else {Vue.prototype.$toast(请先登录);// 定时器setTimeout(() {next(/user); // 强制去到/user所对应的路由界面}, 1000);}} else {// 如果不是去往购物车的路由则直接通过守卫去到to所对应的路由界面next()}
})
5.2. 异常处理
解决刷新页面底部tabbar显示错题。 computed:{active:{get(){console.log(this.$route.path)const path this.$route.pathswitch(path){case /home:return 0;case /topic:return 1;case /category:return 2;case /cart:return 3;case /user:return 4;default:return 0}},set(){}}}
2.编程式导航在跳转到与当前地址一致的URL时会报错但这个报错不影响功能
// 该段代码不需要记理解即可
const originalPush VueRouter.prototype.push;
VueRouter.prototype.push function push(location) {return originalPush.call(this, location).catch((err) err);
};
3.用户页引入头像
直接在标签中引入相对路径图片地址图片不显示需要使用如下模块式引入方式。
// import 方式
import headImg from ../assets/touxiang.png;// require 方式
let headImg require(../assets/touxiang.png)
项目优化—路由懒加载 当打包构建应用时JavaScript 包会变得非常大影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块然后当路由被访问的时候才加载对应组件这样就更加高效了。 {path: /home,//首页name: Home,component: () import(/views/Home),meta: { // 用来判断该组件对应的页面是否显示底部tabbarisShowTabbar: true}},
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/89984.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!