一、首页


1.header区域开发

编写基本样式:

step1:
首先安装CSS 的预处理框架  npm 下载安装 stylus 、stylus-loader
step2:
编写程序要把页面拆分成一个又一个的组件 再通过引入组件的方式进行组合
导出局部组件 并命名一个name

在Home.vue引入局部组件
需要在components里声明 ,在页面上插入局部组件的时候 就可以直接插入<home-header> 就等同于HomeHeader

step3:
设置样式

在样式里这么写,引入css预处理器stylus 并且使用 scoped 使该样式只对当前组件有效

使用stylus后 写样式就不用中括号写了  并且尺寸用rem来写  

联系css中学的flexbox 这里使用flex来确保中间框的大小

插入iconfont图标

在基本样式写完后,需要插入iconfont图标
step1:
在网站上下载图标
step2:
在 assert/styles/iconfont文件夹里粘贴字体文件
在 assert/styles 文件夹里粘贴iconfont.css文件
并且更改css文件中的路径 确保正确引入各个字体文件

step3:
在main方法中引入iconfont

step4:
在Header.vue中使用iconfont

step5:
给图标设置居中,首先把元素标签改为div

再通过对该div设置text-align:center 来实现居中

注意:设置图标样式 要注意此时使用stylus 所以写样式时要按照元素的父子关系写


进行代码优化

许多变量,如背景颜色等,在项目中被反复使用,可以自定义名称
step1:
创建styles/varibles.styl  在该文件中写bgColor

step2:
在样式里引入样式,需要使用@import

step3:
可以使用自定义的变量了

除变量外,许多网址也被反复使用 

想要简洁一点,可以使用@
在css中要使用~@
需要更简洁一点的话,打开bulid/webpack.base.conf.js,在alias中自己设置路径别名

设置完就可以使用了

2.首页轮播

创建分支 

在实际项目开发过程中,每开发一个新的功能就需要创建一个新的分支
使用新分支来开发各种功能,测试通过后,在合并到主分支上
step1:
在码云中新建分支
step2:
把线上创建的分支同步到本地
下载分支
使本地分支切换该新建分支上


创建轮播

step1:
下载轮播插件Vue-Awesome-swiper

并按照官网中的提示,mian方法中全局引入该插件 
step2:
创建新组件 组件由以下三个部分组成

按照插件官方步骤,插入组件代码
需要在data中返回 swiperOption

step3:
在Home.vue中同样进行引入
step4:
对代码进行适当的删减
左右箭头不需要 可以删除

滚动条也可以删除
接下来插入图片就行了

step5:
接下来对图片进行样式设置,如高度宽度等

优化抖动

此时界面存在抖动感,有些类似于高度塌陷的问题
step1:
在轮播代码最外层加入一个div标签

注意:
如果直接设置height为31.25% 其height是相对于父级元素height而言的,而不是相对于宽度,
所以此处只能设置padding-bottom,从而将当前区域撑开
或者 vw指得viewpoint width,视窗宽度,1vw=视窗宽度的1%

界面完善

加入轮播底部的白灰色点点

step1:
添加配置pagination,引入底部圆点

step2:改变圆点颜色

注意:
此处的颜色样式并不是在当前组件内的,所以直接设置不起作用。
必须使用 >>> 做一个穿透 才能不受scoped的限制

step2:
做循环输出,需要在data里定义一个对象数组

step3:
在组件中使用v-for循环这个数组

step4:
添加配置loop:true, 从而实现前后循环轮播效果


提交分支代码

step1:
首先提交代码到码云
step2:
把新分支合并到主分支上
首先切换到master分支上

把当前分支合新增内容并到master分支上

再把master内容提交到线上


3.图标区域布局
照例,首先线上创建分支,在同步到本地。创建新的vue组件,再在Home.vue中引入组件。
step1:
做一个整体div块占位


step2:小图标 同样要进行占位


此时父元素的高度是0 所以icon也得设置padding-bottom
依次类推,共设置8个icon
step3:
对各个子块进行样式设置

3.引入AJAX

使用axios,并且在Home.vue中请求AJAX数据,并把数据传给每一个子组件
把数据放在static/mock里,创建一个json(因为只有static里的内容才能从外部访问)
里添加,使mock里的数据不被提交到线上
首先引入:

使用声明周期函数,mounted表示在页面加载后执行该数据


虽然代码里写的是api请求,但通过配置,使api请求转到本地mock文件夹中,需要对数据进行更改
g
父子组件之间传值:
step1:在父组件中创建data 传入空值
step2:把值以属性的形式传给子组件

step3:在子组件进行接收传过来的值
step4:在父组件中请求得到AJAX 将r请求得到的res值 传给 父组件的data

step5:在子组件中使用data接收父组件传来的值

二、城市选择页面

1.配置路由

step1:
在路由配置文件里添加配置
需要import City

step2:找到需要跳转页面的子块 添加router-link 和 to 属性

2.城市列表页面和字母表

基础页面编写:


