外卖APP项目—No.3页面骨架开发
外卖APP项目—No.3页面骨架开发
本文重点跟大家介绍外卖APP项目的页面骨架开发,主要包括三部分:组件拆分、Vue-router、1像素border实现。废话不多说,正文马上开始!
组件拆分
组件拆分(上)
- 本项目为一个单页面应用,根组件为App.vue; 根组件下分为goods(商品)、ratings(评价)、seller(商家)三个子组件。
- 在public目录下新建css子目录,将reset.css文件存放在该子目录下,reset.css可以帮助我们对页面以及一些DOM元素做一些通用的样式设置。
reset.css文件/** * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/) * http://cssreset.com */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video{ margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; font-weight: normal; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section{ display: block; } ol, ul, li{ list-style: none; } blockquote, q{ quotes: none; } blockquote:before, blockquote:after, q:before, q:after{ content: ''; content: none; } table{ border-collapse: collapse; border-spacing: 0; } /* custom */ a{ color: #7e8c8d; text-decoration: none; -webkit-backface-visibility: hidden; } ::-webkit-scrollbar{ width: 5px; height: 5px; } ::-webkit-scrollbar-track-piece{ background-color: rgba(0, 0, 0, 0.2); -webkit-border-radius: 6px; } ::-webkit-scrollbar-thumb:vertical{ height: 5px; background-color: rgba(125, 125, 125, 0.7); -webkit-border-radius: 6px; } ::-webkit-scrollbar-thumb:horizontal{ width: 5px; background-color: rgba(125, 125, 125, 0.7); -webkit-border-radius: 6px; } html, body{ width: 100%; font-family: "Arial", "Microsoft YaHei", "黑体", "宋体", "微软雅黑", sans-serif; } body{ line-height: 1; -webkit-text-size-adjust: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } html{ overflow-y: scroll; } /*清除浮动*/ .clearfix:before, .clearfix:after{ content: " "; display: inline-block; height: 0; clear: both; visibility: hidden; } .clearfix{ *zoom: 1; } /*隐藏*/ .dn{ display: none; }
- 在index.html中引入reset.css文件,并设置禁止视口缩放,因为本项目是一个移动端Web应用,视口不可缩放
index.html<!DOCTYPE html> <html lang=""> <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,maximum-scale=1.0, minimum-scale=1.0,user-scalable=no"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <title><%= htmlWebpackPlugin.options.title %></title> <link rel="stylesheet" type="text/css" href="css/reset.css"> </head> <body> <noscript> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
组件拆分(中)
- 在components目录下创建header子目录,在header子目录创建HeaderVue.vue组件
注意:根据 ESLint 官方代码风格指南,除了根组件(App.vue)以外,其他自定义组件命名要使用大驼峰命名方式或者用“-”连接单词进行命名;
HeaderVue.vue<template> <div class="header"> 我是header </div> </template> <script > export default { setup() { } } </script> <style > </style>
- 在App.vue中引入HeaderVue.vue组件
组件拆分(下)
- 使用flex布局实现tabbar
App.vue<template> <div id="app"> <div id="header"> <Header></Header> </div> <div class="tab"> <div class="tab-item">商品</div> <div class="tab-item">评价</div> <div class="tab-item">商家</div> </div> <div class="content"> I am content </div> </div> </template> <script> import { } from 'vue'; import Header from './components/header/HeaderVue' export default { setup() { }, components: { Header }, } </script> <style lang="stylus" rel="stylesheet/stylus"> #app .tab display: flex width :100% height: 40px line-height: 40px .tab-item flex: 1 text-align: center </style>
渲染效果如下:
Vue-router
Vue-router(上)
- 在components目录下新建goods、ratings、seller三个子目录,在这三个子目录下分别新建GoodsVue.vue、Ratings.vue、SellerVue.vue三个组件。
注意:组件内容可以先不用在意,此处以GoodsVue.vue为例,给出我的demo。<template> <div class="goods"> 我是GoodsVue </div> </template> <script > export default { setup() { } } </script> <style > </style>
- 配置路由信息,也就是修改router目录下的index.js文件,具体如下:
index.js文件import { createRouter, createWebHashHistory } from 'vue-router' const routes = [ { path: '/', redirect: '/goods', }, { path: '/goods', name: 'goods', component: () => import('../components/goods/GoodsVue') }, { path: '/ratings', name: 'ratings', component: () => import('../components/ratings/RatingsVue') }, { path: '/seller', name: 'seller', component: () => import('../components/seller/SellerVue') } ] const router = createRouter({ history: createWebHashHistory(), routes, linkActiveClass:'active' }) export default router
- 修改App.vue文件,具体如下:
App.vue<template> <div id="app"> <div id="header"> <Header></Header> </div> <div class="tab border-1px"> <div class="tab-item"> <router-link to="/goods">商品</router-link> </div> <div class="tab-item"> <router-link to="/ratings">评论</router-link> </div> <div class="tab-item"> <router-link to="/seller">商家</router-link> </div> </div> <div class="content"> <keep-alive> <router-view></router-view> </keep-alive> </div> </div> </template>
Vue-router(下)
-
完善tabbar的样式,使其在选中的情况下使用高亮样式
修改App.vue文件中的样式如下:#app .tab display: flex width :100% height: 40px line-height: 40px .tab-item flex: 1 text-align: center & > a /* display: block; 可以使得点击超链接所在的整个div都有效,否则只有点中超链接文本时才有效,这一属性可以优化用户体验 */ display: block font-size: 14px color: #778593 &.active color #fff background-color: #f60
-
在router目录下的index.js文件中,添加如下所示的属性配置:
linkActiveClass:‘active’
渲染效果如下:
1像素border实现
- 在common目录的stylus子目录下新建mixin.styl文件,具体内容如下:
border-1px($color) position:relative &:after display:block position:absolute left:0 bottom:0 width:100% border-top:1px solid $color content:''
- 在App.vue中使用@import引入mixin.styl:
@import "./common/stylus/mixin.styl"
- 在common目录的stylus子目录下新建base.styl文件,在这个文件中全局定义border-1px的css类,并将其应用到App.vue的类名为tab的div中,base.styl具体内容如下:
@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)
- 在common目录的stylus子目录下新建index.styl文件,使用@import引入mixin.styl、icon.styl和base.styl三个文件,具体如下:
@import "./mixin" @import "./icon" @import "./base"
- 在main.js中全局引入index.styl,具体如下:
import './common/stylus/index.styl';
渲染效果如下:
总结:移动端1像素边框的实现主要通过伪元素和缩放实现;在需要添加边框的元素上添加一个after伪元素,并设置这个伪元素为绝对定位,使其定位到需要添加边框元素的下方,并给这个伪元素添加1像素的边框;再定义一个全局css类,并根据设备最小的dpi设置缩放比例,比如最小dpr为1.5,缩放比例就为0.7;最小dpr为2,缩放比例就为0.5。