1.项目地址
https://gitee.com/x-nn-c/travel_vue.git
2.项目介绍
https://blog.csdn.net/weixin_43681801/article/details/129779241
3.部分功能实现细节(推荐结合源码看)
3.1 city-alphabet–城市选择页字母表部分
3.1.1 实现点击字母跳转到相应列表(兄弟组件传值)
- 点击之后可以跳转到对应首字母开头的列表(兄弟组件间的传值)alphabet(兄)传给city(父)再转发给list(兄)
3.1.2 实现滑动列表可以对应显示相应字母
- item中list绑定touchstart、touchmove、touchend事件,对应事件methods中写对应方法实现动作
- touchmove中(实现鼠标拖动时的动作):
- 先算A字母距离顶部的值,使用ref获取标签中的值,通过offsetTop属性获取高度
- 再算拖动时手指所处位置,减去A的高度就是字母所在位置
- 计算每个字母的真正位置,减去A的高度后需要除以字母本身的高度20
- touchmove中(实现鼠标拖动时的动作):
3.1.3 可以优化的点
- startY写在方法里,每次调用都会计算一次,可以单独提出声明
- 添加节流限制函数(定时器,每次执行延迟16毫秒执行,如果16毫秒期间有新的执行则清空当前的执行下一个。)执行频率,手指滑动的时候每一次都会执行函数,执行频率过高。
3.2 city-search----城市搜索功能
3.2.1 搜索功能实现
获取输入到输入框的内容(keyword),其中有两个字段spell和name,用indexof判断value中是否含有keyword,有则返回结果到result数组中,最后赋值给list。
之后在html标签中用v-for循环显示结果就行
3.2.2 可优化的地方
- 当搜索结果过多时,列表无法向下滚动查看更多,可以使用better-scroll解决
- 搜索结果为空的时候,可以添加友好提示
添加一个li专用来显示提示信息,添加显示条件v-show来控制显示,标签中不提倡写逻辑,所以将逻辑移到computed属性中写
当list为空的时候即为查找输入框中匹配内容为空,则显示提示页。
但是因为输入框默认为空,所以需要在外围再加一个显示条件,这里加了之后只有当搜索框中有内容时才会判断显示搜索内容的结果。
3.3 city-vuex----首页和城市选择页共享数据
- 建立city和home之间的连接组件(可以用bus但比较麻烦,vue官方提供了vuex更方便),实现城市选择页选择城市后,首页的城市也变为选择的城市,跳转回首页。
- 建立src/store文件夹用来专门编写vuex逻辑,一般需要配备三个单独文件
- state—用来存放所有数据
- actions----用来调用commit激活mutations并接收组件传来的数据传递给mutations
- mutations----可以写方法来改变state数据,数据来自actions中调用commit的方法
- 如果没有异步或批量操作,可以在组件中直接调用commit,省去actions
- 在main.js中调用store并在实例中挂载即可在全局用$store调用store中的数据
- 选择城市之后跳转回首页可以用编程式导航(router除了可以使用标签跳转,还可以调用push(’路径‘)方法进行跳转)
3.3.2 可以优化的点
- 选择城市切换成功后,实际上没有进行切换,再次刷新页面会重新显示切换前的城市。因为sessionStrorage在浏览器关闭后数据就会消失,可以改使用localStorage(建议套try-catch)
- 首页的城市显示处的样式width不能写死,否则两字以上城市显示会有问题。可以通过设置最小宽度来进行调整
- 可能在vue文件中template直接调用store中的数据代码比较长,vuex提供了新的API–mapState,使得可以将vuex中的数据映射到computed计算属性中,可以在vue文件中直接this.调用。
- 参数可以是数组也可以是对象
- 参数可以是数组也可以是对象
- vuex同样提供了一个API–mapMutation–来将mutation直接映射到组件中,仅限commit方法,dispatch不行
3.4 city-keepAlive----组件加载优化
-
每次进入首页和城市选择都会重新加载一次json文件。在app.vue中的router-view外加一层keep-alive标签,即开启缓存加载模式
-
需注意开缓存加载之后,第二次加载相同页面会加载缓存,而如果上次在城市选择页面更改了城市,由于缓存并不会修改,故刷新后首页依旧显示的是最后缓存的城市。
- 可以用activted钩子+一个辅助变量记录最后缓存城市
- 可以用activted钩子+一个辅助变量记录最后缓存城市
3.5 Detail-banner ----景点详情的头部信息显示
3.5.1 整体布局
- 标题部分用flex布局,关于让右边图片提示数量信息的位置与左侧标题同高,涉及外部大盒子的line-height、title的padding、font-size和number部分的margin
- 底部是渐变色,加background写从上到下线性渐变
3.5.2 点击图片之后的图片查看效果
- 在banner中添加组件gallary,画廊的滚动效果用swiper插件实现
- 默认不显示,添加v-show属性控制显隐,当点击banner中图片的时候显示画廊(加@click)
- 点击图片之后关闭画廊,gallary中添加close事件emit传递给父组件banner,banner进行显隐控制
3.5.3 可以优化的点
- 可能添加显隐控制之后可能会因为宽度计算问题swiper无法正常滚动的问题
- 法1:swiperOptions中添加observeParents:true属性和observer:true,以此来监听自身和父元素的变化,变化时会自动刷新。(可能不好使)
- 法2:v-show换成v-if
4. 可能出现的问题
4.1 移动端1像素边框问题
- 有些屏幕分辨率较高可能是1倍屏2倍屏,那设置border为1px的时候在2倍屏上就会变成实际的2px,因为设置的1px是css的像素。
- 解决方案: border.css文件(利用css的scale进行不同屏幕放大缩小的适配)
4.2 移动端300毫秒点击延迟
- 有些机型上click事件点击后会延迟300毫秒才执行。
- 解决方法:引入fastClick库
4.3 图片加载抖动
- 图片没加载完成之前是默认无高度的,加载完成后才会有设置的高度,图片加载慢,后边的元素因为高度变化会在图片加载到完成的阶段有一个突然被挤下来的抖动感。
- 解决方法:最外边加一层div class="wrapper"设置css,padding-bottom根据图片宽度设置,390对应39%
4.4 img中src输入本地路径不显示图片
- 在用v-for进行循环数据读取结合显示各种东西时
- 如果有图片,则需要在src前加冒号:,进行动态绑定,之后直接引用变量
- 如果路径为本地路径,则需要加require,require中的路径需要写全,便捷访问无效
- 如果有图片,则需要在src前加冒号:,进行动态绑定,之后直接引用变量
4.5 标题字数过多显示不开
- 可以使用css设置多余的显示成“…”
- overflow: hidden
white-space: nowrap
text-overflow: ellipsis
- overflow: hidden
4.6 swiper轮播图从最后一张开始放
- 因为设置的通过ajax获取数据,设置的获取列表swiperList的默认值为空数组,开始的时候就是没数据的状态。
- 解决方法:在渲染之前加一个判断,等到有数据才开始渲染。判断可以以数组长度为依据。可以v-if中直接写list.length但是不推荐在标签中写逻辑,故添加computed属性来进行逻辑编写,标签中直接调用
4.7 this.$refs获取不到数据,undefined
- 如果是非循环中,那么refs可能 点击查看详情
- 如果在循环中,那么ref循环返回的是一个数组,需要指定下标进行获取
- 如果接值子组件写的都没问题,可以看一下传值子组件传递的值是否有问题
4.8 css画三角,画出来总体变成长方形
- 可以更改display为block或inline-block,或者加position,原理不详
4.9 router-link标签vue默认将其变为a标签,样式也跟随a标签
-
法1:可以将需要添加路由的标签直接写成router-link标签,然后添加tag属性指定router变化的方向。
-
法2:可以直接修改a的样式为指定样式
4.10 页面拖动的距离会作用于全局
拖动一个页面,点击进入另一个页面同样会显示上一页离开时的位置
- v-router官网中提供了解决方法:
scrollBehavior (to, from, savedPosition) {
return { x: 0, y: 0 }
}
将上述代码添加到路由文件的Router实例中,表示每次路由进入新页面会从头显示页面