让字母表竖着居中:

flex-direction属性:flex-direction 属性规定灵活项目的方向。
(如果不是flex 则不起作用)

justify-content属性:设置或检索弹性盒子元素在主轴(横轴)方向上的对齐方式

BetterScroll使用

better-scroll 是一款重点解决移动端(已支持 PC)各种滚动场景需求的插件 具体使用参照官网


动态数据渲染

请求AJAX 和Home组件里一样

兄弟组件数据传递

要实现点击右侧字母表 城市列表就滚动到对应的字母
思路:对字母表组件绑定一个点击事件 获得每次点击时的字母值 并将这个字母值传递给List组件
即  兄弟组件传值:字母表——>City.vue——>List.vue
1.对字母表组件 绑定一个点击事件

2 每次点击都向外触发事件change

3.在City.vue中监听事件change

change事件触发函数 handleLetterChange

以属性的形式 获取传来的值 并传给List.vue

List.vue接收

4.在List接收到传来的Letter值后,当字母值改变,List的显示也应该改变
使用 *** watch 实现:(一旦letter改变 就执行watch里的代码)
给每个字母绑定ref

获取$refs这个数组的第一个值(即当前字母项)使用scroll插件的函数实现跳转效果
取  第[0]项 是因为此时的$refs[this.letter]是一个数组 但是scroll方法使用的必须是元素。
取[0]值即为取到了元素


补充:ref $refs

在Vue中一般很少会用到直接操作DOM,而ref $refs 就是用来实现DOM操作的
ref 被用来给元素或子组件注册引用信息, 引用信息将会注册在父组件的 $refs 对象上,如果是在普通的DOM元素上使用,引用指向的就是 DOM 元素,如果是在子组件上,引用就指向组件的实例。
$refs 是一个对象,持有已注册过 ref 的所有的子组件。

当和 v-for 一起使用的时候,得到的 ref 将会是一个包含了对应数据源的这些子组件的数组 
也就是下图的这个情况:

字母表滚动时List也滚动

1.对字母表 绑定三个滚动事件

2.需要在data定义一个标识位 touchStatus: 来保证在滑动时才执行某些代码

开始时:

结束时:


3. 当 touchStatus:true 时 即为滑动字母表的过程
要将字母表上滑动的值传递给LIst 
思路时通过计算距离来确定当前滑动的字母是哪个
首先 通过计算属性定义一个letters的数组:

其次 定义两个数值:

这个高度为:A到绿色下沿


这个高度为:手指距离最顶部的高度
这两个高度相减,并且除以每个字母的高度,得到此时字母的下标

向外触发change事件


进行优化

节流:

3.搜索逻辑实现

搜索页面要实现的几个要点:

最起码的搜索逻辑


1.双向绑定input框内的输入值:

2.定义data

3.逻辑实现

4.循环输出this.list 

搜索结果页面滚动

依旧是使用better-scroll 和 生命周期钩子

无搜索结果时应有提示

通过 v-show 来实现

不搜索时搜索页面应该隐藏

也是通过v-show 来实现


4.**非兄弟组件传值:通过Vuex实现数据共享**

在City.vue和Home.vue这两个非兄弟组件间传值:需要Vuex实现

理念:把公用的数据放在一个仓库里 从而实现读取和改变(整个流程是单向的)

读state中的数据

1.在 src下 创建store(仓库)

写index.js
(Vue)里在使用插件都是用Vue.use来实现的
导出Vuex创建的Store
仓库里面有个state 存储着全局公用的数据

2.在main中引入store

在创建根实力时传入store

3.在需要使用公共数据的组件里使用 


改state中的数据

要实现List和Search中点击城市 就改变公共数据中city的值
1.首先以List组件为例
增加click事件 调用方法 传入此时的值

组件调用 dispatch 方法


2.在store的index文件中 创建actions:
ctx表示上下文 用ctx调用commit 执行mutations


3.创建mutations
在mutations中写入方法 改变数据

整个流程为:组件调用actions actions调用mutations mutations改变数据

对search组件做同样的改变

 页面跳转

希望实现点击城市后自动跳转回首页
在vue中有两种页面跳转的方式,这里使用编程式:
点击完城市跳转回首页:

5.一些优化

优化1:本地存储

之前的代码:在选中城市后一刷新又恢复到了初始默认值
通过localStorage 可以实现本地存储,解决这个问题

优化2:拆分state和mutations

state.js

mutations.js

index.js:

优化3:减少复杂度

使用mapState 和mapMutations 减少代码的复杂度
原本调用state里的数据需要写为:

复杂冗长
因此使用vuex的  mapState, mapMutations 接口进行简化

定义计算属性 mapState 
把vuex中的数据映射到该计算属性city里

直接使用

也可以写为:表示把vuex中的city数据映射到计算属性currentCity里

使用时为:



同理,定义mapMoutations 把changeCity 映射过来

调用时:


6.Vuex其他功能
getters




类似于computed属性 

Module
进行拆分