外卖项目初始化01

这篇具有很好参考价值的文章主要介绍了外卖项目初始化01。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

sell-app-day01

今日任务

  • 项目的搭建
    • 创建项目
    • 仓库(把代码上传上去,切换个人分支)
    • 工程化scss
      • reset.scss
      • main.scss [统一的出口]
      • common.scss [公共的样式]
      • vant.scss [覆盖vant的样式]
      • var.scss 【变量的文件,
        • css3 的变量
          • 一键切换皮肤 【了解一下】
      • mixin.scss
    • 屏幕适配 【
      • px 转换成 vw
    • axios的配置(token)
    • 环境变量
  • 路由划分
  • vant引入
  • 商家信息
    • 接口: http://1.15.179.44:3001/ , http://129.211.169.131:5000
  • 商品信息
    • 接口

项目介绍

  • 参考地址

  • 用户的群体:给点外卖的用户。

  • 功能点:

    • 首页

      • 商家信息
        • 模糊效果
      • 商品 【重点】
        • 基本的页面的渲染
        • 滚动效果的制作
          • 左联右 【简单】
          • 右联左【需要自己去计算】
        • 商品页面与购物车组件联动
          • vuex 【重点】
      • 商家
      • 评价
    • 详情页面

      • 页面之间的通信【重点】

手机端适配

讲道理设计师只会给一份手机端项目设计稿(375px 750px)。

例子: 假设设计稿的宽度为750, 在设计稿上量出一个div的宽度为375px

真机的宽度 实际宽度 屏幕(视口)占比 vw
375px 187.5px 50% 50vw
414px 207px 50% 50vw
912px 456px 50% 50vw

css3出了一个新的单位: vw。vw:视口(屏幕的宽度)的百分之1。

结论:将px单位转换为vw单位,就能够适配到各个手机端。等比的缩放

px转换为vw不需要开发者自己去算,有第三方插件: postcss-px-to-viewport

postcss-px-to-viewport配置

  • 搜索文档: postcss-px-to-viewport npm

  • 安装插件: yarn add postcss-px-to-viewport -D

  • 在项目的根目录下创建文件: postcss.config.js

  • 在postcss.config.js中编写配置

    module.exports = {
        plugins: {
            // 插件: 将px转换为vw
          'postcss-px-to-viewport': {
            // 设计稿宽度,你在设计稿上量出的宽度,不用自己划算,直接写。
            viewportWidth: 750,
          }
        }
    }
    
  • 重启

  • 测试

    • 给项目中的一个div加一个宽高,然后再浏览器切换机型,看他具体的大小

css3变量【了解!!】

scss/less变量

这个变量设置之后,并不是全局使用。你需要在使用的地方进行导入。

场景: 设置一系列全局变量。 在类名为.box下注入一个变量。

css3的变量

可以设置全局/局部的变量。

  • 全局: 给最外层的节点注入一个变量
  • 局部: 给某一个节点设置一个局部变量

特点:

  • 可以很方便的被覆盖,很多ui组件库都在使用

主题色切换方案

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q1Ir9o7t-1690507265571)(…/resource/md/1.主题色切换.png)]

  • 创建一个var.scss,定义三套主题色

    // scss的变量页没有全局变量  【哪里需要哪里引入】
    $main_color: #ff6900;
    
    // css3的变量
    
    // 全局的变量
    // 
    :root {
        --base-color: #ff6900;
    }
    
    // 根节点 下面的某一些节点(有一个属性叫做 theme     属性的值为red)
    :root [theme="red"] {
        --base-color: red;
    }
    
    
    :root [theme="gray"] {
        --base-color: #ccc;
    }
    
  • 在main.scss中引入变量文件(var.scss)

    @import './reset.scss';
    @import './common.scss';
    @import './vant.scss';
    @import './var.scss';
    
  • 在main.js下全局注册main.scss

    • import ‘@/assets/style/main.scss’
  • 在App.vue 去指明主题

    <div id="app" :theme="theme" >
        <nav>
          <router-link to="/">Home</router-link> |
          <router-link to="/about">About</router-link>
        </nav>
    	<button @click="theme = 'red'">过年</button>
        <button @click="theme = ''">默认</button>
        <button @click="theme = 'gray'">灰色</button>
        <router-view/>
      </div>
    
    data() {
        return {
            // 默认的
           theme: '' 
        }
    }
    
  • 在所有的组件中通过var取base-color

    <style scoped lang="scss">
        .theme-wrapper {
            color: var(--base-color);
        }
        .container {
            width: 50px;
            height: 50px;
            background: var(--base-color);
        }
    </style>
    

