Vue3 仿京东电商项目 | 首页开发【项目初始化】

完整原文地址见简书

更多完整Vue笔记目录敬请见《前端 Web 笔记 汇总目录(Updating)》



本文内容提要

  • 项目初始化
  • 装ESLint插件
  • 装Vetur插件
  • 目录 | node_modules、package.json
  • 目录 | public目录
  • 目录 | .editorconfig文件
  • 目录 | package-lock.json
  • 目录 | src
  • 样式兼容浏览器
  • 使用移动端模拟器
  • iconfont.cn阿里矢量图标库的使用【采集icon到项目】
  • 浏览器最小只能使用12px的文字尺寸,如果要显示10px,需要写20px然后缩小一半
  • 优化 | 有从属关系的css 可以简写
  • 优化 | css引入的简写

  • 1.end 至此底部栏UI基本完成
  • 2.1 bug | error Trailing spaces not allowed no-trailing-spaces
  • 2.2 注意 | CSS Class的优先级
  • 2.3 新建scss文件,定义通用的样式变量【类似 android的res/style/ 下文件】
  • 2.4 新建scss文件,封装mixin,效果同上
  • 位置栏至此初步完成
  • 3. 搜索和 banner区域
    • 3.1 新增iconfont项目图标【search】,更新项目 链接资源代码
    • 3.2 防止弱网时,图标加载太慢 导致周围组件 发生抖动
  • 4.图标 Grid网格布局
  • 5.附近栏
    • 5.1 流式布局的魅力
    • 5.2 注意<p>标签的默认margin!!(其他标签 也要注意 默认margin等)
  • 5.3 【overflow-y: auto】处理溢出,使得底部导航栏不会跟着动
  • 6.拆分组件代码
    • 然后是Nearby部分的拆分
    • home.vue中注册为子组件:
    • 最后拆分底部导航栏部分
  • 7.使用v-for、v-html优化代码
    • ** 7.1 iconfont转义问题**
    • 7.2 巧用表达式控制css处理!!!
    • ** 7.3 字符串模板 匹配实战**
    • 7.4 首页UI基本实现(画完了)
    • 8.1 scoped 限制 样式的作用范围
    • 8.2 安装、使用Vue.js devtools


项目初始化


装ESLint插件

协助做代码校验,规范代码:


装Vetur插件

识别、高亮显示Vue语法:


目录 | node_modules、package.json

npm install之后(有时候项目会自动生成,就无需npm install了),
package.json 是 记录第三方库依赖 的目录,
node_modules 存放 第三方库依赖模块:

其中,package.json 的代码其实有很多学问:
《package.json配置详解》中,
browserslist 指定项目兼容浏览器或设备的版本,
"> 1%"指全球范围内用户使用量> 1%的浏览器;
"last 2 versions"指上述的浏览器中,只支持最新的两个浏览器版本;
"not dead"指正在维护的浏览器;

{
  "name": "h5-components",
  "version": "1.2.0",
  "description": "",
  "main": "./lib/index",
  "module": "./es/index",
  "files": [
    "lib",
    "es",
    "dist",
    "assets"
  ],
  "repository": "http://.../h5-components.git",
  "homepage": "http://...",
  "author": "",
  "license": "MIT",
  "scripts": {
    "dll": "webpack --config webpack.dll.config.js",
    "rccompile": "rc-tools run compile --babel-runtime --copy-files",
    "dev": "webpack-dev-server --env.api dev",
    "rcdist": "rc-tools run dist",
    "ucs": "yarn upgrade h5-css",
    "rclint": "rc-tools run lint",
    "build": "yarn rccompile && git add . && git commit -m '[compile]' && git pull && git push"
  },
  "config": {
    "port": 8089,
    "entry": {
      "h5-components": [
        "./index.js"
      ]
    }
  },
  "dependencies": {
    "antd-mobile": "^2.2.0",
    "classnames": "^2.2.1",
    "exif-js": "^2.3.0"
  },
  "devDependencies": {
    "file-loader": "^1.1.5",   
    "less-loader": "^4.1.0",
    "lodash": "^4.17.4",
    "lodash-webpack-plugin": "^0.11.4",
    "mini-css-extract-plugin": "^0.4.1"   
  },
  "sideEffects": [
    "*.scss"
  ],
  "browserslist": [
    "iOS >= 8",
    "Firefox >= 20",
    "Android > 4.2",
    "> 1%",
    "last 2 versions",
    "not ie <= 10"
  ]
}


目录 | public目录

这里主要是配置了一些通用的内容,如这里的index.html中的icon,配置了网页的图标:


目录 | .editorconfig文件

配置编辑器的特性;

EditorConfig使用介绍


目录 | package-lock.json

