vue2.x仿饿了么app,不同的封装思路,很适合初学者练手

2,117 阅读7分钟

项目vue2.0_elm

这是我的第一篇博客,这个项目也是我第一个相对来说技术比较全面的项目,感觉比较适合新手练手,我自己也是刚学完vue2.x不久,如果有哪里写的不对,欢迎大家给我留言,我会去更改。

这篇博客也是记录一下自己写的第一个项目。

项目获取地址

项目简介

这个项目网上也有很多开源的,我也是用了他们的json文件自己做了一个,对刚学完vue2.x的人来说确实值得一练。

我的封装方法嵌套的层数会有点多,我是在某破站向coderwhy老师学习的封装方法,个人理解这种封装思路虽然层数会很多,但是结构真的很清晰,也很方便维护。

技术栈

  • vue2.x
  • vuex
  • vue-router
  • axios
  • mock
  • sass
  • better-scroll
  • moment.js

项目目录

src //项目源码
 |--assets	//资源
       |--css	//css资源
       |--fonticon	//icoMoon官网得图标字体
       |--img	//图片资源 下面的文件夹和组件名相对应
 |--common	//公共文件
 |--components	//组件
       |--common	//在其他项目中也有可能使用的组件
       |--content	//当前项目使用的组件
 |--mock	//mock.js相关文件
 |--network		//封装了网络请求的文件
 |--router		//封装路由
 |--store		//vuex
 |--views		//项目的主要界面
       |--detail	//详情界面
       |--goods		//商品界面
             |--childComps	//当前页面用到的子组件
       |--ratings	//评价界面
       |--seller	//商家界面
             |--childComps	//当前页面用到的子组件
 

项目部分截图

~~

Project setup

npm install

Compiles and hot-reloads for development

npm run serve

Compiles and minifies for production

npm run build

项目部分内容笔记

分析项目

  • 总共分为6个页面
  • 3个页面由路由控制
  • 3个页面动画进入
  • header头部是多个页面共有的(这里的头部不包括路由控制的tab栏)
  • nav-bar独立封装为一个组件
  • goods(商品) ratings(评价) seller(商家) 为路由控制界面,并放在views文件夹下
  • detail(商品详情)是动画进入页面,放在views文件夹下
  • carts也封装为一个独立的组件

设置项目别名

在项目根目录下新建vue.config.js,然后可以复制以下代码:

module.exports = {
  publicPath: './',
  configureWebpack: {
    resolve: {
      extensions: [],
      alias: {
        'assets': '@/assets',
        'common': '@/common',
        'components': '@/components',
        'network': '@/network',
      }
    }
  }
}

router封装

利用懒加载。三个路由 goods、ratings、seller,默认重定向为goods

API接口

用其他大佬开源项目中的json文件,在结合mock.js实现前后端分离。jsonmock都放在mock文件夹下,并在main.js中导入文件。

axios网络请求

这里coderwhy老师教的封装方法我感觉十分好用,这里把方法讲一下,本人表达能力不是很好,白纸黑字很难看得懂,建议结合源码阅读:

  1. network文件夹下建立request文件
  2. request文件中导出一个函数request
  3. 函数需要传入一个参数config,这个config作用后面会讲
  4. 函数内部创建axios实例instance
  5. 实例内先创建一些api共有的baseURLtimeout等属性
  6. 函数request返回值为axios实例instance的调用,并传入config,即:return instance(config)
  7. 接下来根据项目中哪些组件需要访问接口来创建文件,本项目主要为那三个路由控制的组件
  8. 根据第7条创建goods.jsratings.jsseller.js三个文件
  9. 三个文件都需要导入request.js文件中导出的request函数
  10. 这里以goods.js为例,根据goods组件的需求,导出一个函数,函数名最好取的有意义一些
  11. 函数返回值为刚刚导入的request函数的调用,并传入一个对象,对象内是goods需要访问的apiurl(注意这里的url要省略掉前面axios实例已经有的baseURL),也可以加一些其他特有的属性,也就是把这个对象作为axios实例instance调用时的参数config使用了
  12. 到这里就算封装完毕了,在goods组件中只需要导入goods.js的方法,在进行调用即可,调用后会返回一个promise,然后用thencatch进行后续的逻辑编程