vant的引入

vant是一系列: 微信小程序(vant weapp),vue2 (vant2.x), vue3(vant4.x)。官网

  • 安装

    • yarn add vant@latest-v2
  • 在页面中按需引入

    import Button from 'vant/lib/button';
    import 'vant/lib/button/style';
    

    在页面中引入组件,引入它对应的样式。注册使用

  • 全局,把所有组件都变成全局组件(类似于elementui)

    import Vant from 'vant';
    import 'vant/lib/index.css';
    // Vant是一个对象,这个对象一定有一个方法: install
    
    Vue.use(Vant);
    

在main.js中引入样式,引入所有组件, use一下

  • 全局,把你需要的组件,注册成全局。样式我们全局引入

    import 'vant/lib/index.css';
    import { Button, Tabs } from 'vant';
    
    // 只把Button注册成全局组件
    Vue.use(Button).use(Tabs)
    
    

    我们这次采用这个

better-scroll的使用

官方链接

  • 满足三个条件

    • 滚动容器高度固定
    • 滚动容器下只有一个节点(div)
    • 滚动的内容 > 滚动容器
  • 安装 BS

    • yarn add @better-scroll/core
      
  • 导入

    import BS from '@better-scroll/core'
    
  • 初始化BS

    // 字符串: #box   
    // dom节点
    new BS(滚动容器, {
        一些配置
    })
    

作业

  • 修改tab刷新丢失问题
    • 参考外卖管理端,刷新menu定位丢失问题!!!!

sell-app-day02

左联右

  • 给每一个菜单绑定一个点击事件

    <van-sidebar v-model="active">
            <van-sidebar-item @click="clickType(item.name)" v-for="item in list" :key="item.name" :title="item.name"></van-sidebar-item>
          </van-sidebar>
    
  • 给右侧每一类商品给一个id,目的就是为了和左边菜单一一对应起来

     <div v-for="goods in list" :key="goods.name" :id="goods.name">
    
  • clickType里面获取右侧点击的菜单项

    • 根据名字获取dom节点

    • 然后把节点传递给右侧的实例

    • 右侧实例调用scrollToElement达到左联右的效果·

      clickType(id) {
              // 通知右侧的BS实例,你该滚动到哪里
              // string:  document.querySelector
              // dom
              this.rightBS.scrollToElement(document.getElementById(id), 500)
            }
      
      

      注意如果这里传字符串,你要注意你的id的合法性

右联左

  1. 监听右侧内容的滚动距离

    实例.on('监听事件', 回调)
    
    // 初始化右侧BS的时候,配置任何时候都派发滚动事件
    this.rightBS = new BS('#goods_right', {
        click: true,
        // 滚动事件派发
        probeType: 3
    })
    
    // 监听滚动
    this.rightBS.on('scroll', (position) => {
        const { y } = position
        console.log(y, '~~~~~~~~~~~~~')
    })
    
  2. 通过计算属性获取每一类商品的高度

    1. 对高度进行处理 { active:0, min:0 , max: 100}

      computed: {
            typeHeight() {
              let arr = []
              // 第i项之前的总和,最开始为0
              let prevHeight = 0
      
      
              this.list.forEach((goods, i) => {
                // 得到当前第i项商品的高度
                let height = document.getElementById(goods.name).offsetHeight
                arr.push({
                  active: i,
                  min: prevHeight, // 第i项之前的总和
                  max: prevHeight + height  // 第i项之前的总和 + 自身的高度
                })
                // push完之后prevHeight要加上height
                prevHeight += height
              })
              return arr
            }
          },
      
  3. 滚动时候拿到滚动的距离y(取绝对值),在divHeight中进行判断

    this.rightBS.on('scroll', (position) => {
        // 拿到滚动距离取绝对值
        const y = Math.abs(position.y)
        for(let i = 0; i < this.typeHeight.length; i++) {
            let curType = this.typeHeight[i]
            if(y>=curType.min && y < curType.max) {
                this.active = curType.active
                break
            }
        }
    })
    
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6HBwXuGQ-1690507265572)(…/resource/md/左右联动思路图.png)]

