饿了么购物车动画实现
NO PICTURE SAY JB
前言
好久好久没有更新博客了,最近工作确实有点忙,最近的项目总结也一直拖着没写,但是懒才是原罪😔,年轻人要努力啊😤
实现技术
- 移动端布局: flex + rem + flexible(移动端貌似用视口单位更好) + SVG
- 前端框架: VUE(使用了VUE脚手架,版本3+)
- 第三方插件:better-scroll
实现过程
基本结构的搭建
开发是以宽750px的屏幕为基准的,使用rem是为了适应不同尺寸的屏幕。flexible的原理是将屏幕直接分为10等份,以750的屏幕来说,每一份是75px,然后设置1rem === 75px就可以了。
引入flexible
需要注意的地方
当屏幕宽度小于750的时候强制指定根元素的: font-size: 75px去覆盖flexible的值,rem(root rm)是根据根元素的font-size大小确定的。
好用的vscode插件
px to rem & rpx
:自动帮你把px转化为rem,前提是需要设置好参考值:1rem对应多少px
在项目中使用SVG
- 安装插件:
npm install vue-svg-loader --save
- 在根目录下新建vue.config.js
const path = require('path')
function resolve(dir) {
return path.join(__dirname, './', dir)
}
module.exports = {
chainWebpack: config => {
config.plugin('define').tap(args => {
const argv = process.argv
const icourt = argv[argv.indexOf('--icourt-mode') + 1]
args[0]['process.env'].MODE = `"${icourt}"`
return args
})
// svg rule loader
const svgRule = config.module.rule('svg') // 找到svg-loader
svgRule.uses.clear() // 清除已有的loader, 如果不这样做会添加在此loader之后
svgRule.exclude.add(/node_modules/) // 正则匹配排除node_modules目录
svgRule // 添加svg新的loader处理
.test(/\.svg$/)
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]',
})
// 修改images loader 添加svg处理
const imagesRule = config.module.rule('images')
imagesRule.exclude.add(resolve('src/icons')) //存储svg文件的根目录
config.module
.rule('images')
.test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
},
configureWebpack: {
devServer: {
open: true,
// https: true,
proxy: {
'/user': {
target: 'https://devadminschool.icourt.cc',
},
'/live': {
target: 'https://devadminschool.icourt.cc',
},
},
},
},
}
- 新建 svgIcon.vue组件
<template>
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName"/>
</svg>
</template>
<script>
export default {
name: "svgIcon",
props: {
iconClass: {
type: String,
required: true,
},
className: {
type: String,
default: '',
},
},
computed: {
iconName() {
return `#icon-${this.iconClass}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
},
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
fill: currentColor;
overflow: hidden;
}
</style>
- src目录下新建icons文件夹
这个文件夹跟第二步中的对应,如下图
icons中新建svg文件夹(存储svg文件)和 index.js
//index.js 内容 import Vue from 'vue' import SvgIcon from '@/components/svgIcon' // svg组件 // 注册到全局 Vue.component('svg-icon', SvgIcon) const requireAll = requireContext => requireContext.keys().map(requireContext) const req = require.context('./svg', false, /\.svg$/) requireAll(req)
在项目中使用
功能点实现
滑动效果实现
滑动效果要考虑到左侧与右侧的联动,点击左侧,右侧需要调到相应位置,滑动右侧,左侧也要相应变化。
对于右侧:获取每一个大类(例如:湘菜、川菜)距离顶部的距离(offsetTop),然后监听scroll事件,将事件的y值与每一项的offsetTop对比来联动左侧
对于左侧: 点击的哪一个直接将右侧的dom元素的实例上滑-offsetTop
遇到的坑
使用BScroll的时候,发现滑动不了:
加入购物车效果实现
当点击+的时候,需要实现购物车跳入的动画,通过 vue 过渡实现
补充:
- getBoundingClientRect()是DOM元素到浏览器的可视距离
- 通过监听 transitionend、animationend进行相应状态变化
努力哦,少年!!!