vue2项目积累

148 阅读9分钟

axios

axios二次封装

XMLHttpRequest、fetch、JQ、axios

要在项目文件目录下安装axios:cnpm install --save axios

为什么需要进行二次封装axios?

请求拦截器、响应拦截器:请求拦截器可以在发请求之前处理一些业务;响应拦截器当服务器数据返回以后,可以处理一些事情。

api文件夹

在src中创建api文件夹,写一些关于axios的代码。

接口中:路径都带有/api,我们就设置baseURL:'/api' {33816019-66B3-F062-3574-368F15FFC808}.jpg

接口统一管理

  • 项目很小:完全可以在组件的生命周期函数中发请求
  • 项目大:axios.get('xxx')。在api文件夹中加入一个index.js对API进行统一管理 如:三级联动 {FFCD59D2-8000-A051-08F9-E66DAF6FA3E4}.jpg {5928DF7C-C5F4-9E7A-D883-415707346606}.jpg {ECF50367-9457-3FDB-84DC-5E723E6C3956}.jpg

nprogress进度条的使用

安装:cnpm install -save nprogress 在request.js中引入进度条及其样式,并在请求和响应拦截器中设置开始和结束 {E3FA79BF-1DE5-C4B2-1218-E5D8B125D386}.jpg {4D6246B1-7A1D-9D0D-4221-293C0EDFB4DB}.jpg

vuex状态管理库

vuex是官方提供一个插件,状态管理库,集中式管理项目中组件共用的数据。切记,并不是全部的项目都需要vuex,项目很大,组件很多,数据很多,数据维护很费劲用vuex。

安装vuex

安装vuex @指定一下版本 只能安装3.xxx

stroe文件夹

1.在src中引入store文件配置vuex,创建index.js。 {07656EDA-0655-BDD2-3994-47EC2DFF16C5}.jpg 2.模块式开发写法:在store中创建各个模块的文件夹,里面创建index.js {B3E6E7F2-073B-03D3-1501-8790A8DC7A2E}.jpg {A85486B0-A6E7-DC9D-608D-ECD699AF07AD}.jpg

三级联动模块

{5C7F685A-0840-66CE-D053-45E3ECCDA066}.jpg {42523AD4-65CC-2F52-C595-664C8582F4D1}.jpg {ACE21E09-0A74-CCEB-2725-FEAA8509A51B}.jpg {B4A5C0C7-5CE0-5DAB-DB49-3E6D558FD271}.jpg

用JS完成hover效果

{C6ED4551-EBB2-D228-B6C8-CBF5CF5BD12A}.jpg {A4EFF363-2721-31E0-7EC1-9CAE26283329}.jpg

防抖方法下一章节

路由跳转

声明式导航router-link可以实现路由跳转与传参,但可能会出现卡顿现象。router-link可能循环出很多组件【创建组件实例】。解决方法:自定义属性+编程式导航。 {1FE19978-FF95-E327-F4E6-C4B6DEDE7645}.jpg {E97E3727-0199-34A1-F0C5-50EA22FC029E}.jpg 遇到的问题:跳转页面后,URL丢失search。解决方法:在配置路由文件中占位后面添加一个? {BA9FDB79-A435-074D-CAD8-589579D033B6}.jpg

鼠标移入和移开针对search和home页面的设计

{58A69703-4156-2316-DAFD-48A1F5694B47}.jpg {EFCA9E17-D15E-2112-02B4-D99A9295AB8D}.jpg 过渡动画(前提:组件、元素务必要有v-if/v-show指令才可以进行过渡动画) 先用transition包裹 {1024423F-62FF-41C6-2F07-7375A9950A49}.jpg CSS {C236CDF6-892C-2E3D-BCC5-872D712AA440}.jpg 优化:因为主页和搜索页都有三级联动模块,都要向服务器发送请求,浪费资源,所以在App.vue中派发action {4A70B80E-AE37-ED5B-D159-3C6752EE1E9B}.jpg 解决路由跳转之后参数不全的情况。在typeNav和header组件分别更改为 {1DCAD381-356A-408A-0E23-DBD5472F16AC}.jpg {7C5BC012-3747-C55E-947D-B7889A7FDAFF}.jpg

