文章目录
在码云创建index-recommended分支
然后在根目录下cmd,输入命令行
git pull
git checkout index-recommended
git status
npm run dev
在Home.vue中引用Recommend.vue组件和Weekend.vue组件
Recommend.vue组件
<template>
<div class="recommend">
<div class="title">热销推荐</div>
<ul>
<li
class="item border-bottom"
v-for="item in recommendList"
:key="item.id"
>
<img class="item-img" :src="item.imgUrl" />
<div class="item-info">
<p class="item-title">{{ item.title }}</p>
<p class="item-desc">{{ item.desc }}</p>
<button class="item-button">查看详情</button>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HomeRecommend',
data () {
return {
recommendList: [
{
id: '0001',
imgUrl:
'http://img1.qunarzz.com/sight/p0/201404/23/04b92c99462687fa1ba45c1b5ba4ad77.jpg_140x140_73fda71d.jpg',
title: '大连圣亚海洋世界',
desc: '浪漫大连首站,浪漫的海洋主题乐园'
},
{
id: '0002',
imgUrl:
'http://img1.qunarzz.com/sight/p0/201404/23/04b92c99462687fa1ba45c1b5ba4ad77.jpg_140x140_73fda71d.jpg',
title: '大连圣亚海洋世界',
desc: '浪漫大连首站,浪漫的海洋主题乐园'
},
{
id: '0003',
imgUrl:
'http://img1.qunarzz.com/sight/p0/201404/23/04b92c99462687fa1ba45c1b5ba4ad77.jpg_140x140_73fda71d.jpg',
title: '大连圣亚海洋世界',
desc: '浪漫大连首站,浪漫的海洋主题乐园'
}
]
}
}
}
</script>
<style lang="scss" scoped>
.title {
line-height: 0.8rem;
background: #eee;
text-indent: 0.2rem;
margin-top: 0.2rem;
font-size: 0.32rem;
font-weight: 500;
}
.item {
overflow: hidden;
display: flex;
height: 1.9rem;
// background: red;
.item-img {
width: 1.7rem;
height: 1.7rem;
padding: 0.2rem;
}
.item-info {
flex: 1;
padding: 0.2rem;
// 让省略号显示出来
min-width: 0;
.item-title {
line-height: 0.54rem;
font-size: 0.32rem;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.item-desc {
line-height: 0.4rem;
color: #ccc;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.item-button {
line-height: 0.44rem;
margin-top: 0.16rem;
background: #ff9300;
padding: 0 0.2rem;
border-radius: 0.06rem;
color: #fff;
}
}
}
</style>
Weekend.vue组件
<template>
<div class="recommend">
<div class="title">周末去哪儿</div>
<ul>
<li
class="item border-bottom"
v-for="item in recommendList"
:key="item.id"
>
<!-- 防止网速慢的情况下抖动 -->
<div class="item-img-wrapper">
<img class="item-img" :src="item.imgUrl" />
</div>
<div class="item-info">
<p class="item-title">{{ item.title }}</p>
<p class="item-desc">{{ item.desc }}</p>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HomeWeekend',
data () {
return {
recommendList: [
{
id: '0001',
imgUrl:
'http://img1.qunarzz.com/sight/source/1505/9f/f585152825459.jpg_r_640x214_5d46e4cc.jpg',
title: '大连圣亚海洋世界',
desc: '浪漫大连首站,浪漫的海洋主题乐园'
},
{
id: '0002',
imgUrl:
'http://img1.qunarzz.com/sight/source/1505/9f/f585152825459.jpg_r_640x214_5d46e4cc.jpg',
title: '大连圣亚海洋世界',
desc: '浪漫大连首站,浪漫的海洋主题乐园'
},
{
id: '0003',
imgUrl:
'http://img1.qunarzz.com/sight/source/1505/9f/f585152825459.jpg_r_640x214_5d46e4cc.jpg',
title: '大连圣亚海洋世界',
desc: '浪漫大连首站,浪漫的海洋主题乐园'
}
]
}
}
}
</script>
<style lang="scss" scoped>
.title {
line-height: 0.8rem;
background: #eee;
text-indent: 0.2rem;
margin-top: 0.2rem;
font-size: 0.32rem;
font-weight: 500;
}
.item-img-wrapper {
overflow: hidden;
height: 0;
padding-bottom: 33.9%;
.item-img {
width: 100%;
}
}
.item-info {
padding: 0.2rem;
// 让省略号显示出来
min-width: 0;
.item-title {
line-height: 0.54rem;
font-size: 0.32rem;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.item-desc {
line-height: 0.4rem;
color: #ccc;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
</style>
效果如下:
ajax请求
Vue官方现在推荐我们使用axios请求接口,axios是基于promise的http请求客户端
使用npm安装axios
npm install axios
or
npm i axios
然后在要使用的组件Home.vue中引入axios
在static静态目录下创建接口的json数据。访问本地json的话,本地json必须放到static下面
在.gitignore里添加下static/mock,这样就不会提交到git仓库里
不要直接将static路由暴露,需要重定向,在config/index.js配置即可
如果配置文件发生改变,需要重新启动应用npm run dev
Home.vue
这里用到了父组件给子组件传值
<template>
<div>
<home-header :city="city"></home-header>
<home-swiper :list="swiperList"></home-swiper>
<home-icons :list="iconList"></home-icons>
<home-recommend :list="recommendList"></home-recommend>
<home-weekend :list="weekendList"></home-weekend>
</div>
</template>
<script>
// 局部组件需要插入到components中,由于键和值都是一样的,所以写成HomeHeader
import HomeHeader from './components/Header'
import HomeSwiper from './components/Swiper'
import HomeIcons from './components/Icons'
import HomeRecommend from './components/Recommend'
import HomeWeekend from './components/Weekend'
import axios from 'axios'
export default {
name: 'home',
data () {
return {
city: '',
swiperList: [],
iconList: [],
recommendList: [],
weekendList: []
}
},
components: {
HomeHeader,
HomeSwiper,
HomeIcons,
HomeRecommend,
HomeWeekend
},
methods: {
getHomeInfo () {
axios({
url: '/static/mock/index.json',
method: 'get'
}).then(this.getHomeInfoSucc)
},
getHomeInfoSucc (res) {
console.log(res)
res = res.data
if (res.ret && res.data) {
const data = res.data
this.city = data.city
this.swiperList = data.swiperList
this.iconList = data.iconList
this.recommendList = data.recommendList
this.weekendList = data.weekendList
}
}
},
// 钩子函数mounted
mounted () {
this.getHomeInfo()
}
}
</script>
<style></style>
Header.vue
<template>
<div class="header">
<div class="header-left">
<div class="iconfont back-icon"></div>
</div>
<div class="header-input">
<span class="iconfont"></span>
输入城市/景点/游玩主题
</div>
<div class="header-right">
{{this.city}}
<span class="iconfont arrow-icon"></span>
</div>
</div>
</template>
<script>
export default {
name: 'HomeHeader',
props: {
city: String
}
}
</script>
<style lang="scss" scoped>
// styles指的是webpack.base.conf.js中的 src/assets/styles路径的简写
@import '~styles/varibles.scss';
.header {
display: flex;
line-height: 0.86rem;
background-color: $bgColor;
color: #fff;
.header-left {
width: 0.64rem;
float: left;
.back-icon {
font-size: 0.4rem;
text-align: center;
}
}
.header-input {
flex: 1;
background: #fff;
border-radius: 0.1rem;
padding-left: 0.2rem;
margin-top: 0.12rem;
margin-left: 0.2rem;
height: 0.64rem;
line-height: 0.64rem;
color: #666;
}
.header-right {
width: 1.24rem;
float: right;
text-align: center;
.arrow-icon {
margin-left: -0.04rem;
font-size: 0.24rem;
}
}
}
</style>
Swiper.vue
<template>
<!-- 在swiper外面加上一层div,是为了防止在网速慢的情况下抖动的bug,用户体验不好 -->
<div class="warpper">
<!-- 解决轮播图默认在第一张 -->
<swiper :options="swiperOption" v-if="showSwiper">
<swiper-slide v-for="item in list" :key="item.id">
<img class="swiper-img" :src="item.imgUrl" />
</swiper-slide>
<!-- 用于分页 -->
<div class="swiper-pagination" slot="pagination"></div>
</swiper>
</div>
</template>
<script>
export default {
name: 'HomeSwiper',
// ES6 data后面要有空格
props: {
list: Array
},
data () {
return {
swiperOption: {
// 参数选项,显示小点
pagination: '.swiper-pagination',
// 循环轮播
loop: true,
// 每张播放时长1秒,自动播放
autoplay: 1000,
// 滑动速度
speed: 500
}
}
},
// 用计算属性,避免模板中有太多内容
computed: {
showSwiper () {
return this.list.length
}
}
}
</script>
<style lang="scss" scoped>
// 样式进行了穿透 只要warpper下出现swiper-pagination-bullet-active类名就变色
// 这样就不受scoped作用域的限制
.warpper >>> .swiper-pagination-bullet-active {
background-color: #fff !important;
}
.warpper {
overflow: hidden;
width: 100%;
height: 0;
padding-bottom: 31.25%;
background: #eee;
.swiper-img {
width: 100%;
}
}
</style>
Recommend.vue
<template>
<div class="recommend">
<div class="title">热销推荐</div>
<ul>
<li
class="item border-bottom"
v-for="item in list"
:key="item.id"
>
<img class="item-img" :src="item.imgUrl" />
<div class="item-info">
<p class="item-title">{{ item.title }}</p>
<p class="item-desc">{{ item.desc }}</p>
<button class="item-button">查看详情</button>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HomeWeekend',
props: {
list: Array
}
}
</script>
<style lang="scss" scoped>
.title {
line-height: 0.8rem;
background: #eee;
text-indent: 0.2rem;
margin-top: 0.2rem;
font-size: 0.32rem;
font-weight: 500;
}
.item {
overflow: hidden;
display: flex;
height: 1.9rem;
// background: red;
.item-img {
width: 1.7rem;
height: 1.7rem;
padding: 0.2rem;
}
.item-info {
flex: 1;
padding: 0.2rem;
// 让省略号显示出来
min-width: 0;
.item-title {
line-height: 0.54rem;
font-size: 0.32rem;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.item-desc {
line-height: 0.4rem;
color: #ccc;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.item-button {
line-height: 0.44rem;
margin-top: 0.16rem;
background: #ff9300;
padding: 0 0.2rem;
border-radius: 0.06rem;
color: #fff;
}
}
}
</style>
Weekend.vue
<template>
<div class="recommend">
<div class="title">周末去哪儿</div>
<ul>
<li class="item border-bottom" v-for="item in list" :key="item.id">
<!-- 防止网速慢的情况下抖动 -->
<div class="item-img-wrapper">
<img class="item-img" :src="item.imgUrl" />
</div>
<div class="item-info">
<p class="item-title">{{ item.title }}</p>
<p class="item-desc">{{ item.desc }}</p>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HomeWeekend',
props: {
list: Array
}
}
</script>
<style lang="scss" scoped>
.title {
line-height: 0.8rem;
background: #eee;
text-indent: 0.2rem;
margin-top: 0.2rem;
font-size: 0.32rem;
font-weight: 500;
}
.item-img-wrapper {
overflow: hidden;
height: 0;
padding-bottom: 37.09%;
.item-img {
width: 100%;
}
}
.item-info {
padding: 0.2rem;
// 让省略号显示出来
min-width: 0;
.item-title {
line-height: 0.54rem;
font-size: 0.32rem;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.item-desc {
line-height: 0.4rem;
color: #ccc;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
</style>
通过axios请求接口得到的效果如图: