vue-day14----mock数据(模拟数据)、details路由下详情(Detail)和评价(Assess)页面切换到商品(Goods)页面-localStorage、Assess组件(AssessList)数据渲染-父传子、评价和晒图页面切换-toggle传不同的参数重新请求、上拉加载更多-better-scroll
### mock数据(模拟数据)
json-server:
安装:npm install json-server -g(cmd终端中安装)
启动服务:json-server goods.json
mock.js:
安装:npm i mockjs
src下新建mock/test.js:
const mock=require("mockjs");// node方式 let data=mock.mock({ "data|10":[ { "id|+1":0, "number|1-100":100, "string|1-10":"*", "list|1-10":["吴小明","孙艺珍"], "obj":{ "arr|3":["吴小明","孙艺珍"] }, "ip":"@ip", "color":"@color()" } ] }) console.log(data)
通过node方式打开(终端执行node test.js),可以得到mock生成的数据。
### mock占位符
1、生成n条数据:
{
"success":true,
"data|5":[{}]
}
"data"|N:N代表生成多少条数据
2、图片占位符
"imgUrl":"@image('600x400', '#f00', '#fff', 'jpg', '吴小明')"
参数一:图片的大小
参数二:图片背景颜色
参数三:字体颜色
参数四:图片文字
3、随机生成手机号
"tel":/^1(3|5|7|8)\d{9}$/
正则可以任意匹配字符
4、时间占位符
"time":"@datetime('yyyy-MM-dd A HH:mm:ss')"
5、颜色占位符
"color":"@color()"
6、文本占位符
英文段落:
"txt":"@paragraph()"
中文段落:
"txt":"@cparagraph()"
中文句子:
"txt":"@cparagraph()"
中文标题:
"title":"@ctitle()"
英文名字:
"name":"@name"
中文名字:
"name":"@cname"
7、ip占位符
"ip":"@ip"
8、随机生成收获地址
"address":"@county(true)"
9、字符串
"string|1-10":"*"
随机生成1-10之间的小星星
10、数字
"number|1-100":100
随机生成1-100之间的数字
"id|+1":1
每次生成的id值加1
11、数组对象
"goods|1-10":[
{
"name":"@cname"
}
]
12、数组
"list|1-10":["吴小明","孙艺珍"]
13、对象数组
"obj":{
"arr|3":["吴小明","孙艺珍"]
}
### mock在项目中使用-没有跨域问题
①安装:npm i mockjs
②src下新建mock/index.js:
import mock from "mockjs";// ES6方式 let data=mock.mock({ "data|10":[ { "id|+1":0, "username":"@cname", "tel":/^1(3|5|7|8|9)\d{9}$/, "imgUrl":"@image('600x400', '#f00', '#fff', 'jpg', '吴小明')", "address":"@county(true)", "date":"@datetime('yyyy-MM-dd A HH:mm:ss')", "desc":"@cparagraph(1,5)", "list|5":[ { "imgUrl":"@image('600x400', '#f00', '#fff', 'jpg', '吴小明')" } ], "info|2":{ "goodsInfo":"@csentence(5)" } } ] }) /* mock.mock({})----模拟数据 mock.mock(url,method,()=>{})----模拟接口 */ mock.mock(/\/users\/list/,"get",(options)=>{ url地址要写成正则,不要写成字符串;get和post必须是小写,前端请求时的get可以是大写也可以是小写。 console.log(options) return data; }) // mock.mock(/\/users\/list/,"post",(options)=>{ // console.log(options) // return data; // })
③main.js中引入:import "./mock/index.js";
④组件中使用:
import axios from "axios";
created() { axios({ url:"/users/list", method:"get", params:{username:"wql"}, // method:"post", // data:{username:"wql"} }).then((data)=>{ console.log(data) }) }
这样就可以拿到mock模拟的数据。
### details路由下详情(Detail)和评价(Assess)页面切换到商品(Goods)页面-localStorage
①Goods.vue中接收到product_id时用localStorage存储起来:
props:["product_id"], watch: { product_id:{ async handler(newValue){ if(!newValue){ newValue=localStorage.getItem("product_id"); } localStorage.setItem("product_id",this.product_id); this.getAsyncDetailGoods(newValue); let data=await detailsCommentApi(newValue); this.detailsComment=data.data.data; }, immediate:true } }
②DetailHeader.vue组件中接收:
created() { this.product_id=localStorage.getItem("product_id"); }
③DetailHeader.vue组件中路由跳转时拼接:
<ul> <router-link :to="'/details/goods/'+product_id" tag="li">商品</router-link> <router-link to="/details/detail" tag="li">详情</router-link> <router-link to="/details/assess" tag="li">评价</router-link> </ul>
### Assess组件(AssessList)数据渲染-父传子
①api/index.js中添加 detailsCommentList 接口:
// details接口 details:{ detailsGoods:"/v3/detail", detailsComment:"/v3/comment",//评价 detailsCommentList:"/v3/commentList",// 评价列表 },
②api/request.js中定义获取数据的api(detailsCommentListApi):
// 获取details评价列表 export const detailsCommentListApi=(data)=>{ return http({ method:"get", data:{...data},// 根据请求数据时所传的值解构 url:api.details.detailsCommentList }) }
③pages/Details/Assess.vue中引入:
import {detailsCommentListApi} from "@api/request.js";
④pages/Details/Assess.vue中获取数据:
data(){ return{ product_id:"", curr_page:1, show:1, commentList:[] } }, methods: { async getDetailsCommentList(data){ let response=await detailsCommentListApi(data); this.commentList=response.data; } }, created() { this.product_id=localStorage.getItem("product_id"); let data={ product_id:this.product_id, curr_page:this.curr_page, show:this.show, } this.getDetailsCommentList(data); }
⑤pages/Details/Assess.vue中将获取到的 commentList 传递给 AssessList 组件:
<AssessList :commentList="commentList"></AssessList>
⑥AssessList 组件中通过props接收:
props:{ commentList:{ type:Array, default:[] } },
⑦遍历commentList渲染页面:
v-for="item in commentList" :key="item.id"
### 评价和晒图页面切换-toggle传不同的参数重新请求
分析:当进入评价页面时,此时显示的是“评价”对应的数据,当点击“晒图”时显示“晒图”对应的数据,“晒图”是“评价”中带有带有图片的数据。
其中,“评价”的show为1,没有comment_type值;“晒图”的show为空,comment_type值为1。
①pages/Details/Assess.vue中,为“评价”和“晒图”两个选项卡绑定tap事件,“评价”传show为1,“晒图”传show为空:
<!-- 选项卡 --> <div class="assess-tab-menu"> <ul> <v-touch tag="li" :class="show?'active':''" @tap="toggle(1)">评价 5</v-touch> <v-touch tag="li" :class="show?'':'active'" @tap="toggle('')">晒图 2</v-touch> </ul> </div>
②pages/Details/Assess.vue中,methods中添加toggle()方法:
toggle(show){ this.show=show; let comment_type; if(show==1){ comment_type=null; }else if(show==""){ comment_type=1; } let data={ product_id:this.product_id, curr_page:this.curr_page, show:this.show, comment_type:comment_type } this.getDetailsCommentList(data); }
### 上拉加载更多-better-scroll
better-scroll事件:
pullingDown----下拉加载
pullingUp----上拉加载更多
better-scroll配置项:
pullDownRefresh:true----开启下拉刷新
pullUpLoad:true----开启上拉加载
better-scroll方法:
finishPullDown()----告诉better-scroll可以进行下一次下拉刷新
finishPullUp()----告诉better-scroll可以进行下一次上拉加载
refresh()----重新计算better-scroll,确保滚动效果正常
Detail/Assess.vue页面做上拉加载更多:
①plugins/BScroll/index.vue中,better-scroll配置项中添加 pullUpLoad:true :
pullUpLoad:true
②plugins/BScroll/index.vue中,添加 pullingUp() 和 finishPullUp() 方法:
// 上拉加载更多 pullingUp(callback){ this.BScroll.on("pullingUp",()=>{ callback(); }); }, // 告诉better-scroll可以进行下一次上拉加载 finishPullUp(){ this.BScroll.finishPullUp();// 重新计算better-scroll this.BScroll.refresh(); }
③pages/Details/Assess.vue中,为需要上拉加载的盒子套上<BScroll></BScroll>标签,绑定ref属性:
<BScroll ref="BScroll"> <AssessList :commentList="commentList"></AssessList> </BScroll>
④pages/Details/Assess.vue中,调用 BScroll 组件中定义的 pullingUp()(this.$refs.ref属性值.方法),传入回调函数 pullUpMore():
mounted() { // 上拉加载更多 this.$refs.BScroll.pullingUp(this.pullUpMore); }
⑤methods中pullUpMore()方法用来重新请求数据,重点是curr_page++,拿到数据后和原数据做拼接(解构):
async pullUpMore(){ let comment_type; if(this.show==1){ comment_type=null; }else if(this.show==""){ comment_type=1; } this.curr_page++; let data={ product_id:this.product_id, curr_page:this.curr_page, show:this.show, comment_type:comment_type } let response=await detailsCommentListApi(data); this.commentList=[...this.commentList,...response.data]; }
⑥但是现在上拉加载只会执行第一次,因为还没有执行better-scroll的 finishPullUp() 方法,这个方法在 BScroll 组件中已经定义为 finishPullUp() 方法,每次当数据(commentList)进行变化的时候,需要执行到 BScroll 组件中的 finishPullUp() :
watch: { commentList:{ handler(){ // 第一次加载进来不用触发 finishPullUp() if(this.curr_page!=1){ this.$refs.BScroll.finishPullUp(); } }, deep:true } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结