保证多人协作的时候,依赖能有一个固定的版本;


目录 | src

这里各个文件目录的作用和使用前面基本都用到过了;
assets目录下放一些静态的文件;


样式兼容浏览器

有些HTML标签,同一个标签,在不同的浏览器上,展示效果不一致;
为了 写出来的样式 可以在所有的浏览器上 保持一致,
需要借助一下normallize.css

这里需要在项目上install一下:

添加@[版本],可以指定安装的版本:
在src下新建一个style目录,下新建一个base.scss文件,
编写通用的样式,
这里指定html标签的样式——1rem = font-size = 100px;

清理router中多余的代码,
这边暂时简单测试即可:

在main.js中引入:
运行项目:
可以看到字体很大,
因为这里App.vue的布局自然是在html标签下的,
于是默认使用我们方才定义的样式尺寸:


使用移动端模拟器

首先可以调整一下测试栏的位置:

然后打开移动端模拟器:


iconfont.cn阿里矢量图标库的使用【采集icon到项目】

登录后,搜索图标然后加入购物车:

把购物车里的图标加入项目:
加入已有项目:
或者新建一个项目:
点击到【我的项目】:
可以查看已有的项目内容:
点击下载到本地,
可以将当前目录下的图标的各种格式打包成zip下载下来:
把其中的iconfont.css的这一部分代码复制一下:

在style目录下新建一个css文件,如iconfont.css,把复制的代码贴到这里,
不过这里引用的代码还是本地的,
我们可以替换成在线的:

点击查看在线连接,
点击【暂无代码,点此生成】,
可以生成在线连接代码:
复制上面的在线url引用代码,贴到项目里:
main.js引入这个css文件:
到这里环境就配置完成了;
接着在iconfont网页上,移动到图标上,点击复制对应图标的代码,如&#xe7c7;
最后在DOM节点中使用就可以了,
注意写上class="iconfont"
效果:


浏览器最小只能使用12px的文字尺寸,如果要显示10px,需要写20px然后缩小一半

.docker_title {
  font-size: 20px;
  transform: scaleX(.5) scaleY(.5);//缩小一半
  transform-origin: center top;//缩小中心点
}


优化 | 有从属关系的css 可以简写

注意这里的flex流式布局

<template>
  <div class="docker">
    <span class="docker__item docker__item--active">
      <div class="iconfont">&#xe7c7;</div>
      <div class="docker_title">首页</div>
    </span>
    <span class="docker__item docker__item--active">
      <div class="iconfont">&#xe63a;</div>
      <div class="docker_title">购物车</div>
    </span>
    <span class="docker__item docker__item--active">
      <div class="iconfont">&#xe61e;</div>
      <div class="docker_title">订单</div>
    </span>
    <span class="docker__item docker__item--active">
      <div class="iconfont">&#xe66f;</div>
      <div class="docker_title">我的</div>
    </span>
  </div>
</template>

<style lang="scss">
.docker {
  display: flex;
  box-sizing: border-box;
  position: absolute;
  padding: 0 0.18rem; //间隔
  left: 0;
  bottom: 0;
  width: 100%;
  height: 0.49rem;
  border-top: 1px solid #f10000;

  &__item {
    //等价于 .docker__item
    flex: 1;
    text-align: center;
    .iconfont {
      margin: 0.07rem 0 0.02rem 0; //图标间隔
      font-size: 0.18rem; //调整图标大小
    }
    &--active {
      //等价于 .docker__item--active
      color: skyblue;
    }
  }

  &_title {
    //等价于 .docker_title
    font-size: 20px;
    transform: scaleX(0.5) scaleY(0.5); //缩小一半
    transform-origin: center top; //缩小中心点
  }
}
// .docker__item {
//   flex: 1;
//   text-align: center;
//   .iconfont {
//     margin: 0.07rem 0 0.02rem 0; //图标间隔
//     font-size: 0.18rem; //调整图标大小
//   }
// }
// .docker__item--active {
//   color: skyblue;
// }
// .docker_title {
//   font-size: 20px;
//   transform: scaleX(0.5) scaleY(0.5); //缩小一半
//   transform-origin: center top; //缩小中心点
// }
</style>


优化 | css引入的简写

当前的css文件引入我们是这样写的:

其实我们可以在style目录下新建一个文件,如index.scss
然后把需要引用的css文件都写在这里面:
这样,
使用的时候就只要引入index.scss这个“引用汇总文件”就可以了:


1.end 至此底部栏UI基本完成

commit a0c19703acc3c0da070c9b2b291bdce11ff33646 (HEAD -> master)
Author: aaLiweipeng <31944741+aaLiweipeng@users.noreply.github.com>
Date:   Sat May 8 22:18:29 2021 +0800

    Preliminary completion of the bottom bar