函数的防抖和节流

  • 防抖:前面所有的触发都被取消,最后一次执行在规定的时间之后才会触发,也就是说如果连续快速的触发,只会执行一次。
  • lodash插件:里面封装函数的防抖与节流业务(闭包+延迟器)。lodash函数库对外暴露_函数 {79F7B8BF-B48B-BAFA-D1F6-875B6C9EB325}.jpg
  • 节流:在规定的间隔时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调。把频繁触发变为少量触发。(闭包+延时器)。不要用箭头函数。 {FBFE8BF3-CC68-E287-FA3B-B8E029C08F9F}.jpg {45C850CC-9D05-0E49-45C5-0D5954826618}.jpg

mock数据(模拟)

开发Home首页当中的ListContainer组件与Floor组件:服务器返回的数据(接口)只有商品分类菜单分类数据,对于ListContainer组件与Floor组件数据服务器没有特供,需要mock.js插件:生成随机数据,拦截Ajax请求。

  • 安装:cnpm install mockjs(注意不加.)
  • 使用步骤:
    • 在项目中的src文件夹中创建mock文件夹
    • 准备JSON数据,创建banner.json文件,floor.json文件
    • 把mock数据需要的图片放置到public文件夹中(public文件夹在打包的时候,会把相应的资源原封不动打包到dist文件夹中)
    • 开始mock虚拟数据,通过mockServe.js文件模块实现(webpack默认对外暴露,图片/JSON数据格式默认暴露)
    • mockServe.js文件在入口文件中引入(至少需要执行一次,才能模拟数据) {742551E9-8DC6-873A-AA16-899C29C97605}.jpg 其余都跟request.js一样,修改baseURL {E6D22F99-77EC-8F1B-F546-5BB6DB5842E2}.jpg index.js引入 {02445358-57AF-C6C3-1DC4-450E2C7280E6}.jpg 其他vuex的操作与之前的相同(写API,再写store三连环)

APP.vue {AA5DF656-DD0D-EC9A-B292-163293F868B9}.jpg 配置状态 {03983A28-F693-DBB0-2DC7-372978F69315}.jpg 组件获取数据 {E46CB109-1E4E-63E4-903F-5A8B706C681D}.jpg

swiper

版本太高可能有问题,安装5版本:cnpm install swiper@5.因为很多模块都用swiper,所以直接在入口文件main.js中引入 {261122BC-DBD8-82D7-9ACC-46FCA4C7C10C}.jpg swiper使用时必须结构完整。因为dispatch当中涉及到异步语句,导致v-for遍历的时候结构还没有完全,所以不能写到ListContainer中的index.vue的mounted中。v-for动态构建结构,数据来源于服务器,在mounted生命周期钩子之后。

解决方法:watch:监听已有数据的变化。+nextTick:在下次DOM更新 循环结束 之后,执行延迟回调。在修改数据之后 立即使用这个方法,获取更新后的DOM.错误方法: {16F6D0E1-B29F-5B9B-9231-77BCB98ECDE2}.jpg 正确方法: {2E60696B-ABC6-F929-5647-F94F1F78D189}.jpg

floor组件

需要两个floor模块遍历数据。getFloorList这个action需要在Home路由组件中发,不能在floor组件内部发,因为我们需要v-for遍历floor组件。 src-pages-home-index.vue {18109E4A-7D4A-9BBC-40C7-F1FAF7B9751C}.jpg 信息都在home身上,需要向子组件floor进行通信 {074380CC-B162-D88C-725F-B4A6B54F0D30}.jpg {5D5AE159-D942-CBE3-DD28-D81C73ACB473}.jpg

组件通信方式

  • props:用于父子组件通信。
  • 自定义事件:@on @emit可以实现子给父通信
  • 全局事件总线:$bus 全能
  • pubsub-js:vue中几乎不用,react中使用。全能
  • 插槽:具名插槽、默认插槽、作用域插槽。父组件给子组件提供结构,子组件给父组件提供结构使用的数据
  • vuex 轮播图可直接写到mounted里。因为第一次写轮播图的时候是在当前组件内部发请求,动态渲染结构。这次是在home父组件通过props传递过来的,而且结构都已经有了情况下执行mounted {D2825868-BDC2-DACF-496E-DCF52368F36F}.jpg

