本文主要是介绍外卖APP项目—No.4header组件开发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
外卖APP项目—No.4header组件开发
- 外卖APP项目—No.4header组件开发
- axios应用
- 外部组件
- 渲染效果如下:
- 详情弹层页
- sticky footers布局实现
- StarVue.vue组件实现及应用(五星评价组件)
- flex布局实现
- 完整的HeaderVue.vue组件内容如下:
- 渲染效果如下:
外卖APP项目—No.4header组件开发
本文重点跟大家介绍外卖APP项目的header组件开发,主要包括三部分:axios应用、外部组件、详情弹层页。废话不多说,正文马上开始!
axios应用
- header组件涉及很多商家数据,这些数据需要发送请求来获取,本项目使用axios来发送异步请求。
- axios使用前需要手动安装,安装命令如下:
npm install axios
- 在main.js中引入axios,具体如下:
import { createApp } from 'vue' import App from './App.vue' import router from './router' import store from './store' import axios from 'axios'import './common/stylus/index.styl';axios.defaults.baseURL = 'http://localhost:8080/'const app = createApp(App) app.config.globalProperties.$http = axios app.use(store).use(router).mount('#app')
- 在App.vue中发送请求,获取商家数据,并赋值给data中的seller对象,具体如下:
import Header from './components/header/HeaderVue' export default { data() {return {seller: {},} }, created() {this.getSeller() }, methods: {getSeller(){this.$http.get('/api/data.json').then((res) => {// axios.get('http://localhost:8080/mock/data.json').then((res) => {console.log(res)if(res.status === 200) {this.seller = res.data.seller}}, err => {console.log(err);});},}, components: { Header } }
外部组件
- 父子组件传值:通过props实现
- App.vue通过v-bind将seller传给HeaderVue.vue
- HeaderVue.vue通过以下方式接收seller
props: {seller: {type: Object}}
- 将resource目录中的img子目录的所有图片复制到common目录的stylus子目录下
- 通用样式实现
- 清除浮动:使用after伪元素(修改common目录的stylus子目录下的base.stylus文件,具体如下:)
body,htmlline-height: 1font-weight: 200font-family: 'PingFang SC', 'STHeitisc-Light', 'Helvetica-Light', arial, sans-serif.clearfixdisplay: inline-block&:afterdisplay: blockcontent: "."height: 0line-height: 0clear: bothvisibility: hidden@media (-webkit-min-device-pixel-ratio:1.5),(min-device-pixel-ratio:1.5).border-1px&::after-webkit-transform: scaleY(0.7)transform: scaleY(0.7)@media (-webkit-min-device-pixel-ratio:2),(min-device-pixel-ratio:2).border-1px&::after-webkit-transform: scaleY(0.5)transform: scaleY(0.5)
- 根据设备的dpr设置背景图片(修改common目录的stylus子目录下的mixin.stylus文件,具体如下:)
border-1px($color)position:relative&:afterdisplay:blockposition:absoluteleft:0bottom:0width:100%border-top:1px solid $colorcontent:''border-none()&:afterdisplay: nonebg-image($url)background-image: url($url + "@2x.png")@media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3)background-image: url($url + "@3x.png")
渲染效果如下:
详情弹层页
sticky footers布局实现
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>sticky-footers布局</title><style>body {width: 100vw;height: 100vh;}.top {/* 关键点1:设置内容元素的父容器的min-height: 100%; */min-height: 100%;width: 100%;}.footer {position: relative;width: 100px;height: 32px;/* 关键点3:设置底部元素的margin-top: -64px;,也就是等于内容元素的padding-bottom属性值,从而把底部元素提到内容元素的padding-bottom里 */margin: -64px auto 0 auto;clear: both;font-size: 32px;}.main {margin-top: 64px;/* 关键点2:设置内容元素的padding-bottom: 64px;,为底部元素预留位置 */padding-bottom: 64px;}.clearfix {display: inline-block;}.clearfix:after {display: block;content: ".";height: 0;line-height: 0;clear: both;visibility: hidden;}</style>
</head>
<body><div class="top clearfix"><div class="main">This is the main content.This is the main content.This is the main content.Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreetdolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipitlobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velitesse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odiodignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.This is the main content.This is the main content.This is the main content.Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreetdolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipitlobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velitesse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odiodignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.This is the main content.This is the main content.This is the main content.Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreetdolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipitlobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velitesse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odiodignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla.</div></div><div class="footer">close</div>
</body>
</html>
渲染效果如下:
StarVue.vue组件实现及应用(五星评价组件)
- 在components目录下新建star子目录,并在该子目录下新建StarVue.vue文件,文件内容具体如下:
<template><div class="star" :class="starType"><span v-for="(itemClass, index) in itemClasses" :key="index" :class="itemClass" class="star-item"></span></div> </template><script type="text/ecmascript-6">const LENGTH = 5const CLS_ON = 'on'const CLS_HALF = 'half'const CLS_OFF = 'off'export default {data () {return {}},props:{size:{type: Number},score:{type: Number}},computed:{starType(){return 'star-' + this.size;},itemClasses(){let result = [];let score = Math.floor(this.score * 2) / 2;let hasDecimal = score % 1 !== 0;let integer = Math.floor(score);for(let i = 0; i < integer; i++){result.push(CLS_ON);}if(hasDecimal){result.push(CLS_HALF);}while(result.length < LENGTH){result.push(CLS_OFF);}return result;}},methods: {},} </script><style lang="stylus" rel="stylesheet/stylus">@import "../../common/stylus/mixin.styl";.starz-index: 200font-size: 0px.star-itemdisplay: inline-blockbackground-repeat: no-repeat&.star-48.star-itemwidth: 20pxheight 20pxmargin-right: 22pxbackground-size: 20px 20px&:last-childmargin-right: 0&.onbg-image('star48_on')&.halfbg-image('star48_half')&.offbg-image('star48_off')&.star-36.star-itemwidth: 15pxheight 15pxmargin-right: 16pxbackground-size: 15px 15px&:last-childmargin-right: 0&.onbg-image('star36_on')&.halfbg-image('star36_half')&.offbg-image('star36_off')&.star-24.star-itemwidth: 10pxheight 10pxmargin-right: 3pxbackground-size: 10px 10px&:last-childmargin-right: 0&.onbg-image('star24_on')&.halfbg-image('star24_half')&.offbg-image('star24_off') </style>
- 在HeaderVue.vue中引入组件,具体如下:
import Star from '../star/StarVue.vue'
flex布局实现
Flex 布局教程:语法篇
Flex 布局教程:实例篇
完整的HeaderVue.vue组件内容如下:
<template><div class="header"><div class="content-wrapper"> <div class="avater"><img width="64" :src="seller.avater" alt="商家头像"><!-- <img width="64" src="../../../static/img/01_seller_avater.png" alt="商家头像"> --></div><div class="content"><div class="title"><span class="brand"></span><span class="name">{{seller.name}}</span></div><div class="description">{{seller.description}}/{{seller.deliveryTime}}分钟送达</div><div v-if="seller.supports" class="support"><span class="icon" :class="classMap[seller.supports[0].type]"></span><span class="text">{{seller.supports[0].description}}</span></div></div><div v-if="seller.supports" class="support-count" @click="showDetail()"><span class="count">{{seller.supports.length}}个</span><i class="icon-circle-right"></i></div></div> <div class="bulletin-wrapper" @click="showDetail()"><span class="bulletin-title"></span><span class="bulletin-text">{{seller.bulletin}}</span><i class="icon-circle-right"></i></div><div class="background"><img :src="seller.avater" alt="商家头像" width="375" height="132"></div><transition name="fade"><div v-show="detailShow" class="detail"><div class="detail-wrapper clearfix"><div class="detail-main"><h1 class="name">{{seller.name}}</h1><div class="star-wrapper"><Star :size="48" :score="seller.score"></Star></div><div class="title"><div class="line"></div><div class="text">优惠信息</div><div class="line"></div></div><ul v-if="seller.supports" class="supports"><li class="support-item" v-for="(item, i) in seller.supports" :key="i"><span class="icon" :class="classMap[seller.supports[i].type]"></span><span class="text">{{seller.supports[i].description}}</span></li></ul><div class="title"><div class="line"></div><div class="text">商家公告</div><div class="line"></div></div><div class="bulletin"><p class="content">{{seller.bulletin}}</p></div></div></div><div class="detail-close" @click="hideDetail"><i class="icon-cancel-circle"></i></div></div></transition></div>
</template><script >import Star from '../star/StarVue.vue'export default {data() {return {detailShow: false}},props: {seller: {type: Object}},created(){this.classMap = ['decrease', 'discount', 'special', 'invoice', 'guarantee']},components:{Star},methods: {showDetail(){this.detailShow = true},hideDetail(){this.detailShow = false}},}
</script><style lang="stylus" rel="stylesheet/stylus">@import "../../common/stylus/mixin.styl";.headerposition: relativeoverflow: hiddencolor:#fffbackground: rgba(7, 17, 27, 0.5).content-wrapperposition relativepadding: 24px 12px 18px 24pxfont-size: 0.avaterdisplay: inline-blockvertical-align: topimgborder-radius: 2px.contentdisplay: inline-blockmargin-left: 16px.titlemargin: 2px 0 8px 0.branddisplay: inline-blockvertical-align: topwidth: 30pxheight: 18pxbg-image('brand')background-size: 30px 18pxbackground-repeat: no-repeat.namemargin-left: 6pxfont-size: 16pxline-height: 18pxfont-weight: bold.descriptionmargin-bottom: 10pxline-height: 12pxfont-size: 12px.support.icondisplay: inline-blockvertical-align: topwidth: 12pxheight: 12pxmargin-right: 4pxbackground-size: 12px 12pxbackground-repeat: no-repeat&.decreasebg-image('decrease_1')&.discountbg-image('discount_1')&.guaranteebg-image('gurantee_1')&.invoicebg-image('invoice_1')&.specialbg-image('special_1').textline-height: 12pxfont-size: 10px.support-countposition: absoluteright: 12pxbottom: 18pxpadding: 0 8pxheight 24pxline-height: 24pxborder-radius: 14pxbackground-color: rgba(0, 0, 0, 0.2)text-align: center.countvertical-align: topfont-size: 10px.icon-circle-rightdisplay: inline-blockmargin-left: 6pxline-height: 24pxfont-size: 10px.bulletin-wrapperposition: relativeheight: 28pxline-height: 28pxpadding: 0 22px 0 12pxwhite-space: nowrapoverflow: hiddentext-overflow: ellipsisbackground: rgba(7, 17, 27, 0.2).bulletin-titledisplay: inline-blockvertical-align: topmargin-top: 8pxwidth: 22pxheight: 12pxbg-image('bulletin')background-size: 22px 12pxbackground-repeat: no-repeat.bulletin-textvertical-align: topmargin:0 4px font-size: 10px.icon-circle-rightposition: absolutefont-size: 10px right: 12pxtop: 8px.backgroundposition: absolutetop: 0left: 0width: 100%height: 100%z-index: -1filter: blur(10px).detailposition: fixedz-index: 100top: 0left: 0width: 100%height: 100%overflow: auto// transition: all 0.5sbackground: rgba(7, 17, 27, 0.8)backdrop-filter: blur(10px)&.fade-enter-active, &.fade-leave-activetransition: all 0.5s&.fade-enter, &.fade-leave-toopacity: 0background: rgba(7, 17, 27, 0.8)// &.fade-transition// opacity: 1// background: rgba(7, 17, 27, 0.8)// &.fade-enter, &.fade-leave// opacity: 0// background: rgba(7, 17, 27, 0).detail-wrappermin-height: 100%width: 100%.detail-mainmargin-top: 64pxpadding-bottom: 64px.nameline-height: 16pxtext-align: centerfont-size: 16pxfont-weight: 700.star-wrappermargin-top: 18pxpadding: 2px 0text-align-last: center.titledisplay: flexwidth: 80%margin: 28px auto 24px auto.lineflex: 1position: relativetop:-6pxborder-bottom: 1px solid rgba(255, 255, 255, 0.2).textpadding: 0 12pxfont-weight: 700font-size: 14px.supportswidth: 80%margin: 0 auto.support-itempadding: 0 12pxmargin-bottom: 12pxfont-size: 0&:last-childmargin-bottom: 0.icondisplay: inline-blockwidth: 16pxheight: 16pxvertical-align: topmargin-right: 6pxbackground-size: 16px 16pxbackground-repeat: no-repeat&.decreasebg-image('decrease_2')&.discountbg-image('discount_2')&.guaranteebg-image('gurantee_2')&.invoicebg-image('invoice_2')&.specialbg-image('special_2').textline-height: 16pxfont-size: 12px.bulletinwidth: 80%margin: 0 auto.contentpadding: 0 12pxline-height: 24pxfont-size: 12px.detail-closeposition: relativewidth: 32pxheight: 32pxmargin: -64px auto 0 autoclear: bothfont-size: 32px
</style>
渲染效果如下:
这篇关于外卖APP项目—No.4header组件开发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!