商品页与购物车联动

将商品列表交给vuex保管

  • 请求数据
  • 修改数据
import { goodsListApi } from '@/api/goods.api'
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    // 全部的商品
    list: []
  },
  getters: {
  },
  mutations: {
    M_list(state, payload) {
      state.list = payload
    }
  },
  actions: {
    // action是返回值(promise),如果你没有主动返回,同步代码执行完毕之后,返回一个Promise(undefine)
    async A_list({commit}) {
      // 请求后台的商品列表
      const res = await goodsListApi()
      res.forEach(goods => {
        goods.foods.forEach(foods => {
          foods.num = 0
        })
      })
      commit('M_list', res)
    }
  },
  modules: {
  }
})

商品页调用action

  • 商品页调用完action
  • 当action把仓库中的数据修改之后再初始化BS
created() {
    // 调用仓库中的acation
    this.A_list().then(res => {
      this.$nextTick(() => {
        this.leftBS = new BS("#goods_left", {
          click: true
        });
        this.rightBS = new BS("#goods_right", {
          click: true,
          // 滚动事件派发
          probeType: 3
        });
        // 监听滚动
        this.rightBS.on("scroll", position => {
          const y = Math.abs(position.y);
          for (let i = 0; i < this.typeHeight.length; i++) {
            let curType = this.typeHeight[i];
            if (y >= curType.min && y < curType.max) {
              this.active = curType.active;
              break;
            }
          }
        });
      });
    });
  }

编写一个修改数量的mutation

// 把foods  和  num传入
    // payload: {foods,  num}
    M_num(state, payload) {
      const { foods, num } = payload
      foods.num += num
    }
<!-- vuex的数据能直接改吗? -->
<button v-if="foods.num" @click="M_num({foods, num: -1})">-</button>
{{ foods.num }}
<button @click="M_num({foods, num: 1})">+</button>

编写一个getters表示被选中的商品

getters: {
    // 被选中的foods
    buyGoodsList(state) {
      let result = []
      state.list.forEach(goods => {
        goods.foods.forEach(foods => {
          if(foods.num > 0) result.push(foods)
        })
      })
      return result
    },
  },

编写一个计算总价的getters

getters: {
    // 计算总价
    totalPrice(state, getters) {
      let total = 0
      getters.buyGoodsList.forEach(foods => {
        total += foods.num * foods.price
      })
      return total
    } 
  },

页面通信

页面通信的方式

  • 本地存储

  • 路由传参(vue-router)

    • query

      this.$router.push({
              query: foods,
              path: '/detail'
            })
      
      

      特点: 数据保存在路径上,刷新页面不会丢失

    • params

      this.$router.push({
          params: {},
          name: '路由的名字'
      })
      

      刷新页面丢失!!!

  • 中央事件总线

    • 可以做,但是有bug
    • 步骤
      • $bus
        • Vue.prototype.$bus = new Vue()
      • 发送方
        • $bus.emit(‘自定义事件的名字’, 发送的数据)
      • 接收方
        • $bus.on(‘自定义事件的名字’, data => {})
    • 使用乱传做页面通信,第一次接收不到
  • vuex文章来源地址https://www.toymoban.com/news/detail-486414.html

    • vuex做页面通信,可能会造成数据丢失。
    • 解决方式:做vuex的数据持久化(你把数据放在内存中, 你把数据存在本地,数据库,work,text)。
      • 调用mutation的时候,把数据存到仓库里面一分,存到本地一分
      • state里面:刷新的时候从本地里面取一下
    • 实际开发中,配置持久化插件即可。参考链接

bug修改

  • 菜单切换丢失
  • tab切换,选择num丢失
    • 在action之前判断一手
      • list有值,不求请
      • list没值,重新请求
    • keep-alive的使用
      • 缓存组件