把首页的轮播图拆分成一个公用组件

把floor的轮播图写成和第一次写的轮播图大概一个格式 {76972B9F-8725-3979-83AA-9E95D31D857B}.jpg src-components-Carousel-index.vue {75D606F8-85C9-E822-D672-C9B187AECDB5}.jpg 在main.js注册引入全局组件 {F0E68B98-D6B6-7F11-E9EB-8364AE14A525}.jpg 使用自定义全局组件 {760BA0BE-1CB2-51C6-B30F-5E068E6AA547}.jpg

search模块开发

  • 1.静态页面+静态组件拆分出来
  • 2.发送请求(API)
  • 3.vuex三连环
  • 4.组件获取仓库数据,显示动态数据 {E04D46C1-1773-8C8C-71E5-0F2DF48218BC}.jpg {3B6049C7-0B52-B250-3DD4-3D1E92FBA22C}.jpg

getters

项目中的getters主要作用是:简化仓库中的数据(简化数据而生)=》可以把我们将来在组件中需要用的数据简化,获取数据更加方便 {F7F1FBD1-7C76-9481-804F-DB1B24E81040}.jpg 如果没有网,没法请求,state.serchList是空对象,取不到goodsList {9CB4C70F-C697-8B2A-C2F9-CD8F56B35B40}.jpg 正确: {136D5ED7-9DA5-FE01-C6C7-0D0E733BDF6F}.jpg 发送action不能写在mounted中,因为只会加载一次 {7FB7A18D-85AD-BCDC-E184-4E36A06B67B7}.jpg es6:Object.assign(目标对象,被拷贝的对象,被拷贝的对象),浅拷贝。但是只能发一次请求。 {91CB0F47-3846-2757-6A7E-D7B4AB1AEF9E}.jpg 在search的子组件配置动态获取参数 {E50C03C3-2EC4-3737-7E44-4FF1BC46056C}.jpg 应该这么写 {83E051D0-2DAE-DC2C-4AE9-38907B39254B}.jpg 但是remove功能没法实现地址栏的改变,所以需要进行路由跳转(search跳search) {6878B457-B209-A2E9-4742-6A8DC6206987}.jpg

兄弟组件通信——$bus

当面包屑中的关键字被x掉后(search),需要让兄弟组件Header组件中的关键字清除 在main.js中注册全局事件总线 {EBDEA467-C151-D1A1-6F1F-C45B3D5320F0}.jpg {045A29FC-7F70-3075-F0EF-7FFAA4052454}.jpg Header.vue中 {790AB3DD-B5B8-0586-ECE3-1D606574BE06}.jpg

子父通信——自定义事件

点击了品牌后,整理参数,向服务器发送请求获取相应的数据进行展示。要在父组件发送请求,因为searchParams参数在父组件(search)身上,子组件只需要把点击的品牌信息传给父组件即可。

触发和传参写在子组件身上 {3CE8F947-3620-20A9-8869-03725D31CC1B}.jpg {9DFF2748-780D-F386-0648-E3E6F83157F3}.jpg 父组件身上绑定回调函数 {3CE8F947-3620-20A9-8869-03725D31CC1B}.jpg {DBA6F5F0-0344-1005-A72E-A3609B098DD5}.jpg 关于商品属性的设计也是类似的。父组件: {6283CF32-7BB0-1FA8-1573-554785D7CC42}.jpg {0D50D967-56BA-649E-BACC-2A5D5753962E}.jpg {DBA6F5F0-0344-1005-A72E-A3609B098DD5}.jpg 子组件 {BC21AE64-ED27-4F0D-568D-0B3D964B0EBC}.jpg

难点:排序操作

1:综合 2:价格 asc:升序 desc:降序,故有四种排列方式。初始状态是综合降序order:'1:desc' {A6B363D4-0E3E-9A57-F15C-07E43D0E8451}.jpg {44B5D446-A0AE-19B6-5704-9D7C98EC1E36}.jpg {F548908D-950E-4D3E-E2E2-CD88C355EDB9}.jpg

分页器

