Correcting teacher:PHPz
Correction status:qualified
Teacher's comments:
<template>
<div class="fui-fullHigh-group">
<div class="fui-fullHigh-item menu">
<div class="nav" :class="on==index?'on':''" @click="edit_cat(index)" v-for="(item,index,key) in cat" :key="key" >{{item.name}}</div>
</div>
<div class="fui-fullHigh-item container">
<div class="fui-icon-group" v-for="(item,index,key) in cat" :key="key">
<div v-if="on==index">
<router-link :to="'/goods_lists?id='+item.cid" v-for="(items,indexs,keys) in item.son" :key="keys">
<div class="fui-icon-col">
<div class="icon">
<img class="img" :src="items.pic" />
</div>
<div class="text">{{items.name}}</div>
</div>
</router-link>
</div>
</div>
</div>
</div>
</template>
<script>
import { reactive, toRefs } from "vue";
import { GoodsIndex } from "../../network/index.js";
export default({
setup() {
const data = reactive({
on : 1,
cat: []
});
const edit_cat = (e)=>{
data.on = e;
}
GoodsIndex().then( (e)=>{
data.cat = e.data;
});
return {
title:"分类",
...toRefs(data),
edit_cat
}
}
})
</script>
<style scoped>
.fui-fullHigh-group{
position: absolute;
top: 0;
bottom: 0;
width: 100%;
display: flex;
}
/* 左侧 */
.fui-fullHigh-item{
height: inherit;
width: 100%;
background: #fff;
overflow-y: auto;
}
.fui-fullHigh-item.menu {
width: 5.25rem;
background: #f8f8f8;
}
.fui-fullHigh-item.menu .nav {
font-size: 28rpx;
text-align: center;
color: #000;
padding: 0.2rem 0;
height: 2.5rem;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
position: relative;
display: flex;
justify-content:center;
align-items:Center;
}
.fui-fullHigh-item.menu .on {
background: #fff;
position: relative;
color: #ff5555;
}
/* 右侧 */
.fui-fullHigh-item.container {
position: relative;
padding: 0.8rem;
flex: 1;
}
.fui-icon-group {
position: relative;
overflow: hidden;
background: #fff;
display: flex;
flex-wrap: wrap;
}
.fui-icon-group .fui-icon-col {
height: auto;
position: relative;
padding: 0.5rem 0;
text-align: center;
transition: background-color 300ms;
-webkit-transition: background-color 300ms;
float: left;
border: none !important;
}
.fui-icon-group .fui-icon-col {
float: left;
margin-right: 17px;
padding-top: 10px;
}
.fui-icon-group .fui-icon-col .icon {
height: 115px;
width: 100%;
margin: auto;
text-align: center;
line-height: 2.2rem;
}
.icon {
font-family: "icon" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.img {
width: 115px;
height: 100%;
}
.fui-icon-group .fui-icon-col .text {
font-size: 24px;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 0.2rem;
color: #000;
}
.fui-icon-group .fui-icon-col .text {
font-size: 0.55rem;
line-height: 1.05rem;
padding-top: .5rem;
}
</style>
<template>
<!-- 修复only one root问题 -->
<div>
<Header :title="title"></Header>
<div style="background:#f3f3f3;">
<!-- 商品列表 -->
<div class="fui-content">
<div class="fui-content-inner">
<div class="fui-goods-group block">
<!-- 单个商品 -->
<div class="fui-goods-item" @click="go_url()" v-for="(item,index,key) in lists" :key="key">
<img class='image' :src="item.img_s"/>
<div class="name">{{item.title}}</div>
<div style="line-height:0.7rem;height:0.7rem;color:#b2b2b2;font-size:0.6rem;margin-top: .2rem;text-decoration: line-through"></div>
<div class="price">
<span class="text">¥100</span>
<span class="buy">销量:10</span>
</div>
</div>
</div>
<button v-if="is_btn" class="ant-btn ant-btn-primary" style="width:100%;" @click="xiala()">加载更多</button>
</div>
</div>
</div>
</div>
</template>
<script>
import Header from '../../components/Header.vue';
import { reactive, toRefs } from "vue";
import { useRoute,useRouter } from "vue-router";
import { GoodsLists } from "../../network/index.js";
export default({
components:{
Header
},
setup() {
const route = useRoute();
const router = useRouter();
const go_url = ()=>{
router.push("/goods_details");
}
const data = reactive({
lists: [],
page: 1,
num: 1,
is_btn:true
});
GoodsLists({id:route.query.id, p : data.page}).then( (e)=>{
data.lists = e.data.lists;
data.num = e.data.num;
if(data.page >= data.num){
data.is_btn = false;
}
} )
const xiala = ()=>{
data.page = data.page+1;
if(data.page <= data.num){
GoodsLists({id:route.query.id, p : data.page}).then( (e)=>{
data.lists = data.lists.concat(e.data.lists)
})
if(data.page >= data.num){
data.is_btn = false;
}
}
}
return {
go_url,
title:"列表",
...toRefs(data),
xiala
}
}
})
</script>
<style scoped>
/* 顶部筛选 */
.sort {
position: relative;
width: 100%;
padding: .4rem 0;
background: #fff;
-webkit-box-align: center;
border-bottom:1px solid #e7e7e7;
}
.sort .item {
position: relative;
width: 1%;
display: table-cell;
text-align: center;
font-size: 0.7rem;
border-left: 1px solid #e7e7e7;
color: #666;
}
.sort .item:first-child {
border: 0;
}
.on .text{
color: #fd5454;
}
/* 商品 */
.fui-content {
position: absolute;
right: 0;
left: 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
.fui-content-inner {
box-sizing: border-box;
border-top: 1px solid transparent;
margin-top: -1px;
}
.fui-goods-group {
height: auto;
overflow: hidden;
background: #f9f9f9;
}
.fui-goods-group.block {
padding: 0.2rem;
}
/* 单个商品 */
.fui-goods-group .fui-goods-item {
width: 50%;
float: left;
border-bottom: 0;
background: none;
padding: 0.25rem;
display: block;
}
.fui-goods-item {
position: relative;
height: auto;
padding: 0.8rem;
border-bottom: 1px solid #e7e7e7;
background: #fff;
overflow: hidden;
display: flex;
}
.image {
width: 100%;
overflow: hidden;
margin: 0;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
position: relative;
float: none;
}
/* 商品名 */
.detail {
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
background: #fff;
padding-left: 0.5rem;
padding: 0.5rem;
}
.name {
height: 1.7rem;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
font-size: 0.65rem;
line-height: 0.9rem;
margin-top: 0;
color: #262626;
}
.price {
position: relative;
display: flex;
align-items: center;
font-size: 0.7rem;
margin-top: 0;
}
.price .text {
flex: 1;
color: #ff5555;
font-size: 0.8rem;
}
.buy {
text-align: center;
color: #666;
font-size: 0.6rem;
}
.ant-btn {
line-height: 1.5715;
position: relative;
display: inline-block;
font-weight: 400;
white-space: nowrap;
text-align: center;
background-image: none;
border: 1px solid transparent;
box-shadow: 0 2px 0 rgb(0 0 0 / 2%);
cursor: pointer;
transition: all .3s cubic-bezier(.645,.045,.355,1);
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
touch-action: manipulation;
height: 32px;
padding: 4px 15px;
font-size: 14px;
border-radius: 2px;
color: rgba(0,0,0,.85);
background: #fff;
border-color: #d9d9d9;
}
.ant-btn-primary {
color: #fff;
background: #1890ff;
border-color: #1890ff;
text-shadow: 0 -1px 0 rgb(0 0 0 / 12%);
box-shadow: 0 2px 0 rgb(0 0 0 / 5%);
}
</style>
<?php
namespace app\api\controller;
use think\facade\Db;
use think\facade\Request;
class Api{
// Access to XMLHttpRequest at 'http://www.tp.com/index.php/api/Api/index'
// from origin 'http://localhost:8080' has been blocked by CORS policy: No
// 'Access-Control-Allow-Origin' header is present on the requested resource.
// 错误信息:是因为前后端分离导致的。前后端 前端和后端的域名不是一个。不是一个,就会出现这种错误。
// 跨域名访问的安全错误提示
// public function __construct(){
// // 使用php的header函数,设置为*,全部能访问
// header("Access-Control-Allow-Origin:*");
// header("Content-Type : application/json; charset=utf-8");
// // header("Access-Control-Allow-Headers:content-type");
// // header("Access-Control-Request-Method:GET,POST");
// }
public function index(){
// 如何写一个 前端数据接口呢?app、小程序、vue
// 接口:让2个以上的项目进行数据联通,数据交互
// 多个语言 必须有统一的格式, 最后返回值,必须多种语言都能使用
// 接口的统一数据格式是 json
// php有json的函数
// json_encode 把php的数据加密成json格式
// json_decode 把json格式转为 php数据格式
// $arr = [
// "ouyangke" => "欧阳克",
// "miejue" => "灭绝师太",
// "php" => [
// "ouyangke",
// "miejue"
// ],
// "tianpeng" => "朱天蓬"
// ];
// json格式,是文本,我们就可以echo
// {"ouyangke":"\u6b27\u9633\u514b","miejue":"\u706d\u7edd\u5e08\u592a","tianpeng":"\u6731\u5929\u84ec"}
// echo json_encode($arr);
// 1、接口 必须用json返回数据
// 2、用数组 转为json数据
$ad = Db::table('oyk_adver')->where('status',1)->order('sort DESC')->select()->toArray();
$lists = Db::table('oyk_shop_lists')->where('status',1)->order('add_time DESC')->limit(6)->select()->toArray();
// & 取之前的地址
foreach($lists as &$v){
$img = explode(';',$v['img']);
$v['img_s'] = $img[0];
}
// 3、接口只能一次性返回数据,不能多次
// echo json_encode($ad);
// echo json_encode($lists);
$arr = [
'ad' => $ad,
'lists' => $lists
];
echo json_encode($arr);
}
public function goods_index(){
$cat = DB::table('oyk_shop_cat')->where('status',1)->order('pid,sort DESC')->select()->toArray();
$tmp = [];
foreach($cat as $v){
if($v['pid'] == 0){
$tmp[$v['cid']] = $v;
}else{
$tmp[$v['pid']]['son'][] = $v;
}
}
$arr = [
'code' => 0,
'msg' => '成功',
'data' => $tmp
];
echo json_encode($arr);
}
public function goods_lists(){
$page = input('post.p');
$id = input('post.id');
$count = Db::table('oyk_shop_lists')->where('status',1)->where('cid',$id)->count();
$lists = Db::table('oyk_shop_lists')->where('status',1)->where('cid',$id)->page($page,5)->select()->toArray();
foreach($lists as &$v){
$img = explode(';',$v['img']);
$v['img_s'] = $img[0];
}
$arr = [
'code' => 0,
'msg' => '成功',
'data' => [
'lists' => $lists,
'num' => ceil($count/5)
]
];
echo json_encode($arr);
}
}
import {request} from "./request.js";
export function Index(){
return request( {
method : "POST",
url : "Api/index"
} )
}
export function GoodsIndex(){
return request( {
method : "POST",
url : "Api/goods_index"
} )
}
export function GoodsLists(data){
return request({
method: "POST",
data: data,
url : "Api/goods_lists",
})
}
<?php
// 全局中间件定义文件
return [
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
// \think\middleware\SessionInit::class
// 跨域请求
\think\middleware\AllowCrossDomain::class
];