Vue 学习Day8 命名视图/详情页/注册/登录/购物车

命名视图

一个路由对应多个视图的变化,每个视图对应不同的组件

  • App.vue 抽离底部组件 components/footer.vue
    在这里插入图片描述
  • App.vue 添加第二个视图,设置name属性,配置路由规则时则可以选择要不要底部
    在这里插入图片描述
  • 修改router/index.js的路由规则
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

首页列表点击进入产品的详情

设计详情页面以及添加路由

在这里插入图片描述
在这里插入图片描述

  • 详情页根据 /detail/proid proid为产品的id,依据产品的id不同获取不同的数据,渲染页面。 这时采用动态路由

动态路由匹配
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:

  • 改造详情的路由,增加标识
    在这里插入图片描述

声明式跳转

<router-link to=""></router-link>

  • 偏向JS的写法

<router-link :to="'/detail/'+item.proid"></router-link> 正确的
在这里插入图片描述

<router-link :to="{ name: 'detail', params: { proid: item.proid }}" ></router-link>
在这里插入图片描述
在这里插入图片描述

编程式跳转

this.$router.push / replace / go ()

  • 偏向JS的写法

在这里插入图片描述

  • Vue 推荐的写法
    在这里插入图片描述
  • 演变写法
    在这里插入图片描述

详情页面获取参数请求数据

  • 获取路由的参数信息
  • 当匹配到一个路由时,参数值会被设置到this.$route.params,可以在每个组件内使用

this.$route.params
在这里插入图片描述
在这里插入图片描述

  • 封装获取产品详情数据的接口
    在这里插入图片描述
  • 详情页面请求数据
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 渲染详情页面
    在这里插入图片描述
    在这里插入图片描述
  • 添加加入购物车组件 vant GoodsAction
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 修改详情头部
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 返回上一页
    在这里插入图片描述
  • 点击加入购物车 ---- 必须等登陆 — 注册

注册功能

  • 个人中心页面添加 注册登录 入口
    在这里插入图片描述
    在这里插入图片描述
    ? 如果未登录显示等和注册按钮,如果是已登录 显示的个人的信息
  • 完成注册表单
  • 注册头
    在这里插入图片描述
    在这里插入图片描述
  • 注册表单
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 复制注册的页面 至 登陆页面 ,修改标识为登录
    在这里插入图片描述
  • 完成注册功能 — 将数据提交给后端,后端校验有没有该用户,没有完成注册,注册成功 跳转到登陆页面(一定是替换)
  • 封装注册接口的方法 api/index.js
    在这里插入图片描述
  • 注册页面完成业务逻辑
    在这里插入图片描述
    在这里插入图片描述

登陆功能

  • 封装登陆接口 api/index.js
    在这里插入图片描述
  • 登录页面完成业务逻辑
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

加入购物车

后端代码

  1. 设计购物车的集合 admin-app/sql/col/carts.js
    在这里插入图片描述

  2. 设计加入购物车的业务逻辑
    admin-app/api/cart.js
    在这里插入图片描述

  3. 封装更新数据库的方法
    admin-app/sql/index.js
    在这里插入图片描述

  4. 购物车接口引入数据库完成业务逻辑
    在这里插入图片描述

var express = require('express');
var router = express.Router();
var sql = require('./../sql')
var Cart = require('./../sql/col/carts')
var Pro = require('./../sql/col/pros')
var uuid = require('node-uuid')

/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('购物车相关接口');
});

/**
 * @api {post} api/cart/add 加入购物车
 * @apiDescription 加入购物车
 * @apiGroup cart
 * @apiParam { string } userid 用户ID
 * @apiParam { string } proid 产品id
 * @apiParam { number } num 产品数量 (默认为1)
 * @apiSuccessExample { json } Success-Response:
 * res.send({
 *   code: '804',
 *   message: '完善购物车信息'
 * })
 * {
 *  code: '200',
 *  message: '加入购物车成功'
 * }
 * @apiSampleRequest /api/cart/add
 * @apiVersion 1.0.0
 */