v-for是可以遍历:Array/Object/number/sting/Iterable的。在search组件上安装分页器,但是鼠标点击的页数事件在子组件身上。需要自定义事件传参。先设虚拟数据调试成功后再用服务器数据 {408F7DEA-CA57-B248-2162-4D16D9E8DB78}.jpg {15374AE0-A358-6788-D784-C6B9A553DA78}.jpg 数据总数在search的state中 {9FB5E888-F035-6C7C-E925-0B43521C8B5E}.jpg {31485E9F-2606-8BAF-63F2-1999E370DEAD}.jpg 子组件绑定事件 {3704848D-EA1C-23C3-7419-4E8A9F624F30}.jpg

购物车模块

详情页和购物车模块

特殊的一点是,在详情页中点击加入购物车,需要将参数带给服务器(发请求),但是服务器发回来的数据只是成功或者失败,所以不需要使用三连环进行储存。 {3F484662-21A6-EF34-D6C8-A54431512C74}.jpg {B4F1642F-D684-8B84-C076-BF2BF63C678A}.jpg 还要进行路由跳转。在路由跳转的时候,还需要将产品信息(skuInfo)和产品加购的数量(skuNum)带给下一级路由组件。一些简单的数据(skuNum)通过query形式给路由组件传递。但是一些复杂的数据(skuInfo是个对象),如果使用query传输,地址栏会自动转换成一串字符串(乱码)不美观。所以选择通过会话存储(不持久化,会话结束数据消失)。且本地存储、会话存储都不能存储对象,一般存储的是字符串。 {299B3C24-686D-1EAC-2757-3A8D4C399B35}.jpg {E334099D-A7FD-4474-FD1E-E46A25D89D6B}.jpg 购物车中的加减和输入个数 {F4C43528-F503-2FDE-9F34-88E6467A8A5C}.jpg 要求传递差值 {C92240DC-4AED-E3D7-4631-F815837865BD}.jpg

Promise.all

删除所有购物车中的数据。这个没有配置接口,需要通过调用删除一个产品的函数循环调用达到目标。 {6CE17342-E53A-A281-F7CF-241B15E38A24}.jpg 使用Promise.all。 {02DB8505-2916-4D54-2EA7-2A814EA7F869}.jpg 全选框和上面的勾选框联动。判断全选框的isChecked状态,把它的值赋值给其他勾选框的isChecked {49513C2A-9FDE-E6ED-B487-D945FC97D4AE}.jpg 还是使用Promise.all,使用forEach遍历item,打印出来state判断路径哦。 {C5CFA997-A74B-219A-E150-CBFE20F078FE}.jpg

assets文件夹

防止全部组件共用的静态资源

@

在样式中也可以使用@符号(src别名),但是要加波浪号 {DA0A3493-EB2A-ECB7-D96E-E9C0C2FD4743}.jpg

注册的业务

通过数据库存储用户信息(名字、密码)。 解构赋值真的方便。 {62B5A9C1-560C-55F1-D2CE-5FB90364E648}.jpg 要传递一个对象data,KV一致。 {AAE2CFA5-0EF9-D687-8C75-D1C45D49D252}.jpg

登录

登陆成功时,后台为了区分用户,服务器下发token(令牌:唯一标识符)。登录接口:做的不完美,一般登录成功服务器会下发token,前台持久化存储token,(带着token找服务器要用户信息进行展示) {803716EF-573C-64C1-7808-AC650C5757FE}.jpg 在api文件夹下的request.js中的请求拦截器中,请求拦截器写一个判断,如果有token则带给服务器 {4E4D23C7-7541-C850-7BD1-FFD5A45DAF94}.jpg vuex仓库储存数据不是持久化,所以要通过localStorage存储token(本身就是字符串,localStorage也是存储字符串的所以不用转换),在utils中设置一个新的js {0A27F54A-4CC1-A132-3FDD-78C5463241F0}.jpg 在store组件中引入我们定义的三个方法。初始化state直接获取localStorage中的token。存在问题:除了home派发dispatch获取信息之外,其他页面一刷新就会丢失token。 {C4CB9E56-801D-53F7-B577-3AB0E067155A}.jpg {E06F7FD7-DEF4-0097-ACF3-0C47AC0F4D70}.jpg

