商品

Center
实验内容
商品列表页

. 数据加载和渲染

. 添加到购物车

. 查看详情

商品详情页

. 收藏

. 分享

. 选择规格、数量

. 查看评论

. 热门推荐

. 添加到购物车

. 直接下单

前置知识
数据绑定
状态管理
网络请求 Axios - GET
下拉刷新、触底加载 - 限自建服务器
开发环境
操作系统 Window 10+
文本编辑器 Vs Code
谷歌浏览器 Chrome
Node.js
数据接口
数据接口
/utils/data/coffee.json
商品节点数据 - 可根据需要调整
{
  "id": 1,
  "name": "桂院牛肉面",
  "desc": "Lorem ipsum dolor sit, amet consectetur adipisicing elit.",
  "img": "/coffee/coffee1.jpg",
  "priceOrignal": 14,
  "price": 12,
  "discount": 0.2,
  "flavour": "卤香",
  "isFollow": false,
  "stock": 100,
  "cup": [
    {
      "tag": "中杯",
      "sel": true
    },
    {
      "tag": "大杯",
      "sel": false
    },
    {
      "tag": "超大杯",
      "sel": false
    }
  ],
  "ther": [
    {
      "tag": "热",
      "sel": false
    },
    {
      "tag": "冰",
      "sel": true
    }
  ],
  "sugar": [
    {
      "tag": "不另外加糖",
      "sel": true
    },
    {
      "tag": "半糖",
      "sel": false
    },
    {
      "tag": "标准糖",
      "sel": false
    }
  ]
}
参考代码 - 一般实现
触底加载 - 更多细节,请访问 HTML - scroll
import axios from 'axios';
import { ref, onMounted, onUnmounted } from 'vue';
let list = ref([])
const loadList = () => {
  axios.get('/good.json')
    .then(res => {
      list.value = [...list.value, ...res.data.cont]
    })
}

const doScroll = () => {
  let html = document.documentElement;
  let per = html.scrollTop / (html.scrollHeight - html.clientHeight);
  console.log(per);
  if (per >= 0.7) {
    console.log('loading');
    loadList()
  }
}

onMounted(() => {
  loadList()
  window.addEventListener('scroll', doScroll)
})

onUnmounted(() => {
  window.removeEventListener('scroll', doScroll)
})      
参考代码 - 使用状态管理
创建商品仓库 good.js - 返回商品列表 good 和加载商品列表的异步函数 fetchGood
import { ref } from 'vue'
import { defineStore } from 'pinia'
import axios from 'axios'

export const useGoodStore = defineStore('good', () => {
  const good = ref([])
  let loading = ref(false)
  let error = ref(null)
  let fetchGood = async () => {
    loading = true
    try {
      // 假设调用API获取商品列表
      const response = await axios.get('https://glpla.github.io/utils/data/coffee.json');
      console.log(response.data.cont);
      good.value = response.data.cont;
    } catch (err) {
      error.value = err.message
    } finally {
      loading = false
    }
  }
  return { good, fetchGood }
})
在组件中引入仓库并获取数据 - 使用计算属性侦听 good 的变化;也可以使用监听 watch
import { computed, onMounted } from 'vue';
import { useGoodStore } from '@/stores/good';
let store = useGoodStore()

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

const addCart = (item) => {
  console.log(item);
}

onMounted(() => {
  store.fetchGood()
})
const good = computed(() => store.good)
页面渲染 - 列表渲染,略
参考效果
商品列表页