响应式综合运用

Reactivity

实验题目
产品列表页
产品详情页
实验目的
掌握类 class 和样式 style 的基本使用
掌握计算属性 Computed 的基本使用
掌握条件渲染 v-if 的基本使用
掌握列表渲染 v-for 的基本使用
掌握响应式数据 ref()、reactive() 的基本使用
初步了解路由的使用
进一步熟悉资源服务器的搭建和使用*
实验内容

.使用静态数据完成组件的开发和设计

产品列表页 Goods.vue
产品详情页 DetailsView.vue;其中甜品 dessert、推荐 recommend 可以先不组件化设计,后续内容学习完再优化为组件;其它部分可以根据情况组件化设计,如轮播图可以设计为组件
其它设计*

.定制滚动条 scrollbar

.阿里字体图标 Iconfont

.主题切换

后端*

.搭建数据服务器;可以使用自己熟悉的服务器环境

.准备 json 数据;可以使用 大树小站 提供的在线资源数据,也可以自己设计数据

.启动服务,响应用户的数据请求

.前端:从数据服务器拉取数据并渲染

参考效果和参考代码
参考数据:https://glpla.github.io/utils/data/coffee.json;其中一个节点信息如下;图片仅给出部分地址;实际使用时,要拼接上服务器地址;如果没有服务器支撑,请使用本地图片或在线图片
{
  "id": 0,
  "name": "桂院螺蛳粉",
  "desc": "Lorem ipsum dolor sit, amet consectetur adipisicing elit",
  "img": "/coffee/coffee0.jpg",
  "price_original": 15,
  "price": 12,
  "discount": 0.2,
  "flavour": "辛辣",
  "is_follow": false,
  "stock": 100,
  "cup": [
    { "id": 1, "tag": "中杯", "sel": true },
    { "id": 2, "tag": "大杯", "sel": false },
    { "id": 3, "tag": "超大杯", "sel": false }
  ],
  "ther": [
    { "id": 0, "tag": "热", "sel": false },
    { "id": 1, "tag": "冰", "sel": true }
  ],
  "sugar": [
    { "id": 0, "tag": "半糖", "sel": false },
    { "id": 1, "tag": "标准糖", "sel": false },
    { "id": 2, "tag": "不加糖", "sel": true }
  ],
  "dessert": [
    {
      "id": 1,
      "img": "/dessert/dessert1.png",
      "title": "adipisicing elit",
      "priceOrignal": 5,
      "discount": 0.3
    },
    {
      "id": 2,
      "img": "/dessert/dessert2.png",
      "title": "consectetur elit",
      "priceOrignal": 8,
      "discount": 0.4
    },
    {
      "id": 3,
      "img": "/dessert/dessert3.png",
      "title": "sit amet elit",
      "priceOrignal": 10,
      "discount": 0.5
    }
  ],
  "recommend": [
    {
      "id": 1,
      "img": "/coffee/coffee1.jpg",
      "title": "lorem ipsum dolor",
      "desc": "lorem ipsum dolor sit amet consectetur elit",
      "priceOrignal": 12
    },
    {
      "id": 2,
      "img": "/coffee/coffee2.jpg",
      "title": "lorem ipsum dolor",
      "desc": "lorem ipsum dolor sit amet consectetur adipisicing",
      "priceOrignal": 15
    },
    {
      "id": 3,
      "img": "/coffee/coffee3.jpg",
      "title": "lorem ipsum dolor",
      "desc": "lorem ipsum dolor sit amet adipisicing elit",
      "priceOrignal": 20
    }
  ]
}
参考结构
<div class="goods">
  <template v-if="goods.length">
    <div class="item" v-for="(item, ind) in goods" :key="item.id">
      <img class="img" :src="'https://glpla.github.io/utils' + item.img" alt="">
      <div class="info">
        <h4 class="title">{{ item.name }} <span class="flavour">{{ item.flavour }}</span> </h4>
        <div class="desc">{{ item.desc.repeat(2) }}</div>
        <div class="price">¥{{ item.price }} <span class="price-inner">(市场价<span>¥{{ item.price_original
              }}</span>)</span> </div>
        <div class="price-discount">预估到手 <span>¥{{ getDiscount(item) }}</span></div>
      </div>
      <div class="btn" @click="addCart(item)">
        <span class="iconfont icon-gouwuche_o"></span>
      </div>
    </div>
  </template>
  <div v-else>lists empty</div>
</div>
参考逻辑 - 数据获取需要服务器支撑
import { computed, onMounted, ref } from 'vue';

const goods = ref([])

const getDiscount = computed(() => {
  return item => {
    return (item.price * (1 - item.discount)).toFixed(2)
  }
})

onMounted(() => {
  let json = fetch('https://glpla.github.io/utils/data/coffee.json')
    .then(response => response.json())
    .then(data => {
      console.log(data.cont);
      goods.value = data.cont
    })
})
参考效果
产品列表页 Goods.vue
产品详情页 DetailsView.vue
产品详情页 DetailsView.vue
消费者权益保护 Guarantee.vue
拓展与思考
组件化

.产品组件

.轮播图

逻辑优化

.数据分页

.触底加载

.数据加载指示器以及动画

保存/推送项目到自己的代码仓库