路由守卫

to是要跳转的路由信息,from是从哪个路由信息来的,next()放行,next(path)放行到指定路由

引入仓库 {6D5EF1D9-7327-C8BE-5E63-DEEB90083413}.jpg 设置前值守卫(之所以获取name而不是userInfo是因为如果是个空对象的话,判断布尔值也是true) {9BF75434-D0EC-45E6-18BB-1D6F068C65D3}.jpg 解决了其他页面一刷新丢失token的问题。重新派发action,获取信息。 {E54F3AB8-D765-2EBE-B911-C7BC1726936A}.jpg

结算

  • html结构的a标签的target属性:
    • target="_self" 内容在当前页面显示。
    • target="_blank" 内容在新页面显示。
    • target=“three” 内容在对应窗口显示
    • target="_top" 在当前窗体打开链接,并替换当前的整个窗体(框架页),清除所有包含的框架
    • target="_parent" 在父窗体中打开链接,在窗口与顶级框架中,等同于_self

find的使用

find()用于找出第一个符合条件的数组成员,没有找到则返回undefined {79A7E34D-F569-6980-3090-7AAAEE1674E6}.jpg

pay

开始练习不用vuex。1.在main.js中引入API就不用在每个组件中单独引用 {BBBCD485-80B9-4575-4514-BFB130701652}.jpg 2.设置点击事件,获取需要传递的data和query参数 {B9D9E149-01C6-0C27-91C1-1DE508A1013A}.jpg 3.使用$API,并在data中初始化orderId,把query参数传递,也可以写成字符串形式 {1A4F3F04-8373-350C-1291-76B340685FFE}.jpg

生命周期函尽量不要添加async

可以和methods连用 {6CF23BCA-BD4D-5253-E3C0-5DDA4269BF9A}.jpg

组件库

React(Vue):antd[PC] antd-mobile(移动端) Vue:ElementUI[PC] vant[移动端]

配置完毕需要重启项目 element-ui版本下载2.15.5,15不行!!!改了好久。

两种写法

{669F4419-0FA0-7EF6-A9C9-364784C1F613}.jpg 样式没有引入的话,在main文件中import 'element-ui/lib/theme-chalk/index.css'

生成二维码QRcode

npm i qrcode 在组件中import QRCode from 'qrcode',返回一个promise,可以把二维码地址字符串转换成二维码。

二级路由

{5D7305E8-CAB0-78B6-7111-E31073046A5C}.jpg {4C5DFA79-7F9F-7048-510E-3D75CDAED3ED}.jpg {D17E036C-AD71-E26D-EF3A-FDA9AAB0F572}.jpg

全局守卫补充

{8A8DB3B5-B9FD-564A-8153-523552476DAB}.jpg 在login.vue中 {CF92C637-A9ED-311C-3089-A681EDA4ED67}.jpg

路由独享守卫

{243DB384-1A7F-830F-E9EF-CD7DB8951F74}.jpg {8091FE4E-022C-B7F0-FDCF-5C52F5B6DBA3}.jpg

组件内守卫

{5C6432C2-5EAB-D958-7A0C-1F8B5C0E9527}.jpg

补充

图片懒加载

{8C654B29-B964-296D-9BFA-9533477A474F}.jpg {D97DCDE1-0306-1A02-5577-9F0F4ADF325B}.jpg {B59208D3-5654-A18A-CF57-4B6C26D4E3BA}.jpg

表单验证

vee-validate{B917757B-7C82-BE5A-E195-71C1E4C46E14}.jpg {731DBA15-E1C1-930A-007C-90B5A78D81FA}.jpg 在main.js中{827B096F-09A4-96A4-F030-15CCE0F6087D}.jpg 在注册组件中 {2BCBE049-1916-F02C-FAB0-D87ADBA87EA4}.jpg 全都符合标准再发请求 {96426508-3531-4E8C-F0AF-FF485FD4221C}.jpg

路由懒加载

把不同路由对应的组件分割成不同的代码块,然后当路由被访问时才加载对应组件,更高效。 {26B76BF9-AF75-8E0C-C9CB-656ABAF4D77E}.jpg