推荐博客
Vue 2.5 开发 去哪儿 旅游网站项目记录
项目源码 : https://gitee.com/doublesgzl/Travel
6-1 环境配置 (建议看下视频)
6-2 项目代码介绍
6-3 单文件组件与Vue中的路由
6-4 单页应用VS多页应用 解析1、解析2、解析3 GOOD
6-5 项目代码初始化
1.首页header开发
2.stylus预处理器的使用
3.iconfont 的使用
4.首页轮播图
5.图标区域页面布局和逻辑实现 参考
6.热销推荐组件和周末游组件开发
7.ajax 请求获取首页数据
1-1 创建Home.vue
的子组件
pages/home/components/Header.vue
pages/home/Home.vue
组件中引入子组件Header.vue
,
.wrapper
overflow :hidden
width: 100%
height:0
padding-bottom :31.25%
4-3 给轮播插件添加底部的轮播点
第一步,在data中返回pagination: '.swiper-pagination'
,发现底部出现蓝色的点;
data: function () {
return {
swiperOption: {
pagination: '.swiper-pagination'
}
}
}
第二步,设置点的样式,不能写在.wrapper
的下面,会失效!!!
// 样式穿透
.wrapper >>> .swiper-pagination-bullet-active
background: #fff
4-4 swiper轮播图的图片循环
第一步,在swiper
下面只保留一个swiper-slide
标签,设置v-for=''item of SwiperList"
;
第二步,在data
中加入轮播图片数据
data: function () {
return {
swiperOption: {
pagination: '.swiper-pagination',
loop: true // 用于循环轮播,否则第一张图片前面就空了
},
SwiperList: [{
id: '0001',
imgUrl: 'http://mp-piao-admincp.qunarzz.com/mp_piao_admin_mp_piao_admin/admin/20197/ae8987bff39ff10e82675a3643154e66.jpg_750x200_0f187b2e.jpg'
}, {
id: '0002',
imgUrl: 'http://mp-piao-admincp.qunarzz.com/mp_piao_admin_mp_piao_admin/admin/20197/e43d3043ee612ad71dd6c68f29e3ed9a.jpg_750x200_b90f2963.jpg'
}, {
id: '0003',
imgUrl: 'http://mp-piao-admincp.qunarzz.com/mp_piao_admin_mp_piao_admin/admin/20193/d7bbc21db442366a882e04ddc984669a.jpg_750x200_85e640d9.jpg'
}]
}
}
4-5 保存代码到本地仓库并提交到线上仓库
master分支放的是整个项目所有功能最新的代码,index-swiper分支上放的是具体功能开发完成的代码。一般开发时会自己开发一个新的分支,测试没问题后整合到master分支上。
git add .
git commit -m 'change'
git push
(把本地index-swiper分支上的内容提交到线上index-swiper分支上)git checkout master
(合并,先切换到master分支上)git merge origin/index-swiper
(把线上index-swiper分支新增的内容合并到本地merge分支)git push
(把master分支的内容也提交到线上)5-1 在线上git仓库上新建一个index-icons
分支,然后在终端获取新创建的分支到本地
git pull
git checkout index-icons
5-2 实现图标区域布局,定义样式
5-3 图标区域逻辑实现,多页切换的轮播效果展示。
同Swiper组件在data中return一个iconsList数组,在template中使用轮播结构放入每个图标模块。 并在Chrome浏览器上安装Vue devtools插件
(一种vue的调试工具),安装完毕后重启浏览器,在浏览器开发者工具的最上面一栏的最后就可以看见Vue
一项了。
问题(1):当只有一条数据时,页面中仅可以操控图标模块范围进行滑动,在别的空白区域却不行,这里需要设置swiper的.swiper-container
样式为icons
的样式,从而解决此问题,.swiper-container
类你可以在浏览器开发工具中选中区域进行查看。
{{item.desc}}
.icons >>> .swiper-container
width :100%
height :0
padding-bottom :50%
问题(2):若共有10条数据,当前页面只能显示8条,另外两条被隐藏了,也无法滑动显示,此时,利用Vue中的计算属性
来控制每个轮播页中数据的显示 ,更新swiper的数据绑定。
computed: {
pages () {
const pages = []
this.iconsList.forEach((item, index) => {
const page = Math.floor(index / 8)
if (!pages[page]) {
pages[page] = []
}
pages[page].push(item)
})
return pages
}
}
{{item.desc}}
5-4 用省略符代替长串文字,通过CSS样式控制
.icon-text
...
overflow :hidden
white-space :nowrap
text-overflow :ellipsis
5-5 将省略符的CSS代码封装
创建styles/mixins.styl
文件,写入以下代码,在Icons.vue
的style标签内导入@import '~styles/mixins.styl'
,然后用ellipse()
一句话即可
ellipse()
overflow :hidden
white-space :nowrap
text-overflow :ellipsis
.icon-text
...
ellipse()
5-6 保存代码到本地仓库并提交到线上仓库
git add .
git commit -m 'change'
git push
git checkout master
git merge origin/index-swiper
git push
6-1 在git线上仓库中创建index-recommend
分支,在终端Travel下依次执行
git pull
git checkout index-recommend
6-2 新建components/Recommend.vue
组件,同Home.vue
组件连接;
6-3 先搭建好页面结构和CSS样式,再循环显示数据,套路基本同上
热销推荐
-
{{item.title}}
{{item.desc}}
6-4 周末游组件开发 代码同6差不多 微调就行
6-5 保存代码到本地仓库并提交到线上仓库
- git branch (查看所有分支)
7-1 线上git仓库创建index-ajax
分支,下载到本地仓库
git pull
git checkout index-ajax
7-2 如何在没有后端支持的情况下实现数据的模拟??
创建static/mock/index.json
文件,将swiperList
,iconsList
,recommendList
,WeekendList
等本地开发的模拟数据放置到index.json
中。之所以放到static
文件夹下,是因为static
文件夹里的内容可直接被外界访问到,比如在浏览器中输入http://localhost:8080/static/mock/index.json
,就可以显示出/index.json
中的内容。
7-3 /index.json
中存储的是一些本地开发的模拟数据,并不希望它同代码上传到本地/线上仓库,此时,在.gitignore
文件中添加static/mock
即可。
7-4 统一在Home.vue
中发送一次Ajax请求,而不要试图在每个组件中都发送Ajax请求:
(1)首先在Home.vue
中导入import axios from 'axios'
,记得提前安装axios
库;
(2)让页面挂载好之后去执行getHomeInfo()
方法;
mounted () {
this.getHomeInfo()
}
(3)在函数中定义getHomeInfo()
方法,去获取Ajax数据,axios返回的结果是一个promise对象;数据获取成功后调用getHomeInfoSucc()
输出结果。
methods: {
getHomeInfo () {
axios.get('/api/index.json')
.then(this.getHomeInfoSucc)
},
getHomeInfoSucc (res) {
console.log(res)
}
}
7-5 在实际项目开发中,不建议随意改动axios.get(‘/api/index.json’)
中的地址,那如何转换到本地模拟的接口地址(/static/mock/index.json
)呢?
【解决】在vue中提供了proxy代理
功能,以此实现接口地址的转换。在config/index.js
文件中设置:
proxyTable: {
'/api':{
target:'http://localhost:8080',
pathRewrite:{
'^/api':'/static/mock'
}
}
}
这里理解成用"/api"代替target里面的地址,后面组件中调用接口时直接用api代替 。比如调用"http://localhost:8080/static/mock/index.json",直接写"/api/index.json"即可。注意,它不是vue提供的,而是webpack dev server 提供的。
7-6 首页父子组件的数据传递
在父组件中
export default {
...
data () {
return {
city: '',
SwiperList: []
}
},
mounted () {
this.getHomeInfo()
},
methods: {
getHomeInfo () {
axios.get('/api/index.json')
.then(this.getHomeInfoSucc)
},
getHomeInfoSucc (res) {
res = res.data
if (res.ret && res.data) {
this.city = res.data.city
this.SwiperList = res.data.swiperList
}
}
}
}
在子组件中,props是子组件访问父组件数据的唯一接口。若子组件想引用父组件的数据,需要在props中声明一个变量city,变量city就可以引用父组件的数据(
)。然后在子组件模板里渲染变量city,此时渲染出来的就是父组件中的数据。
...
{{this.theCity}}
7-7 在Swiper
组件的数据传递中出现问题:默认显示的图片是第四张而不是第一章图片?这是因为Swiper
最初是通过空数组创建的,然后Ajax获得数据后才变成真正的数据,为避免此问题,首先判断list
数组是否为空,待获取到真正的数据才创建Swiper
。
进一步,在模板中尽量避免出现一些逻辑性的代码,比如
v-if="list.length"
,这里可以使用computed
计算属性来实现数组长度的计算,然后在v-if
中直接使用showSwiper"
计算属性即可。
...
computed: {
showSwiper () {
return this.list.length
}
}
7-8 Icons.vue
、Recommend.vue
、Weekend.vue
数据绑定
7-9 Swiper.vue
组件中的图片自动轮播
data: function () {
return {
swiperOption: {
pagination: '.swiper-pagination', // 轮播点
loop: true,
autoplay: 3000 // autoplay: true虽然自动轮播了但是速度很快,直接在后面跟时间设置就好
}
}
},
7-10 保存代码 合并到master分支
1 路由配置 + 搜索框布局
2 列表布局
3 BetterScroll 的使用和字母表布局
4 页面的Ajax动态数据渲染
5 兄弟组件数据传递 及 列表性能优化
6 搜索逻辑实现
7 Vuex实现数据共享
8 Vuex的高级使用及localStorage
9 使用keep-alive优化网页性能
1-1 创建city-router
分支。在router/index.js
中配置City.vue
的路由信息,导入import City from '@/pages/city/City'
。
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/city',
name: 'City',
component: City
}
]
1-2 【首页到城市列表页面的跳转】在Header.vue
中,给“北京”的div外面包围
,地址根据index.js
的路由配置决定。
成功跳转后,“北京”字体颜色变成绿色,是因为添加
过程中,给div
包裹了一个a
标签,默认显示绿色。这里给header-right
设置字体颜色为白色即可。
{{this.city}}
1-3 在“城市列表页面”左上角添加返回按钮,同样用router-link
链接。
1-4【搜索框布局】创建Search.vue
组件,添加input框设置样式即可。
1-5 将city-router
分支合并到master
分支上。
2-1 新建city-list
仓库。创建List.vue
组件,添加3个list模块,设置样式。
2-2 给整个list
设置position :absolute
和overflow :hidden
,固定页面的高度,使屏幕不随内容的增加而变长。
.list
overflow :hidden
position :absolute
top: 1.58rem
left:0
right :0
bottom :0
BetterScroll 插件(github)实现页面的滚动。
3-1 插件安装
npm install better-scroll --save
Better-scroll
插件使用的结构要求,要按照这种结构编写项目代码
- ...
- ...
...
3-2 插件使用
import BScroll from 'better-scroll'
,ref
用于获取DOM元素
- 在
mounted
中设置如下,然后页面可以上下拖动了
mounted () {
// 获取DOM元素,相当于let list = document.querySelector('.list');let scroll = new BScroll(list)
this.scroll = new BScroll(this.$refs.wrapper)
}
3-3 字母表
新建Alphabet.vue
组件,添加一组...
来做字母表,设置绝对位置,样式如下。
.list
display :flex // 弹性布局
flex-direction :column // 主轴方向为纵轴
justify-content :center // 纵向居中
position :absolute // 绝对位置
right:0 // 向右靠
top:1.58rem // 设置顶部距离
bottom :0 // 设置底部距离
width:.4rem //设置字母表的宽度
.item
text-align :center
line-height :.4rem
color :$bgColor
3-4 将city-list
分支合并到master
分支上
4 页面的动态数据渲染(Ajax)
4-1 创建city-ajax
分支。在City.vue
中导入import axios from 'axios'
,通过ajax
从static/mock/city.json
中模拟数据的获取。
data () {
return {
cities: {},
hotCities: []
}
},
mounted () {
this.getCityInfo()
},
methods: {
getCityInfo () {
axios.get('/api/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
}
}
}
4-2 在City.vue
中的template
中传递数据给子组件
4-3 在List.vue
子组件中,通过props
获取父组件传递过来的数据,并使用v-for
循环遍历输出。注意:v-for
可以遍历数组
和对象
,在遍历对象
时,,key
表示对象中的属性,可以用来当做key,比如var list = {"A":[{"a"},{"b"}],"B":[{"c","d"}]};
,其中,key
代表的就是“A”,"B","C"
props: {
hot: Array,
cities: Object
}
{{key}}
{{innerItem.name}}
4-4 在Alphabet.vue
组件中,用v-for
循环遍历props
从父组件获取的对象
数据;
4-5 将city-ajax
分支合并到master
分支上;
5 兄弟组件数据传递
点击字母表,希望相应的内容能自动滚动到页面的显示区域中。
5-1 新建city-components
分支;
5-2 在Alphabet.vue
的循环项li
中添加click
事件,在methods中写入handleLetterClick()
。那么,如何在Alphabet.vue
和List.vue
之间传值呢?
-
{{key}}
methods: {
handleLetterClick (e) {
console.log(e.target.innerHTML)
}
}
5-3 (1)bus总线传值;(2)让Alphabet.vue
把数据传给City.vue
,再由City.vue
把数据传递给List.vue
。
使用方式(2)进行传值。首先,由Alphabet.vue
子组件在循环元素上添加点击事件handleLetterClick()
中,通过this.$emit()
件向外触发change
事件,传递数据给City.vue
父组件,this.$emit('change', e.target.innerHTML)
。其次,由City.vue
父组件监听@change="handleLetterChange"
事件,并在methods中定义handleLetterChange()
来处理从Alphabet.vue
接收到的数据。
handleLetterChange (letter) {
console.log(letter)
}
5-4 由City.vue
父组件将接收到的数据通过属性的形式(:letter="letter"
)转发给List.vue
子组件。
...
...
data () {
return {
...
letter: ''
}
},
methods: {
...
handleLetterChange (letter) {
this.letter = letter
}
}
5-5 最后,在List.vue
子组件中通过props
接收City.vue
父组件传递过来的数据。
5-6 拿到点击的字母后(this.letter发生改变),如何使相应的列表内容滚动显示在页面中???
【解决】 List.vue
子组件中用watch
监听letter
的变化。通过:ref
和this.$refs[this.letter]
获取对应的DOM元素,然后通过this.scroll.scrollToElement(this.$refs[this.letter][0]
)`一步实现。
props: {
hot: Array,
cities: Object,
letter: String
}
...
...
import BScroll from 'better-scroll'
...
mounted () {
// 获取DOM元素,相当于let list = document.querySelector('.list');let scroll = new BScroll(list)
this.scroll = new BScroll(this.$refs.wrapper)
},
watch: {
// 在watch中监听letter的变化
letter () {
if (this.letter) {
// 返回的ele是一个数组,但在this.scroll.scrollToElement()中参数必须是一个DOM元素,所以传入数据为ele[0]
const ele = this.$refs[this.letter]
this.scroll.scrollToElement(ele[0])
}
}
}
5-7 滑动字母表,使左侧的城市列表也会随之变动。
在Alphabet.vue
中给循环项绑定三个事件:@touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd"
,在methods
中定义这三个函数,为保证在touchStart
事件之后才可以触发touchMove
事件,在data
中定义touchStatus: false
来控制事件顺序。
...
data () {
return {
touchStatus: false
}
},
methods: {
...
handleTouchStart (e) {
this.touchStatus = true
},
handleTouchMove () {
},
handleTouchEnd () {
this.touchStatus = false
}
}
接下来,需要知道当前滑动到的是字母表中的第几个字母,需要根据位置来进行判断。首先,通过计算属性 遍历cities
获取存储字母表的数组letters
。
computed: {
letters () {
const letters = []
for (let i in this.cities) {
letters.push(i)
}
return letters
}
}
获取到letters
数组后,在template
中用letters
数组代替cities
对象来遍历,
-
{{item}}
下一步,在handleTouchMove()
事件中计算距离,来判断当前手指滑动所在位置的字母,并将该字母传递给City.vue
父组件。
handleTouchMove (e) {
if (this.touchStatus) {
// startY是字母"A"至list顶部的距离
const startY = this.$refs['A'][0].offsetTop
// e.touches[0]表示一些手指的信息,clientY是手指到页面最顶部的距离
// 当前手指到list顶部的距离 = 手指到页面最顶部的距离 - 页面顶部蓝色区域的高度
const touchY = e.touches[0].clientY - 79
// index从0计数: 当前手指所在的位置是第index个字母 = (当前手指到list顶部的距离 - 字母"A"至list顶部的距离)/ 每个字母的高度
const index = Math.floor((touchY - startY) / 20)
// 这里要判断index的值,不要让它超出范围,不然后面数据都不存在,会出错
if (index >= 0 && index <= this.letters.length) {
this.$emit('change', this.letters[index])
}
}
}
5-8 列表性能优化
(1)在handleTouchMove()
事件中,this.startY
是固定的,不需要每次都计算一遍,因此把它提取出来,在updated()
钩子中执行,在handleTouchMove()
中只要调用this.startY
即可,
data () {
return {
touchStatus: false,
startY: 0
}
},
// 当页面的数据被更新的同时页面完成渲染后,updated钩子函数执行
updated () {
// startY是字母"A"至list顶部的距离
this.startY = this.$refs['A'][0].offsetTop
}
(2)函数节流 限制函数执行的频率
如果this.timer
已经存在,把this.timer去除掉,否则创建一个新的this.timer
;
延迟16ms之后再执行,假设在这16ms之内又进行了手指的滚动,那么它会把上一次要做的动作清除掉并重新执行这一次要做的事情!!!
data () {
return {
touchStatus: false,
startY: 0,
timer: null
}
},
handleTouchMove (e) {
if (this.touchStatus) {
if (this.timer) {
clearTimeout(this.timer)
}
this.timer = setTimeout(() => {
// e.touches[0]表示一些手指的信息,clientY是手指到页面最顶部的距离
// 当前手指到list顶部的距离 = 手指到页面最顶部的距离 - 页面顶部蓝色区域的高度
const touchY = e.touches[0].clientY - 79
// index从0计数: 当前手指所在的位置是第index个字母 = (当前手指到list顶部的距离 - 字母"A"至list顶部的距离)/ 每个字母的高度
const index = Math.floor((touchY - this.startY) / 20)
// 这里要判断index的值,不要让它超出范围,不然后面数据都不存在,会出错
if (index >= 0 && index <= this.letters.length) {
this.$emit('change', this.letters[index])
}
}, 16)
}
}
6 搜索逻辑实现
功能 :当搜索城市名字或拼音时,能把搜索结果显示出来
6-1 新建city-search-logic
分支。在data
中存一个keyword
数据,让input框的内容同keyword
做一个双向绑定(v-model
)。
...
data () {
return {
keyword: ''
}
},
6-2 Search.vue
子组件接受City.vue
父组件传递的cities
数据,用于搜索词的匹配。
props: {
cities: Object
}
6-3 在data
中定义list
空数组,用watch
监听keyword
的变化,并增加一个节流函数,提高代码的执行效率
- {{item.name}}
...
data () {
return {
keyword: '',
list: [],
timer: null
}
},
watch: {
keyword () {
if (this.timer) {
clearTimeout(this.timer)
}
this.timer = setTimeout(() => {
const result = []
// 遍历cities对象中的内容
for (let i in this.cities) {
this.cities[i].forEach((value) => {
if (value.spell.indexOf(this.keyword) > -1 ||
value.name.indexOf(this.keyword) > -1) {
result.push(value)
}
})
}
this.list = result
}, 100)
}
6-4 修改
的样式
.search-content
...
background :#eee
.search-item
line-height:.62rem
padding-left :.2rem
color: #666
background :#fff
6-5 若搜索结果很多,但是页面显示内容有限,如何实现页面搜索结果的滚动?
引入import BScroll from 'better-scroll'
,在mounted
钩子函数中创建一个scroll,this.scroll = new BScroll(this.$refs.search)
,其中传入的是类名为search-content
的div
结构;
6-6 在搜索框中输入搜索内容,会显示搜索结果,但此时若是清空搜索框内容,页面中依然存在原来的搜索结果。
在keyword
监听代码中判断keyword
是否为空,若为空,则设置list = []
,返回即可。
if (!this.keyword) {
this.list = []
return
}
6-7 在input
中输入一长串内容,但无内容匹配。
在
中再添加一个li
标签,- 没有找到匹配数据
,当list
数组为空,则显示“没有找到匹配数据”。
前面说到,当尽量避免在template
中使用逻辑运算,可用计算属性代替。
- 没有找到匹配数据
...
computed: {
hasNoData () {
return !this.list.length
}
}
6-8 实现页面搜索结果与城市列表的切换,即未搜索时显示城市列表,搜索时显示搜索结果。用v-show="keyword"
来判断即可,keyword
为空,则不显示。
6-9 保存代码,将city-search-logic
分支合并到master
分支
7 使用Vuex实现首页和城市列表页面的数据共享
功能:将城市页面中的数据传递给首页。
但City.vue
组件和Home.vue
组件没有共有的父组件,无法实现数据的中转,而使用Bus总线又会很麻烦。在Vue中提供了一个vuex数据框架。
7-1 vuex
的初步使用
(0)新建city-vuex
分支
(1)安装vuex
:npm install vuex --save
;
(2)创建src/store/main.js
,写入
import Vue from 'vue'
import Vuex from 'vuex'
// 使用Vuex插件
Vue.use(Vuex)
// 导出Vuex创建的一个store仓库
export default new Vuex.Store({
// state存放的是全局公用的数据
state: {
city: '北京'
}
})
(3)在src/main.js
中 导入vuex
import store from './store/main.js'
...
new Vue({
el: '#app',
router,
store,
components: { App },
template: ' '
})
7-2 让Header.vue
组件使用vuex
的数据
以前,Header.vue
中的city
是由Home.vue
父组件传递进来的,而且该数据是Home.vue
父组件通过Ajax获取的。现在我们希望city
是前端存储的,而不是后端返回给前端的,所以在Home.vue
父组件中把city
相关的数据都删除掉,把static/mock/city.json
中的city
数据也删除,此时页面就不会显示城市名。
如何将公用数据中的城市名称显示出来呢?
在Header.vue
中删除props数据,将{{this.city}}
改成{{this.$store.state.city}}
,页面中就能正常显示城市名称了。
this.$store
就是store/main.js
中创建的Vuex.Store()
,由于在src/main.js
创建根实例时把store
传递进去了,然后它会被派发到每一个子组件中,所以在每个子组件中都可以通过this.$store
获取到公用数据。
7-3 在城市列表页面中,修改当前城市的显示。
7-4 当点击列表中的城市时,让公用数据中的this.$store.state.city
发生变化,流程:子组件
->Actions
->Mutations
->State
。
(1)给List.vue
组件,热门城市中的每个循环项绑定一个@click=“handleCityClick(item.name)”
事件,并传入相应的item.name
;
(2)在methods
方法中,通过dispatch
派发一个名字为changeCity
的action
,并传入参数city
;另外,在store/main.js
中定义action
操作。
methods: {
handleCityClick (city) {
this.$store.dispatch('changeCity', city)
}
}
export default new Vuex.Store({
// state存放的是全局公用的数据
state: {
city: '北京'
},
actions: {
changeCity (ctx, city) {
console.log(city)
}
}
})
(3) 调用Mutations
改变公用的数据state.city
actions: {
// ctx调用commit()方法
changeCity (ctx, city) {
ctx.commit('changeCityMutation', city)
}
},
mutations: {
// state参数指的是所有的公用数据
changeCityMutation (state, city) {
state.city = city
}
}
(4) 在上方操作中,并没有用到异步执行,可以直接跳过Actions
步骤,让子组件直接使用Mutations
变更状态。
在List.vue
中,将this.$store.dispatch('changeCity', city)
替换为this.$store.commit('changeCityMutation', city)
,删除store/main.js
中Actions
操作。
(5)实现:点击城市列表中的列表项,实现数据的动态更新。
{{innerItem.name}}
(6)实现:城市搜索时,点击下方搜索结果的城市,实现数据的动态更新。
(7)实现:在城市列表页面中选择某城市后,自动跳转到首页。
涉及到Vue Router
中的编程式导航
(I’m here)
methods: {
handleCityClick (city) {
this.$store.commit('changeCityMutation', city)
// 跳转到首页,一步就好
this.$router.push('/')
}
}
(8)页面跳转方式小结
网页页面跳转的两种方式
1)a标签的跳转
2)JS的window.location.href实现跳转
vue跳转的两种方式
1)router-link 标签的跳转
2)JS的编程式导航 router.push()实现页面跳转
7-5 合并city-vuex
分支到master
上。
后面的内容因为电脑故障 导致笔记丢失 可以点击前面章节中的链接分别查看相关内容。
第9章 旅游网站详情页面开发
渐隐渐显Header组件
公用组件的拆分
路由参数的获取与处理
递归组件的使用
通用动画效果的代码封装
9-1 动态路由和banner布局
9-2 公用图片画廊组件拆分
9-3 实现Header渐隐渐显效果
9-4 对全局事件的解绑
9-5 使用递归组件实现详情页列表
9-6 动态获取详情页面数据
9-7 在项目中加入基础动画
第10章 项目的联调,测试与发布上线
项目的联调,测试,及发布的详细流程;
过程中可能遇到的问题及修复方案;
异步组件,提高大型项目的首屏速度;
10-1 项目前后端联调
10-2 真机测试
10-3 打包上线
10-4 异步组件实现按需加载
10-5 课程总结与后续学习指南