尚品汇笔记——尚硅谷
尚品汇笔记
前端核心:
1、构建页面Html+CSS+…
2、接口传来数据
3、vuex接收并处理数据
4、组件接收数据渲染到页面
5、交互
1、Vue的目录分析
node_modules: 是安装node后用来存放用包管理工具下载安装的包的文件夹。
public: 一般用于存放一些静态资源文件,例如图片,视频,音频等资源文件。需要特别注意的是webpack在进行打包的时候,会将public中的所有静态资源原封不动的进行打包。
src:
asset:也是用于存放一些静态资源文件
components:公共组件,非公共放在page
App.vue:是整个项目的根组件,所有组件的后缀名均为·vue
main.js:是文件的入口文件,程序执行先从该文件开始
babel.config.js:: 配置文件(babel相关)
package.json: 项目的详细信息记录
package-lock.json: 缓存性文件(各种包的来源)
2、项目配置
2.1:项目的基本运行指令,自动打开浏览器,打包文件,自动修复
"scripts": {"serve": "vue-cli-service serve","build": "vue-cli-service build","lint": "vue-cli-service lint"},
2.2:关闭eslint工具(不关闭严重影响,不按照eslint语法就报错)
module.exports = {//关闭eslintlintOnSave: false}
2.3:2.3 src文件夹配置别名,创建jsconfig.json,用@/代替src/
{"compilerOptions": {"target": "es5","module": "esnext","baseUrl": "./","moduleResolution": "node","paths": {"@/*": ["src/*"]},//文件运行后产生的"lib": ["esnext","dom","dom.iterable","scripthost"]}
}
3、注册路由
3.1:
import VueRouter from "vue-router";
import Vue from "vue";// 引用路由文件
import routes from './routes'// 使用路由
Vue.use(VueRouter)// 对外包括,方便在mian.js中应用
export default new VueRouter({routes
})
3.2 routes文件夹统一管理路由
import Home from '../pages/Home/'const routes=
[{//query参数的跳转是path的路径,params的跳转参数是namepath:'/Home',name:'/Home',component:Home}
]
export default routes
3.3 main.js中注册路由,一定不能忘记在Vue中注册路由
import Vue from 'vue'import router from './router'new Vue({router,render: h => h(App),}).$mount('#app')
4、注册全局组件
在main.js中注册过的组件,在全局都是有效的,不需要在任何vue文件中引用,直接用就好
// 引入公共组件中的TypeNavimport TypeNav from './components/TypeNav.vue'// 注册全局组件 第一个参数就是组件的名字Vue.component("TypeNav",TypeNav)
直接全局组件TypeNav,注册过
<template><div id="app"><Header/><TypeNav/><router-view/><Footer/></div></template>
5.重定向:
在初始化项目时,路由自动跳转到设置的路由
// 重定向{path: '/',redirect: '/Home'},
6. 二次封装axios
主要是要用到请求拦截器和响应拦截器;
请求拦截器:可以在发请求之前可以处理一些业务,配置下baseURL路径
响应拦截器:当服务器数据返回以后,可以处理一些事情
// 封装axiosimport axios from "axios";// const requests =axios.create({// 配置基础路径,发请求的时候,会直接带上基本路径,不需要重复书写baseURL:'/api',// 相应事件5s,超过则失败timeout:5000})requests.interceptors.request.use((config)=>{// config是一个非常重要的属性,包含着发送的请求头,许多信息可以写在里里面return config})export default requests
在index.js文件中书写相对应的地址
import requests from "./requests";// /api/product/getBaseCategoryList 三级菜单
export const reqgetCategoryList=()=>requests({url:`/product/getBaseCategoryList`,methods:'get'
})
7.代理跨域问题
3.1:先放在这里,之后来填跨域的坑
vue.config.json
module.exports = ({// 代理跨域devServer:{proxy:{'/api':{target:'http://gmall-h5-api.atguigu.cn',}}}})
8.Mock
8.1:封装一个mockrequest的二次封装,
和之前封装的相同,不过baseURL不同,在这里封装了,在index.js中就不需要再次书写
// 封装axiosimport axios from "axios";// const MockRequests =axios.create({// 配置基础路径,发请求的时候,会直接带上基本路径,不需要重复书写baseURL:'/mock',// 相应事件5s,超过则失败timeout:5000})MockRequests.interceptors.request.use((config)=>{// config是一个非常重要的属性,包含着发送的请求头,许多信息可以写在里里面return config})export default MockRequests
8.2 创建mock响应内容
在src下创建mock文件夹,创建mockServer.js,同时在文件下下创建其他的json数据文件
import Mock from "mockjs";// 引入json文件import banner from './banner.json'import floor from './floor.json'//mock数据:第一个参数请求地址、第二个参:请求数据 Mock.mock('/mock/banner',{code:200,data:banner})Mock.mock('/mock/floor',{code:200,data:floor})//记得要在main.js中引入一下//import ''@/mock/mockServer
8.3 在api中发送请求,注意请求变了
import MockRequests from "./MockRequests";// banner轮播图mockexport const reqBannerList =()=>MockRequests({url:`/banner`,methods:'get'})// floor页面 mockexport const reqFloorList =()=>MockRequests({url:`/floor`,methods:'get'})
9.接口数据被分割成两个模块
9.1 可以使用v-show配合v-for一起使用,最好不用v-if,会显示报错
vue2中,v-for的优先级比v-if高,所以警告,并不影响运行
vue3中,v-if的优先级比v-for高
但是如果一起用,还是会浪费性能,所以项目还是老老实实的computed计算属性
v-for="(img,index) in item.recommendList" :key="index" v-show="index<2"
10、轮播图swiper的封装
挖坑
11、Vuex
11.1 安装vuex npm i vuex@3
注意:vueRouter和vuex
"vue": "^2.6.14","vue-router": "^3.6.5","vuex": "^3.6.2"
12.编程式导航+事件委托解决路由跳转
12.1 事件委托:概念:事件委托也叫事件代理,“事件代理”即是把原本需要绑定在子元素的响应事件(click keydown…)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。举个例子- 英语老师要受英语作业,老师让学习委员统一收取作业,再交给她学习委员就充当了委托中的父元素
好处:不需要对任何的一个子元素进行单独处理,而是汇总起来批量处理,可以大量节省内存占用,减少事件注册,比如在ul上代理所有li的click事件。
<ul id="list"><li>item 1</li><li>item 2</li><li>item 3</li>......<li>item n</li></ul>// ...... 代表中间还有未知数个 li
12.2
实现点击任何标题都可以跳转到Search页面
实现思路:
<div class="all-sort-list2" v-for="(nav) in categoryList" :key="nav.categoryId"><div class="item bo"><h3><!-- 一级菜单 --><a @click="goSearch" :data-categoryName='nav.categoryName' :data- categoryId1='nav.categoryId'>{{nav.categoryName}}</a></h3><div class="item-list clearfix" ><div class="subitem" v-for="nav1 in nav.categoryChild" :key='nav1.categoryId'><dl class="fore"><dt><!-- 二级菜单 --><a @click="goSearch" :data-categoryName='nav1.categoryName' :data-categoryId2='nav1.categoryId'>{{nav1.categoryName}}</a></dt><dd ><em v-for=" nav2 in nav1.categoryChild " :key="nav2.categoryId"><!-- 三级菜单 --><a @click="goSearch" :data-categoryName='nav2.categoryName' :data-categoryId3='nav2.categoryId'>{{nav2.categoryName}}</a></em></dd></dl></div></div></div> </div></div>
1、需要在点击获取点击时的数据,自定义属性就登上帷幕,在event.target.dataset属性中可以获取
2、利用es6新属性,解构赋值,取出属性,判断
3、跳转路由,这个地方写的特别好,分别定义location和query,随后赋值
goSearch(event){// 获取当前点击的数据let element =event.targetconsole.log(element)let {categoryid1,categoryid2,categoryid3,categoryname}=element.datasetconsole.log(categoryid1,categoryid2,categoryid3,categoryname )// 如果有categoryname的话那就是a标签里面的if(categoryname){// 创建跳转路由let location={name:'Search'}// 跳转参数let query ={categoryName:categoryname}if(categoryid1){query.categoryid1=categoryid1}else if(categoryid2){query.categoryid2=categoryid2}else if(categoryid3){query.categoryid3=categoryid3}location.query=querythis.$router.push(location)}},
13.transition过度效果
14.父子组件通信面包屑
Vue组件间通信的几种常见方式:
- props / $emit
- emit/emit/emit/on 全局时间总线$bus
- ref / $refs 父子
- 依赖注入(provide / inject) 祖孙子
- Vuex 全局(用的多)
这里我们用的是props/$emit子父通信
需求:点击子组件,在index页面上呈现面包屑的效果
分析:1、绑定点击事件2、绑定emit的事件 this.$emit('事件名',传参)3、父组件中写自定义事件4、渲染页面
<template>//简化代码,方便查看<li v-for="mark in trademarkList " :key="mark.id" @click="BrandHandler(mark)">{{mark.tmName}}</li><a @click="attrHandler(attr2,attr)">{{attr2}}</a>
</template><script>export default {name: 'SearchSelector'methods:{// 点击品牌,出现面包屑BrandHandler(Brand){this.$emit('BrandHandler',Brand)},// 属性的面包屑attrHandler(attr2,attr){this.$emit('attrHandler',attr2,attr.attrId)}}}
</script>
//传参props or 子传父事件
< template> <SearchSelector :attrsList='attrsList' :trademarkList='trademarkList' @BrandHandler='BrandHandler' @attrHandler='attrHandler'/></template>
<script>methods:{// 品牌的面包屑 添加propsBrandHandler(Brand){// es6 解构let props=`${Brand.tmId}:${Brand.tmName}`if( this.searchParams.props.indexOf(props)==-1){this.searchParams.props.push(props)}},// 属性的面包屑同样添加propsattrHandler(attr,attrId){let props =`${attrId}:${attr}`if( this.searchParams.props.indexOf(props)==-1){this.searchParams.props.push(props)}},
</script>
15.分页器
这里我懒了,不太像手写分页器了,用了element-ui就当是锻炼下插件能力了
14.1 安装element-ui (npm i element-ui)
14.2main.js中注册(官网有安装教程)
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css';Vue.use(ElementUI)new Vue({render: h => h(App),
}).$mount('#app')
14.3 在element-ui中取分页器代码,自己改下
<div class="block page"><el-pagination:current-page.sync="searchParams.pageNo":page-size="searchParams.pageSize"layout="prev, pager, next, jumper":total="searchParams.total"></el-pagination></div>
第三个页面 /detail
五个需求点:
- 左上方的面包屑
- 左边图片的轮播图和图片
- 中间的属性选择
- 数量的增减和改变
- 加入购物车的跳转
左上方的面包屑 :
1、 分析:参数是由上一层Search传输而来的路由参数,在向服务器发送数据的时候带上这个参数
routes.js
Detail.js
控制台的数据传回
渲染上页面:
面包屑效果图:
2、左边图片的轮播图和图片:
分析:父子组件通信、ImageList子组件,利用swiper轮播官网提供组件
效果图:
实现大图和轮播图的兄弟通信功能:
imageList:
Zoom兄弟组件:
这里特别说明一下使用全局$bus的时候记得main.js中注册,否则就是报错emit/on
反思:这个案例还是非常有代表性的组件通信,动态改变页面功能,剖析本质,组件通信也就这回事
中间的属性选择 :
分析:选择属性只能选择一种,所以可以考虑到排他算法,这是最优解
item是单独的属性值 arr是item的父级,把父级的所有置空,然后一个子级脱颖而出,写好active就好数量的增减和改变:
mouseout:鼠标移除的时候触发校正
- 加入购物车的跳转
跳转路由的方法有编程式路由和。。。。,这里就是编程式路由,比较直观的带参
第四个页面 AddCartSuccess
三个需求:
- 图片渲染上页面
- 文字和带参skuNum渲染页面
- 两个跳转页面(原路由,新路由)
思路:这是一个小页面。所以在数据上,接口并未提供返回数据,仅提供向服务器增添数据的接口,这时候选择用sessionStorage会话储存来保存上个页面的数据,也可以做到页面间的数据共享,不过劣势在于仅单次使用有效。
图片渲染上页面:
通过会话储存来存储Detail页面的数据,注意要更改成Json格式,否则就是object报错,再在下个页面取出
第五个页面:shopcart
七个需求:
- 商品的基础渲染
- 商品的增减、保证输入框是整数
- 删除商品
- 选择商品
- 全选全部商品
- 选择商品件数和总金额呜
- 结算页面的选择
UUID
接口: url:/cart/cartList
,在接口文档中,是一个get请求,无法在参数中传递身份信息,只能在requsts 分装函数中定义
先在src下创建utils工具,创建uuid的js文件,对外暴露函数(记得 npm install uuid)
import {v4 as uuidv4} from 'uuid'// 生成临时游客的uuid,不能发生变化,耗能持久储存
export const getUUID =()=>{// 1、判断本地储存是否uuidlet uuid_token =localStorage.getItem('UUIDTOKEN')// 2、本地没有uuidif(!uuid_token){// 2.1 生成uuiduuid_token =uuidv4()//2.2储存本地localStorage.setItem('UUIDTOKEN',uuid_token)}// 当用户有uuid时就不会生成return uuid_token
}
用户的uuid_token定义在Detail.js中
import { getUUID } from "@/utils/uuid";const state ={goodList:[],// 游客身份uuid_token:getUUID()
}
requests.js中去发送uuid的参数信息给服务器,返回数据
import store from "@/store";// 请求拦截器:在请求发出去之前会作出一些操作
requests.interceptors.request.use((config)=>{// 1、先判断uuid是否为空if(store.state.Detail.uuid_token){// 2、userTempId字段和后端统一config.headers.userTempId = store.state.Detail.uuid_token}nProgress.start();nProgress.done()return config
})
输入框的加减以及数字的取整
temlple部分
<!-- 减号 --><li class="cart-list-con5"><a class="mins" @click="handler('minus',-1,cart)">-</a><!-- 显示框 --><input autocomplete="off" type="text" :value="cart.skuNum"minnum="1" class="itxt"@change="handler('input',$event.target.value,cart)"><!-- 加号 --><a class="plus" @click="handler('add',1,cart)" >+</a></li>
逻辑部分
// 通过服务器更改产品数量async handler(type,disNum,cart){// 如果type是minus的if(type=='minus'){// 因为值的本身不能低于1disNum =cart.skuNum <1 ? 0:-1}// 如果type是add的话if(type=='add'){disNum=1}// 如果type==changeif(type=='input'){if(isNaN(disNum)&&disNum>0){disNum=0}else{disNum=parseInt(disNum)-cart.skuNum}}try {this.$store.dispatch('getAddorReduceShopCart',{skuId:cart.skuId,skuNum:disNum})this.getData();} catch (error) {alert(error)}}
尚品汇笔记——尚硅谷相关推荐
- vue实战项目-电商商城前台-(学习尚硅谷的)尚品汇
文章目录 最好使用视频上的账号密码,13700000000 密:111111 最新服务端接口地址:http://gmall-h5-api.atguigu.cn 脚手架使用 1.创建项目 2.脚手架默认 ...
- 前端 | ( 九)尚品汇实操练习 | 尚硅谷前端html+css零基础教程2023最新
学习来源:尚硅谷前端html+css零基础教程,2023最新前端开发html5+css3视频 系列笔记: [HTML4](一)前端简介 [HTML4](二)各种各样的常用标签 [HTML4](三)表单 ...
- 尚硅谷尚品汇_后台管理项目
vueProject_尚品汇后台管理 项目源码 文章目录 vueProject_尚品汇后台管理 login/out模块 product模块 login/out模块 .env.development . ...
- 电商项目尚品汇学习笔记
本文参考其他文章自己整理补充的,要阅读原文请查看:尚品汇项目笔记_爱哭的毛毛虫的博客-CSDN博客_尚品汇项目 1.vue文件目录 public文件夹:静态资源,webpack进行打包的时候会原封不动 ...
- 【Vue】032-尚硅谷-尚品汇-mockjs模拟数据---20230111
032-尚硅谷-尚品汇-mockjs模拟数据 官网链接 第一步:安装依赖包mockjs 安装mockjs `npm install --save mockjs` 第二步:在src文件夹下创建一个文件夹 ...
- 尚硅谷 VUE 尚品汇项目实战问题解决方式整理
最近在自学大型vue项目,选中了尚硅谷的尚品汇,之前也学习过黑马程序员的一个电商后台管理项目,因为项目打包优化时候出了Bug,就闲置了,但是代码是一行一行敲完啦,也放到了码云上!学完这个尚品汇准备下一 ...
- 尚品汇项目笔记(持续更新中)
项目网络教学视频链接:尚硅谷VUE项目实战,前端项目-尚品汇(大型\重磅)_哔哩哔哩_bilibili 目录 一. 使用vue-cli脚手架去初始化项目 二.项目的其他配置 三.项目路由分析 四.创建 ...
- 尚硅谷VUE项目实战,前端项目-尚品汇
001-尚硅谷-尚品汇-教程简介_哔哩哔哩_bilibili 需要的知识点 搭建vue-router pages文件夹放置路由页面 router文件夹配置路由 回到入口文件注册(main.js) ...
- 尚硅谷 VUE 尚品汇项目实战问题解决方式整理(Vue3 版)
教学视频:https://www.bilibili.com/video/BV1Vf4y1T7bw 不回要资料的评论,资料在视频底下评论有些仓库里面有. 试图自行解决问题也是程序员必备技能之一,多做尝试 ...
- ① 尚品汇的后台管理系统【尚硅谷】【Vue】
后台管理系统项目简介 什么是后台管理系统项目? 在前端领域当中,开发后台管理系统项目,并非是Java,PHP等后台语言项目 在前面课程当中,我们已经开发了一个项目[尚品汇电商平台项目],这个项目主要针 ...
最新文章
- Java HotSpot VM 命令行参数【官方版】
- linux .sh文件 命令如何写,Linux下面使用命令如何运行.sh文件的两种解决办法
- python中的os abort_Python os.abort()用法及代码示例
- 163 coremail_Icoremail企业邮箱
- jquery-幻灯片效果-编辑中
- Can 情态动词_50
- 新建jsp报错“The superclass javax.servlet.http.HttpServlet was not found on the Java Build Path”...
- Java微信公众平台开发(三)--接收消息的分类及实体的创建
- anguar4 共享服务在多个组件中数据通信
- Oracle数据库练习题(3)
- 什么是DIMM插槽?
- 生物信息学简史,A brief history of bioinformatics- Briefings in Bioinformatics综述解读
- 13.tornado操作之增加用户喜欢的图片展示页+同时展示用户上传的所有图片增加展示图片有多少用户喜欢的功能
- b、B、KB、MB、GB 的关系
- android java 线程通信_Android 线程间通信
- MVC有哪几种过滤器?
- 马尔科夫不等式和坎泰利不等式的证明
- 并行分布式计算 并行计算机体系结构
- 常见的BeanUtils.populate异常 解决方案
- 【转载】自然界通用的“质子缓存”模型