vue项目经验

本文记录了一个Vue商城项目的实践经验,包括标题与内容的联动效果、封装插件的步骤,以及解决滚动条插件better-scroll相关问题。文章详细讲解了如何监听滚动位置、实现上拉加载更多,以及处理滚动条的常见bug。此外,还探讨了轮播图插件swiper的使用,组件通信,以及Vue组件生命周期的理解。同时分享了图片懒加载、Vuex的使用和面试题,最后以一个toast组件的封装为例,展示了如何创建和使用自定义Vue插件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

vue商城项目记录

  • github上有个常用的css初始化样式,可以用npm命令安装npm install --save normalize.css,也可以直接在src/css下新建一个css文件,将normalize的代码复制进去
  • 用脚手架3搭建的项目里,如果要配置路径别名需要自己新建一个vue.config.js文件,放在项目的根目录下
  • 如果只是文字不一样的时候,就没有必要用插槽
  • 为了方便以后管理,导入组件时,尽量分类存放组件,比如公共组件放一块,子组件放一块,方法或额外的数据放一块
  • 在特殊一点的函数里只写关键的代码,例如钩子函数 created 内只需要调用方法,而方法的内部具体实现可以写在 methods 里
created() {
      // 1.请求轮播等数据
      this._getMultiData()
},
methods: {
   _getMultiData() {
        getMultiData().then(res => {
          this.banners = res.data.banner.list
          this.recommends = res.data.recommend.list
        })
      },
}

  • 滚动条插件:better-scroll

    • 监听滚动的位置要用 scroll 事件,需要默认情况下 BScroll 是不可以实时监听滚动位置,但是可以在 new 实例的时候传入第二参数为对象,对象中可以添加 probeType 属性,该属性默认值为 0,当这个属性的值为 0 或 1 时,不侦测实时的位置,当属性值为 2 时,在手指滚动的过程中侦测,手指离开后的惯性滚动过程中不侦测,属性值为 3 时,只要是滚动都侦测
    • 要实现上拉加载更多的效果,先在实例化时添加 pullUpLoad 属性值为 true,需要监听 pullingUp 事件,但默认只触发一次,如果想要触发多次,pullingUp 的回调函数中必须调用 finishPullUp 函数
    • 在 vue 中,实例化 better-scroll 的时候传入的第一个参数也就是元素,最好用 ref 的方式去取,这样可以保证唯一
    • scrollTo(x,y,ms)通过 ms 毫秒滚动到 x,y 坐标的位置
    • 对于 button,无论是否设置 click:true,button 都可以点击,但是对于其他元素如 div,必须设置 click:true 才能监听点击
    • scroll的bug1:可滚动区域的高度一开始就计算好,默认只计算一次,但是如果滚动区域内有大量图片,可能图片尚未加载完成,而图片的高度没被计算进去,等到图片加载完成的时候,滚动区域的高度就相对较小,无法放入所有图片。解决方法,监听每张图片是否加载完成,只要有一张图片加载完成就调用一次scroll的refresh方法,监听图片加载完成在js中用图片元素.οnlοad=fn,在vue中用@load=“fn”
    • scroll的bug2: 无法响应鼠标滚轮滚动,解决方法:创建实例的时候配置一个mouseWheel为true
    • scroll的bug3:手机浏览器下better-scroll中click事件,链接无效的问题,解决方法:创建实例的时候配置click为true,tap为true
  • 轮播图插件 swiper

  • 在组件中,钩子函数 created 里拿不到 HTML 元素,因为还没有挂载

  • 用插件的时候最好自己在封装一层,避免项目跟插件的耦合度太高

  • ref 如果是绑定在组件中的,那么通过this.$refs.name获取到的是一个组件对象

  • ref 如果是绑定在元素中的,那么通过this.$refs.name获取到的是一个元素对象

  • 组件中的 style 标签内的 scope 属性,表示标签内的样式都只对该组件有效

  • 如果页面中分为三块,上和下的高度固定,想要中间自适应有两种方法:第一种是用计算属性 calc(100%-上的高度-下的高度),第二种是用绝对定位,top 设置为上的高度,bottom 设置为下的高度,left:0,right:0

  • 如果需要监听一个组件的原生事件例如点击事件,必须给对应的事件加上.native 修饰符才能监听,如@click.native=“fn”

  • 在标签内写属性名时,不用驼峰式,改为-连接,例如probeType在标签里面写成probe-type

  • 事件总线$bus:

    • 在main.js中给$bus加prototype为vue实例
    • 在需要发送事件的组件内$emit
    • 在需要接收事件的组件内$on
  • 对refresh非常频繁的问题,进行防抖操作,目的就是对于那些很频繁的操作,可以让这些操作等一会,等到一会后看一下还有没有要执行的操作,如果有就合并到一起执行。这种问题还出现在例如要监听输入框中输入的内容,例如当输入a时,就去服务器请求与a相关的数据并显示出来,但是如果对每个字母都去请求一次的话,性能很低,解决的思想是间隔一定时间去获取输入框中的内容,以最后一次修改后的内容去请求数据

    • 防抖debounce/节流throttle
  • setTimeout即使没有延迟时间,也会被放到事件循环的最后才执行

  • 所有组件都有一个属性$el,用于获取组件中的元素

  • bug记录:在谷歌上用移动端查看的时候,点击tabcontrol点不了,但是如果不用移动端查看就可以

  • 在使用浏览器原生的滚动时,为了让导航不跟随一起滚动可以使用position:fixed的方法,但是如果用了其他插件,例如betterscroll,并且给设置滚动区域,那就不需要用fixed了,具体可参照home中的导航

  • 如果在某个组件中需要用到从服务器多个位置返回的数据,要先将数据进行整合,整合到一个对象中,用es6的语法就是封装到一个类中,将多个数据源作为构造函数的参数传入,再在构造函数内获取对应的每个数据,再在组件创建类对应的实例对象,获取数据,让组件对数据进行展示,具体可查看本次案例中detail,

  • 判断空对象:Object.key(obj).length === 0

  • 导入同级文件的时候注意路径是“./文件名”

  • 将时间戳转成时间格式化字符串

    • 传统做法
      • 将时间戳转为date对象
      • 将date进行格式化,转成对应的字符串
    • 但是这种操作很常见,所以要进行封装
  • 两个不同的组件中出现相同的代码,可以考虑使用混入mixin进行封装,具体可查vue文档

  • 如果是两个类中有相同的代码,考虑继承,es6中有extends关键字

  • 在组件中的HTML代码里,如果动态绑定属性要把驼峰式改为-连接,因为HTML不区分大小写,而动态绑定的事件可以用驼峰式

  • this.$nextTick

  • 一般offsettop拿到的值不对,都是因为图片的加载问题

  • 纯数字字符转为number,n*1

  • vuex中的mutation唯一的目的是修改state中的状态

  • mutations中的方法尽可能完成的事件功能单一

  • 修改任何vuex的数据都不要直接修改,而是通过mutation

  • 解决移动端点击延迟300毫秒的问题可以用fastClick插件,先安装再在main.js里导入,在使用fastClick的attach方法

    • npm install fastclick
    • import FastClick from “fastclick”
    • FastClick.attach(document.body)
  • 图片的懒加载可以去GitHub上搜vue-lazyload

    • 什么是图片的懒加载:图片需要显示时才加载
    • 使用:安装-导入-Vue.use-修改img:src->v-lazy
  • px2vw插件使用,将px单位转为vw,方便适配

    • 安装插件,注意是–save-dev
    • 在postcss.config.js中配置相应的设置
  • 服务器nginx

  • 反向代理

  • 面试题

    • 如何理解vue的生命周期
      • Vue的生命周期,首先需要创建一个实例,即在new Vue()的过程中,首先执行了init(默认执行)初始化事件和生命周期,而在init的过程中会先调用beforeCreate函数,然后在初始化注入injections和初始化反应reactivity,再然后调用create函数、
      • 当create完成后,它会去判断创建的vue实例中有没有el选项,如果没有则使用vm.$mount(el)去挂载模板,如果有则执行下一步
      • 判断是否含有template选项,如果有就把template解析成一个render function,其实这里就是一个编译模板的过程,把data对象里的数据和vue语法声明的模板编译成浏览器可读的HTML,这个过程中的关键在于render函数
      • render函数中参数通常写成h,实际含义是…
      • 将编译完成的HTML挂载到对应虚拟dom时会触发beforemount,注意在此时页面中并没有内容,而编译好的HTML将逐步替换掉el属性指向的dom,挂载完成后触发mounted函数,一般在mounted中会做一些ajax请求获取数据进行数据初始化
      • 上面的过程是一个vue实例创建的过程,而后续钩子函数执行则需要外部的触发
      • vue会实时监控数据变化,并随之更新dom,更新前调用beforeUpdate,再经过虚拟dom更新,更新完后触发updated函数
      • 当实例被销毁时,销毁前调用beforeDestroy函数,然后拆除数据监听、子组件和事件监听,销毁完成执行destroyed函数
    • 如何进行组件通信
      • 父传子props
      • 子传父$emit
      • 非父子:事件总线$bus