到了这里,关于外卖项目初始化01的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring初始化项目

    访问地址:https://start.spring.io idea配置:https://start.spring.io 访问地址:https://start.aliyun.com/bootstrap.html idea配置:https://start.aliyun.com 官网 阿里巴巴 版本 最新 稍旧 国内软件 大部分没有(mybatis plus) 有的支持(如:mybatis plus)

    2024年02月09日
    浏览(35)
  • git初始化项目上传

    步骤1:创建远程仓库 平台上建好项目,并copy远程仓库的URL 步骤2:初始化本地Git 首先,进入您本地的项目根目录下,然后,打开命令行界面,导航到该目录并执行以下命令: 执行完之后我们可以看到根目录下会多出一个.git文件。 如果是java项目可以在这个项目根目录下加个

    2024年02月10日
    浏览(49)
  • 多级缓存架构(一)项目初始化

    克隆此项目到本地 https://github.com/Xiamu-ssr/MultiCache 来到 start 目录下,分别有以下文件夹 docker :docker相关文件 item-service :springboot项目 在 docker/docker-compose.yml 中已经定义好如下 mysql 块 my.cnf 如下 运行以下命令启动 docker-compose 之后使用数据库连接工具连接 mysql 容器,创建 he

    2024年02月02日
    浏览(45)
  • Vue初始化项目加载逻辑

    项目创建 我们只需要创建项目即可,剩余的依赖都没必要安装 我们先来看main.js,咱们加了一行备注 通过备注可知,我们首先加载的是App.vue 我们再来看一下App.vue 里都有啥 也就是下面这个红框里的内容才是 那下面的内容是哪里来的呢 那就需要看一下路由设置了 我们看到/目

    2024年02月08日
    浏览(84)
  • 微信小程序项目初始化配置

    注:该文章用于记录或学习交流 微信小程序项目初始化配置准备,包括项目创建,基础路径配置,组件库安装,接口请求封装,部分实用组件封装等 创建初始项目后,对项目文件结构重新梳理 注:目录结构根据个人需求创建,assets和static文件夹的区别详见 assets与static的区别

    2023年04月08日
    浏览(73)
  • 初始化git仓库(已存在项目)

    1.创建git仓库,获取仓库git地址 2.进入已存在项目根目录,打开git bash,执行命令,初始化仓库 3.添加文件 4.配置gitignore文件,排除部分文件 5.提交到本地 6.配置远端仓库 7.push到远程仓库某分支,完成代码上传

    2024年02月11日
    浏览(50)
  • 1、前端项目初始化(vue3)

    安装npm,(可以用nvm管理npm版本)npm安装需要安装node.js(绑定销售?)而使用nvm就可以很方便的下载不同版本的node,这里是常用命令 配置npm源 命令: 设置镜像源: npm config set registry https://registry.npm.taobao.org 查看当前使用的镜像地址: npm config get registry 参考 :https://www.cnbl

    2024年01月20日
    浏览(43)
  • Java开源项目mall学习笔记(1)——项目初始化

            该笔记是记录学习开源项目mall过程的文档笔记,完全原创,转载请声明。同时也对开源项目的作者表示感谢! mall: 🔥 mall项目是一套基于 SpringBoot + Vue + uni-app 实现的电商系统,包括前台商城项目及后台管理系统,采用Docker容器化部署。前台商城系统包含首页门户

    2024年02月12日
    浏览(33)
  • node.js项目express的初始化

    👍 点赞,你的认可是我创作的动力! ⭐️ 收藏,你的青睐是我努力的方向! ✏️ 评论,你的意见是我进步的财富! 在D盘新建一个文件夹,文件夹命名为api 将文件夹拖拽到vscode上面进行打开 新建一个终端 输入 npm init -y,初始化包管理工具 输入npm i express,安装express框架

    2024年01月18日
    浏览(46)
  • 【uniapp】小程序开发,初始化项目vscode

    使用uniapp开发小程序可以实现一份代码打包成多个不同平台的小程序。 这里使用uniapp官方的项目模板作为示例,采用vue3+ts开发,并使用vscode作为开发工具 1、通过以下命令创建模板项目 参考 官方说明 创建以 typescript 开发的工程(如命令行创建失败,请直接访问 gitee 下载模

    2024年02月09日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包