github-commit: https://github.com/aaLiweipeng/ec-pro-202105/commit/30a33b963c323a12b3c1f5a15b238d3aac289a4e


2.1 bug | error Trailing spaces not allowed no-trailing-spaces

解决方案:删除尾部多余的空格


2.2 注意 | CSS Class的优先级

有时候同一个标签,
我们可能会给它定义了多个CSS Class:

这个时候,
我们可以用这种 嵌套 且 不使用&...简写 的方式,
提高CSS Class的优先级:
如此,position__icon的优先级会比iconfont高;


2.3 新建scss文件,定义通用的样式变量【类似 android的res/style/ 下文件】

使用示例:


2.4 新建scss文件,封装mixin,效果同上

使用示例:


位置栏至此初步完成

commit d81edf449371f5d14972e5a6f0b328f2693cde8e (HEAD -> main, origin/main, origin/HEAD)
Author: aaLiweipeng <31944741+aaLiweipeng@users.noreply.github.com>
Date:   Mon May 10 00:23:59 2021 +0800

    Add the top position bar

github:https://github.com/aaLiweipeng/ec-pro-202105/commit/d81edf449371f5d14972e5a6f0b328f2693cde8e


3. 搜索和 banner区域

3.1 新增iconfont项目图标【search】,更新项目 链接资源代码

运行效果:


3.2 防止弱网时,图标加载太慢 导致周围组件 发生抖动【padding、overflow 结合 图片宽高比的 占位技巧】

.banner{
  //以下三行,用于防止弱网时,图标加载太慢
  //导致周围组件 发生抖动
  height: 0;
  overflow: hidden;
  padding-bottom: 46.7%;//图片的宽高比,图片未下载好时提前占位 373/798≈0.4674

  &__img {
    width: 100%;//撑满父布局
  }
}

搜索框和banner初步完成,
GitHub:


4.图标 Grid网格布局

GitHub:**


5.附近栏

GitHub:**

5.1 流式布局的魅力
//附近栏
.nearby {
  &__title {
    margin: .16rem 0 0.04rem 0;
    font-size: .18rem;
    font-weight: normal;
    color: $content-fontcolor;
  }
  &__item {
    // display: flex;
    &__img {
      width: .56rem;
      height: .56rem;
    }
  }
}



//附近栏
.nearby {
  &__title {
    margin: .16rem 0 0.04rem 0;
    font-size: .18rem;
    font-weight: normal;
    color: $content-fontcolor;
  }
  &__item {
    display: flex;
    &__img {
      width: .56rem;
      height: .56rem;
    }
  }
}


5.2 注意<p>标签的默认margin!!(其他标签 也要注意 默认margin等)
    &__highlight {
      // margin: 0.08rem 0 0 0;
      margin-top: 0.08rem;
      line-height: .18rem;
      font-size: .13rem;
      color: #e93b3b;
    }


优化方案:
使用详细的margin样式,处理掉默认的margin:

    &__highlight {
      margin: 0.08rem 0 0 0;
      line-height: .18rem;
      font-size: .13rem;
      color: #e93b3b;
    }

效果:


5.3 【overflow-y: auto】处理溢出,使得底部导航栏不会跟着动
.wrapper {
  overflow-y: auto;//处理溢出,使得底部导航栏不会跟着动
  //内容的 根布局
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0.5rem;
  right: 0;
  padding: 0 0.18rem; //整体内容留白 间隔 上下无 左右0.18
}


6.拆分组件代码

GitHub:
--- views目录下创建一个home目录,
home下新建一个Home.vue;
把App.vue的内容剪切过来;
这个时候App.vue没内容,
然后Home里面的引用路径得改一下:


然后这时候,
App.vue改成一下内容,
就可以如旧正常显示了:

<template>
  <Home />
</template>

<script>
import Home from './views/home/Home'

export default {
  name: 'App',
  components: { Home }
}
</script>

当然这时候只是把主页Home.vue从App.vue中拆除出去而已,
接下来还需要继续拆分;
首先把position部分gap部分拆分出来,
为顶部业务部分【TopPart】:


view/home/TopPart.vue:

<template>
<div class="position">
      <span class="iconfont position__icon">&#xe64f;</span>
      XXXX大学XXXX区66号楼66层
      <span class="iconfont position_notice">&#xe6bb;</span>
    </div>

    <div class="search">
      <span class="iconfont">&#xe613;</span>
      <span class="search__text">菠萝菠萝包</span>
    </div>

    <div class="banner">
      <img
        class="banner__img"
        src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.yipic.cn%2Fthumb%2Ff0f77685%2Fbdaa5f3f%2Ffa49ab25%2Fc7151244%2Fbig_f0f77685bdaa5f3ffa49ab25c7151244.png&refer=http%3A%2F%2Fimg.yipic.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1623252871&t=7a27caac9990c344d03ff0dfff8f6c1d"
      />
    </div>

    <!-- icon网格布局 -->
    <div class="icons">
      <div class="icons__item">
        <img
          class="icons__item__img"
          src="http://www.dell-lee.com/imgs/vue3/菜市场.png"
        />
        <p class="icons__item__desc">菜市场</p>
      </div>
      ...
    </div>

    <!-- 网格布局下 灰色间隔线区 -->
    <div class="gap"></div>

</template>

<style lang="scss">
...
.position {
...
  .position__icon {
  ...
  }
  .position_notice {
...
  }
  color: $content-fontcolor;
}

.search {
...

  .iconfont {
...
  }

  &__text {
...
  }
} //search

//icon网格布局
.icons {
  ...
  &__item {
    ...

    &__img {
      ...
    }
    &__desc {
     ...
    }
  }
}

.banner {
...
  &__img {
    ...
  }
}

//网格布局下 灰色间隔线区
.gap {
...
}
</style>

然后作为子组件引入到Home.vue

<script>
import TopPart from './TopPart'

export default {
  name: 'Home',
  components: { TopPart }
}
</script>

使用:

然后是Nearby部分的拆分

新建文件,
views/home/Nearby.vue,
把home中的【附近栏】相关的代码移过来:


home.vue中注册为子组件:

<script>
import TopPart from './TopPart'
import Nearby from './Nearby'

export default {
  name: 'Home',
  components: { TopPart, Nearby }
}
</script>

使用:

最后拆分底部导航栏部分

新建 views/home/Docker.vue,
把home中的【底部导航栏】相关的代码移过来:;
home.vue中注册为子组件:

<script>
import TopPart from './TopPart'
import Nearby from './Nearby'
import Docker from './Docker'

export default {
  name: 'Home',
  components: { TopPart, Nearby, Docker }
}
</script>

使用:


7.使用v-for、v-html优化代码

主要优化Grid菜单部分,附近栏 和 底部导航栏部分等 list特性的模块,
细节可以看 GitHub:

7.1 iconfont转义问题
<!-- 底部导航栏 -->
  <div class="docker">
    <div
      v-for = "item in dockerList"
      class="docker__item docker__item--active"
      :key="item.icon"
    >

      <!-- 这里不可以用插值表达式写,
      因为 &# 会被自动转义成 文本,
      无法实施符号特性;
      改完记得刷新下页面!!! -->
      <!-- <div class="iconfont">{{item.icon}}</div> -->

      <div class="iconfont" v-html="item.icon" />
      <div class="docker_title">{{item.text}}</div>
    </div>
  </div>
7.2 巧用表达式控制css处理!!!
  • 处理前:
  <!-- 底部导航栏 -->
  <div class="docker">
    <div
      v-for = "item in dockerList"
      class="docker__item docker__item--active"
      :key="item.icon"
    >
.....
  • 处理后,
    更改class属性,使得颜色的样式需要判断,默认是第一个有蓝色:
  <!-- 底部导航栏 -->
  <div class="docker">
    <div
      v-for = "(item, index) in dockerList"
      :class="{ 'docker__item': true, 'docker__item--active': index === 0}"
      :key="item.icon"
    >


7.3 字符串模板 匹配实战


7.4 首页UI基本实现(画完了)


8.

8.1 scoped 限制 样式的作用范围

一个组件的样式应该只能作用于自身组件
不能影响外部组件或者其他组件

实现方式很简单,
只要style标签加个scoped即可,
建议如果没有特殊的需求,
所有单文件组件style标签都可以加上这个特性:


8.2 安装、使用Vue.js devtools

需要梯子,需要在Chrome中进行,
打开网上应用商店:


搜索 类似vue dev字眼:
添加该插件:
然后启用:
然后重启Chrome,打开项目,刷新页面,
点击如下图的位置,可以打开工具:
---Vue devtools第一个功能——可以轻易而直观地观察到
页面各个 分模块/子组件 的区域 以及 分模块/子组件 名:
这个显示的名称,取决于该组件的文件名【毕竟单文件组件】:
不过如果文件中<script>中,有对name属性进行定义的话,则根据这个name属性来处理显示:
---Vue devtools第二个常用功能——
双击某个模块,可以看到其对应的数据、路由情况,
方便做参数调测等:


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,335评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,895评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,766评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,918评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,042评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,169评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,219评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,976评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,393评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,711评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,876评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,562评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,193评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,903评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,699评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,764评论 2 351

推荐阅读更多精彩内容