vue2.0仿去哪儿网移动端Webapp遇到的问题
github地址:https://github.com/tedqin/Travel
demo:https://tedqin.github.io/Travel/
使用vue2.0对去哪儿网的移动端web页面的复现,做个总结。
为什么使用单页面应用
多页面应用
- 每次页面跳转,后端返回一个新的html
- 优点:首屏时间快、seo效果好(搜索引擎可以识别跳转的多个链接)
- 缺点:页面切换慢(每次跳转需发送http请求)
单页面应用
- js感知路由变化,动态清除页面内容并将新页面渲染
- 优点:页面切换快
- 缺点:首屏时间慢,seo差
移动web端配置
- 使用rem单位
- 防止手指放大缩小页面,修改index.js
<meta name="viewport" content="width=device-width,
initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
组件开发
合理拆分组件,提高开发效率。父组件通过import方式导入子组件,并且
export default {
name: 'xxx',
components: {注册子组件名}
插槽
使用场景:当组件的内容希望父组件去定制
stylus
style库,增加开发效率。
其中,.a >>> .b
具有穿透scoped限制的效果
防抖
为了防止图片加载的过程中,页面抖动(图片未加载完毕的时候,文字会在上方,加载完毕后会抖动)
.wrapper
width: 100%
height: 0
overflow: hidden
padding-bottom: 26.7% //图片的宽高比
vuex进行非父子组件数据传递
一般使用
vuex中有几个关键:单向数据的改变过程state
存放公用数据,组件改数据必须调用actions
,做一些异步处理或者批量的同步操作。然后actions调用mutations
,只有通过改变mutations的值才能改变state
- 在state中设置默认值
attr = 'aaa'
- 在组件中通过dispatch向actions派发数据(如果没有异步请求,可以直接使用commit,跳过这步)
this.$store.dispatch('actionsName', data)
在actions中通过commit向mutations发送数据
actionnName(tcx, data) { tcx.commit('mutationsName', data) }
然后在mutations中修改state中的值
mutationsName(state, data) { state.attr = data }
高级使用
- 引入mapState, mapMutations
import [mapState, mapMutations] from 'vuex
- 把mapState添加到计算属性(compute)中,把mapMutations添加到方法(methods)中
computed: { ...mapState({ currentCity: 'city }) }, methods: { ...mapMutations( ['changeCity'] ) }
axios发送ajax请求
- 使用生命周期函数mounted函数获取ajax数据,此时vue实例被挂载,但dom还没有渲染,可以节省性能
- 请求url:
axios.get('xxx/xxx.json')
axios返回的是promise对象,可以使用then
methods: { getCityInfo () { axios.get('/Travel/static/mock/city.json') .then(this.handleGetCityInfoSucc) }, handleGetCityInfoSucc (res) { res = res.data if (res.ret && res.data) { const data = res.data this.cities = data.cities this.hotCities = data.hotCities } ...
- 对以上代码的解释:
- 在mounted钩子函数里面定义一个A方法,只要页面加载完毕就执行A方法
- A方法用于获取后端的数据,它是一个promise函数,只要获取到了函数就then一个B函数
- B函数可以接收一个res参数,这个参数就是返回的结果
- ajax请求一般放在最外层的组件,这样只需要一次请求就可以获取所有页面的内容
ajax获取动态数据
- 在路由里的地址后面写:id,表示把对应的id参数存在了id变量中
- 在获取ajax请求的地址上,可以写
axios.get('xxx/xxx.json?id=' + this.$route.params.id)
- 也可以写
axios.get('xxx/xxx.json', {params: {id: this.$route.params.id}})
router-link
- vue中的内置路由组件
<router-link to='/city'></router-link>
- 使用前先在router/index.js中配置路由
- 可以通过配置tag属性改成别的标签
单行内容超出范围
当单行文字内容超出显示范围,而显示......
时,可以
overflow: hidden
white-space: nowrap
text-overflow: ellipsis
betterscroll
页面滚动插件
函数节流
当鼠标在字母表上来回移动的时候,touchMove执行的频率是非常高的,通过函数节流限制下执行的频率:增加延时器
localstorage
自动缓存,刷新页面的时候已经选择的城市不发生改变
- 相当于cookie,但是用法要简单很多
- 用法:
localStorage.arrt = va;ue
- 最好使用try catch包裹,因为在部分浏览器会报错
keepalive
优化问题:缓存页面数据,防止切换页面会发生多次ajax请求
<keep-alive>
<router-view/>
</keep-alive>
它的意思是,路由内容每被加载一次,就把路由中的内容放到内存之中,下一次再进这个路由的时候,不需要再次渲染这个组件去重新执行钩子函数,只需要你从内存把以前的内容拿出来显示到页面上就可以
组件中name属性
- 在递归组件时使用
- keepalive取消缓存在exclude=’组件name’中使用
- vue devtool调试工具中显示项目结构的名字
组件异步加载
正常情况下,单页应用会在进入首页时加载所有组件
可以删除import特定的组件,然后通过component: () => import('@/pages/home/Home)
按需加载
全局事件解绑
- window是全局事件,无论那个页面都会监听这个事件,会影响到其他页面,所以要解绑
- 在有keep-alive时会出现两个新的钩子函数:
- activated 在页面被显示时执行
- deactivated 在页面即将被隐藏或页面被替换的时候执行
简写
- @表示src目录
- es6中,键值对相同写一个就可以
组件一览
- home
- Header 头部
- Icon 原型图标区域
- Recommend 推荐
- Swiper 图片轮播
- Weekend 周末推荐
- city
- Header 头部
- Alphabet 右侧城市首字母下拉列表
- List 城市列表
- Search 搜索
- detail
- Header 头部
- Banner 主页面
- List 图片详情页的轮播
部署到GitHub pages
参考 https://medium.com/@Roli_Dori/deploy-vue-cli-3-project-to-github-pages-ebeda0705fbd
webpack
后期更新