标题与内容的联动效果

点击标题,滚动到对应的主题

  • 在detail中监听标题的点击,获取index
  • 滚动到对应主题
    • 获取所有主题的offsetTop
    • 问题?在哪里获取正确的offsetTop
      • 在created肯定不行,不能获取到元素
      • 在mounted也不行,图片数据可能还没获取到
      • 在获取到数据的回调函数中也不行,DOM还没有渲染完
      • $nextTick也不行,因为图片的高度没有被计算在内
      • 在图片加载完成后,获取的高度才是正确的高度

内容滚动显示正确的标题

  • 普通做法
(this.currentIndex !== i) && (i < length - 1 && positionY >= this.themeTopYs[i] && positionY < this.themeTopYs[i + 1]) || (i === length-1 && positionY >= this.themeTopYs[i])
  • 条件成立:this.currentIndex !== i
  • 条件一:防止赋值的过程过于频繁
  • 条件二: (i < length - 1 && positionY >= this.themeTopYs[i] && positionY < this.themeTopYs[i + 1]) || (i === length-1 && positionY >= this.themeTopYs[i])
    • 条件二.1 : (i < length - 1 && positionY >= this.themeTopYs[i] && positionY < this.themeTopYs[i + 1])
      • 判断区间,在0和length-1之间
    • 条件二.2 :(i === length-1 && positionY >= this.themeTopYs[i])
      • 判断区间:i === length-1
  • hack做法,给数组增加最后一项为js最大值Number.MAX_VALUE,这样就不用判断区间了
this.currentIndex !== i &&(positionY >= this.themeTopYs[i] && positionY < this.themeTopYs[i + 1])

如何封装一个插件

步骤,以toast组件为例

  • 先封装好一个组件,toast文件夹下的Toast.vue
  • 在toast文件夹下新建index.js文件
  • 在index.js中导入Toast.vue组件,并创建一个新对象obj,导出该对象
  • 在main.js中安装这个插件
    • 导入index.js
    • 用Vue.use(Toast)安装
  • 运行该插件时,会自动找到插件内的install函数,所以插件中需要一个install函数,obj.install= function(Vue){}, 注意该函数默认会传进来一个Vue作为参数
    • 在install函数内,先创建组件构造器,
    • 通过new的方式根据组件构造器可以创建出来一个组件对象
    • 将组件对象手动挂载到一个元素上
    • toast.$el对应的就是div
    • 在Vue的原型上加上$toast,并让它等于刚刚new出来的组件对象
  • Toast.vue组件中可以添加方法,当需要使用这个插件的方法时,可以通过this.$toast.show()直接调用该方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值