router.post('/add', function(req, res, next) {
  // 获取前端提交的数据 post
  let { proid, userid, num } = req.body // 这里绝对不能用const
  num = num * 1 || 1 // 给nun 设置默认值为一,并转类型位num
  // 如果当前用户数据库中有该商品,直接数量相加,如果没有,添加新数据
  // 1 判断前端是否传了 proid userid 没传直接返回
  if ( !userid || !proid ) {
    res.send({
      code : '804',
      msg : '完善购物车信息'
    })
    return 
  }

  // 2 如果当前的用户,数据库中有该商品,那么你的数量直接加num即可,否则直接添加一条新的记录
  sql.find(Cart , {userid , proid} , {_id:0} ).then(data1 => {
    if ( data1.length > 0 ) {
      // 已有该商品。调用修改方法,数量递增 
      // { $inc: { num: num } } 将数据库中的num字段自增num
      // { $set: { num: 10 }} // 设置num值为10
      // $set: { flag: 1 } } 必为选中
      sql.update(Cart, {userid , proid}, {$inc: { num }, $set: { flag: 1 }})
      .then( () => {
        res.send({
          code : '200',
          msg : '加入购物车成功'
        })
      })
    } else {
      // 没有该商品,调用增加数据方法,添加该商品信息
      // 先通过proid 查找购物车中该商品所需的必要信息
      sql.find(Pro, {proid}, {_id: 0}).then(data2 => {
        const { brand, proname, proimg, desc, rating, price} = data2[0]
        const insertObj = {
          cartid : 'cart_' + uuid.v1(),
          userid,
          proid,
          brand,
          proname,
          proimg,
          desc,
          rating,
          price,
          flag : 1, // 该flag为是否被选中,与商品信息flag是否热销不一样
          num 
        }
        // 插入数据库
        sql.insert(Cart, insertObj).then(() => {
          res.send({
            code: '200',
            message: '加入购物车成功'
          })
        })
      })
    }
  })
});

module.exports = router;
  1. 生成接口文档

apidoc -i api/ -o public/apidoc

  1. 测试加入购物车接口
    在这里插入图片描述
  2. 编写 查看购物车接口
/**
 * @api {get} api/cart 查询购物车
 * @apiDescription 查询购物车
 * @apiGroup cart
 * @apiParam { string } userid 用户ID
 * @apiSuccessExample { json } Success-Response:
 * res.send({
 *   code: '805',
 *   message: '请携带用户信息'
 * })
 * {
 *  code: '200',
 *  message: '查询购物车成功'
 * }
 * @apiSampleRequest /api/cart
 * @apiVersion 1.0.0
 */
router.get('/', function(req, res, next) {
  // 获取get请求中的userid
  const { userid } = req.query
  // 通过userid获取购物车中的数据
  // 判断userid是否存在
  if (!userid) {
    res.send({
      code: '805',
      msg: '请携带用户信息'
    })
  } else {
    sql.find(Cart, { userid }, { _id: 0 } ).then(data => {
      res.send({
        code: '200',
        msg: '获取购物车信息',
        len: data.length,
        data: data
      })
    })
  }
});

在这里插入图片描述

前端代码

详情页面加入购物车
在这里插入图片描述

  • 封装加入购物车的接口

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

查看购物车

  • 封装接口
    在这里插入图片描述
  • 查看购物车业务逻辑
    在这里插入图片描述
<template>
  <div class="box">
      <header class="header">
        <van-nav-bar
          title="购物车"
          left-arrow
          @click-left="$router.go(-1)"
          >
        </van-nav-bar>
      </header>
      <div class="content">
        <h3 v-if="flag">您的购物车空空如也,请添加商品</h3>
        <div class="cartlist" v-if="!flag">
          <van-card
            :num="item.num"
            :price="item.price"
            :desc="item.desc"
            :title="item.proname"
            :thumb="item.proimg"
            v-for="item of cartlist"
            currency='¥'
            :key="item.proid"
          >
            <div slot="tags">
              <van-tag plain type="danger">{{ item.brand }}</van-tag>
            </div>
            <div slot="footer">
              <van-button size="mini">+</van-button>
              <van-button size="mini">-</van-button>
            </div>
          </van-card>
        </div>
      </div>
    </div>
</template>

<script>
import Vue from 'vue'
import { getCartData } from '@/api'
import { Toast, Card, Tag, Button, NavBar } from 'vant'
Vue.use(Toast)
Vue.use(Card)
Vue.use(Tag)
Vue.use(Button)
Vue.use(NavBar)
export default {
  data () {
    return {
      flag: true,
      cartlist: []
    }
  },
  mounted () {
    const loginState = localStorage.getItem('loginState')
    if (loginState) {
      const userid = localStorage.getItem('userid')
      getCartData({ userid }).then(res => {
        if (res.data.len > 0) {
          this.flag = false
          this.cartlist = res.data.data
        }
      })
    } else {
      Toast('请先登录')
      this.$router.push('/login')
    }
  }
}
</script>
发布了38 篇原创文章 · 获赞 0 · 访问量 901

猜你喜欢

转载自blog.csdn.net/ZywOo_/article/details/104997616