好处:在这个项目中不能够完全体现出这样封装的好处,如果其他在大项目中,可以通过导出不同方法或设置不同的实例来实现对不同网络请求的统一管理,而且在组件中的代码逻辑也会变得清晰又优雅~~

这个真的很好!!!快去学!!!因为优雅永不过时~~

assets资源管理

fonticon

大家可以直接复制我的fonticon文件夹,也可以去自己习惯的网站找字体图标。

CSS

个人比较喜欢用scss,根据自己喜好来

  1. 先把reset.scss复制过来
  2. 创建base.scss,并导入reset.scss,和fonticon文件夹中的style.scss
  3. base.scss中编写一些公共样式比如font-familybox-sizing还有BFC等,根据自己的习惯来
  4. 创建mixin.scss利用sass的混合指令编写一些代码

img

这里直接复制我的就可以

vuex

主要用来管理购物车信息。

  • 商品操作

    加一减一和清空购物车的操作我这里是通过actions提交mutation实现的。

    遵循了官方文档的建议,为mutation的函数命定义了对应的常量,通过ES2015的计算属性命名功能来使用一个常量作为函数名。

  • getters

    这里根据项目要求需要获取商品数、总价和商品,这里用高阶函数,会让代码变得优雅许多。

scroll组件

该组件主要是对better-scroll又进行了一次封装,可以用在其他任何项目内,不仅限于当前项目,一些属性通过props设置。

goods的滚动事件

主要讲一下右边goodslist滚动时左边goodtab的激活选项跟着变化的两种实现方法

  1. 遍历goodlist中的每个区域,通过offsetTop属性获取到对应的值压入数组中,然后当tab发生点击的时候,根据两者关系找到数组中值,最后在调用scroll组件中的scrollTo方法,位移到对应位置即可。
  2. 利用scroll组件中的scrollToElement方法,这个方法是better-scroll自带的方法。需要传两个参数,第一个是目标元素的选择器,第二个是滚动的动画过渡时间。

localStorage

本地存储方法(这一小节的代码是参考这个博客):

  1. cookie 把信息存储到客户端的浏览器中

    document.cookie = "name=weilangpu";
    console.log(document.cookie);  //name=weilangpu
    
  2. session 把信息存储到服务器上,不是本地存储

  3. localStorage 永久存储到客户端本地

    localStorage.setItem([key],[value]) //向本地存储一条记录,存储的value是字符串格式,如果之前有key了,会覆盖掉之前存的value
    localStorage.getItem([key])  //获取之前存储的值
    localStorage. removeItem([key])  //移除key存储的值
    localStorage.clear()  //把当前源下所有存储记录都移除掉
    localStorage.length()  //获取存储的记录条数 
    localStorage.key(0)  //获取索引为0的一项的key值是什么
    
  4. sessionStorage 会话存储,会话窗口关闭信息就会消失。

    sessionStorage.setItem([key],[value]) //存储
    sessionStorage.getItem([key]) //获取:
    sessionStorage.removeItem([key]) //移除
    sessionStorage.clear() //都移除
    sessionStorage.length() //条数
    sessionStorage.key(0) //索引值
    

ES6高阶函数 map filter every some reduce

  • map:对数组每一项都运行传入的函数,返回由每次函数调用的结果构成的数组。
  • filter:对数组每一项都运行传入的函数,函数返回true的项会组成新的数组之后返回。
  • every:对数组每一项都运行传入的函数,如果对每一项函数都返回true,则这个方法返回true。
  • some:对数组每一项都运行传入的函数,如果有以想返回true则这个方法返回true。
  • forEach:对数组每一项都运行传入的函数,没有返回值。
  • reduce:这个函数接受两个参数,第一个是对每项都会运行的归并函数,第二个是可选的归并起点的初始值,归并函数接收四个参数:上一个归并值、当前项、当前项的索引和数组本身。