笔记目录
小概
本章学习内容:路由使用的复习,路由编程式导航,路由传参。 移动端云音乐项目(vant移动端组件库 ,干货满满)
1. 路由复习
HTML页面两个步骤
- 设置路由导航:<router-link to="/></ rouer-link>默认被渲染成a标签,to可以看出a标签的href
- 设置路由出口:路由对应的组件应该加载的位置
js页面四个步骤(可以路由配置可以单独用一个模块文件来写,也可以直接写在main.js入口配置文件中)
- 导入vue-router并使用,定义组件
- 定义路由规则(routers)
- 创建router实例,然后传入’routers’配置
- 挂载路由(入口文件挂载router实例)
2. 路由编程式导航
路由跳转有两种方式:
- < router-link to=’’>:渲染成a标签,点击无条件跳转,这种是没有业务逻辑的
- this.$router.push: 借助router实例方法(push)使用js条件(类似于window.location.herf),可以做业务逻辑
<script>
export default {
//事件
methods: {
mineClick () {
/*路由跳转有两种方式
1. <router-link> : 渲染成a标签,点击无条件跳转路由。没有业务逻辑
2. this.$router.push() : 使用js条件(类似于window.location.herf),可以做业务逻辑
*/
if (confirm('请先登录')) {
//跳转登录组件(页面)
//写法1 : 使用路径跳转
// this.$router.push('/login')
//写法2 : 使用组件name跳转 (name没有/)
this.$router.push({ name: 'login' })
} else {
//跳转到我的组件
this.$router.push('/mine')
}
},
friendClick () {
/* 路由传参有两种方式
第一种:使用query传参 : 相当于之前的window.location.href = 'url?key=value'
* 接收: this.$route.query (停留在window位置,刷新参数一直在)
第二种: 使用params传参 : 内存传参 (页面不能刷新,一刷新就没有了)
* 接收: this.$route.params
*/
// this.$router.push({
// path: '/friend', //路径跳转组件
// query: {
// //参数
// name: '张三',
// age: 20
// }
// })
/* params传参: 用户在地址栏看不见,页面一刷新就没有了
使用params的时候,需要通过name跳转路由(传递隐私数据)
*/
this.$router.push({
name: 'friend', //name跳转组件
params: {
//参数
name: '张三',
age: 20
}
})
}
}
}
</script>
3. 路由传参
路由传参有两种方式
- 使用query传参 : 相当于之前的window.location.href = ‘url?key=value’
- 接收: this.
$route.
query (停留在window位置,刷新参数一直在
)
- 使用params传参 : 内存传参 (
页面不能刷新,一刷新就没有了
)
- 接收: this.$route.params
*/
4. 移动端云音乐项目
相关技术栈:vue-cli,axios,vue router,vant组件库,组件传参,路由缓存
页面:首页,搜索页,播放页
4.1 axios全局配置与原型挂载
(1)为什么需要原型挂载: 项目中很多个地方都要用axios,用一次导入一次非常麻烦。可以使用js原型链知识,将
axios对象挂载到Vue构造函数原型中,这样每一个组件(组件就是vue实例对象),就可以访问了
(2)如何挂载:Vue.prototype.$ axios = axios
(3)组件如何访问axios : this.$axios
axios.defaults.baseURL = '基地址';
设置请求基地址
vant组件库的组件引入:建议按需引入,需要使用到上面就引入上面组件和样式,好处是项目打包出来比全局导入体积小,我这用的是全局导入,不建议在项目中使用,但是写起来方便,导入一次所有的组件就可以直接使用无需再导入。
main.js人口文件
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
//1.导入axios
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
//axios全局配置
axios.defaults.baseURL = 'https://autumnfish.cn';//设置基地址
Vue.prototype.$axios = axios
//全局导入: 直接在入口文件一次性导入所有的vant组件
//其他地方直接使用,无需导入
import Vant from 'vant';
import 'vant/lib/index.css';
Vue.use(Vant);
new Vue({
router,
render: h => h(App)
}).$mount('#app')
4.2 vant组件的使用
- vant-tabbar导航栏(用于实现底部栏)
底部栏用于点击切换首页和搜索页,功能类似router-link路由导航,写在App.vue主组件中。
<!-- 底部tab栏 -->
<van-tabbar
v-model="active"
@change="onChange"
route
active-color="#8bc34a"
placeholder
>
<van-tabbar-item to="/" icon="home-o">首页</van-tabbar-item>
<van-tabbar-item to="/find" icon="search">搜索</van-tabbar-item>
</van-tabbar>
- vant-navbar顶部栏
首页组件的结构(/)
<van-nav-bar title="首页" fixed placeholder />
fixed是否固定在顶部 默认值:false,placeholder:固定在顶部时,是否在标签位置生成一个等高的占位元素, 默认值: false,加了就是turn。
- vant-swipe轮播图
首页轮播图
通过v-for循环加载轮播图
<!-- 轮播图 -->
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item v-for="item in banners" :key="item.bannerId">
<img class="swipe-img" :src="item.pic" alt="" />
</van-swipe-item>
</van-swipe>
- vant-cell单元格
用来写首页中最新歌单结构
<!-- 列表 -->
<div class="song-list">
<van-cell
@click="playClick(item.id)"
v-for="item in newSongs"
:key="item.id"
:title="item.name"
size="large"
:label="item.song.artists[0].name"
>
<template #right-icon>
<van-icon name="play-circle-o" class="play-icon" />播放按钮
</template>
</van-cell>
- vant-srarch 搜索框
搜素页的搜索框
4.3 首页js代码
<script>
export default {
name: "Home",
//data数据
data() {
return {
//轮播图数据
banners: [],
//推荐歌单数据
songList: [],
//最新音乐
newSongs: [],
};
},
//生命周期钩子
created() {
this.$axios({
url: "/banner?type=2",
method: "get",
}).then((res) => {
//成功回调
// 轮播图数据绑定
this.banners = res.data.banners;
console.log(this.banners);
});
//1.加载轮播图数据
this.$axios({
url: "/banner",
method: "get",
params: { type: 2 },
}).then((res) => {
//成功回调
console.log(res);
this.banners = res.data.banners;
});
//2.加载推荐歌单
this.$axios({
url: "/personalized",
method: "get",
params: { limit: 30 },
}).then((res) => {
//成功回调
console.log(res);
this.songList = res.data.result;
});
//3.最新音乐
this.$axios({
url: "/personalized/newsong",
method: "get",
}).then((res) => {
//成功回调
console.log(res);
this.newSongs = res.data.result;
});
},
//事件处理函数
methods: {
playClick(id) {
//路由跳转
this.$router.push({ path: "/play", query: { id } });
},
},
};
</script>
4.4 搜索页
<template>
<div class="find">
<van-nav-bar title="搜索页" />
<van-search
shape="round"
v-model="value"
placeholder="请输入搜索关键词"
@search="onSearch"
@input="onInput"
/>
<!-- 搜索下容器 -->
<div class="search_wrap">
<!-- 标题 -->
<p class="hot_title">热门搜索</p>
<!-- 热搜关键词容器 -->
<div class="hot_name_wrap" v-if="result.length === 0">
<!-- 每个搜索关键词 -->
<span
class="hot_item"
v-for="(item,index) in hotList"
:key="index"
@click="value=item.first;onSearch()"
>{{ item.first }}</span>
</div>
<!-- 搜索结果 -->
<div class="search_wrap" v-else>
<!-- 标题 -->
<p class="hot_title">最佳匹配</p>
<van-cell
v-for="item in result"
:key="item.id"
:title="item.name"
size="large"
:label="item.artists[0].name"
@click="$router.push({ name: 'play', query: { id: item.id } })"
>
<template #right-icon>
<van-icon name="play-circle-o" class="play-icon" />
</template>
</van-cell>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'find',
data () {
return {
// 搜索关键词
value: '',
//搜索结果
result: [],
//热搜列表
hotList:[]
}
},
methods: {
onSearch () {
//enter键触发
this.$axios({
url: '/search',
method: 'get',
params: { keywords: this.value }
}).then(res => {
//成功回调
console.log(res)
this.result = res.data.result.songs
})
},
onInput () {
//内容变化触发
//判断是否为空,为空则清空搜索列表
if (this.value.length === 0) {
this.result = []
}
}
},
//生命周期钩子
created() {
this.$axios({
url:'/search/hot',
method:'get',
}).then(res=>{
//成功回调
console.log(res)
this.hotList = res.data.result.hots
});
},
}
</script>
<style scoped lang="less">
/* 搜索容器的样式 */
.search_wrap {
padding: 0.266667rem;
}
/*热门搜索文字标题样式 */
.hot_title {
font-size: 0.32rem;
color: #666;
}
/* 热搜词_容器 */
.hot_name_wrap {
margin: 0.266667rem 0;
}
/* 热搜词_样式 */
.hot_item {
display: inline-block;
height: 32px;
margin-right: 8px;
margin-bottom: 8px;
padding: 0 14px;
font-size: 14px;
line-height: 32px;
color: #333;
border-color: #d3d4da;
border-radius: 0.853333rem;
border: 1px solid #d3d4da;
}
/* 给单元格设置底部边框 */
.van-cell {
border-bottom: 1px solid lightgray;
}
.find .play-icon {
font-size: 30px;
color: gray;
}
.find {
.van-cell__title {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
</style>
5. 路由缓存
- 默认情况下,当路由跳转的时候。页面会重新刷新。如果希望不刷新,则可以使用路由缓存。
.
应用场景:搜索页面搜索后显示歌单,点击其中一首歌,路由跳转到播放页面,此时再返回搜索页,路由 跳转默认歌单是会刷新掉的,我们想返回的时候还能看到之前搜索的歌单,就可以用到路由缓存。
用法:将路由出口(< router-view />)用keep-alive包裹,
注意:直接用< keep-alive>< router-view />< /keep-alive>则所有的路由跳转的组件都会被缓存,需要设置include=‘组件名’,设置只有搜索页这个组件才需要路由缓存
。
<!-- 路由出口:显示组件的容器 -->
<keep-alive include="find">
<router-view />
</keep-alive>
总结
云音乐git地址: https://gitee.com/hlwlyp/cloud-music.git