(最详细)VueApp项目实战2 - - 首页制作
一、安装stylus1.stylus、less、sass三者的区别?三者都是CSS的预处理器,无需考虑浏览器的兼容性问题,可以在 CSS 中使用变量、简单的程序逻辑、函数等等在编程语言中的一些基本技巧,使CSS 更加简洁,不同的是写法上存在些差异;2.stylus的安装cd Travel#进入项目目录文件npm install stylus --save#安装stylusnpm install s
·
一、安装stylus
1.stylus、less、sass三者的区别?
三者都是CSS的预处理器,无需考虑浏览器的兼容性问题,可以在 CSS 中使用变量、简单的程序逻辑、函数等等在编程语言中的一些基本技巧,使CSS 更加简洁,不同的是写法上存在些差异;
2.stylus的安装
cd Travel
# 进入项目目录文件
npm install stylus --save
# 安装stylus
npm install stylus-loader --save
# 安装stylus的依赖包
npm run dev
# 运行项目
二、Ajax动态获取首页数据
1.安装axios
npm install axios --save
2.引入Ajax数据 - - - 编辑’Home.vue’
<template>
<!-- template只能向外暴露一个标签,所以需要在外面再套个盒子 -->
<div>
Home
</div>
</template>
<script>
// 引用'axios'获取'ajix'请求
import axios from 'axios'
export default {
name: 'Home'
},
// 所有数据
data () {
return {
city: '',
swiperList: [],
iconList: [],
recommendList: [],
weekendList: []
}
},
methods: {
getHomeInfo () {
// axios.get('/static/mock/index.json')
// 测试环境时候访问的本地'static/mock',上线时候访问的是'api'
axios.get('/api/index.json')
.then(this.getHomeInfoSucc)
},
getHomeInfoSucc (res) {
res = res.data
// 如果后端返回了数值,并且和data的数据相同
if (res.ret && res.data) {
// 定义一个'data'='res.data'
const data = res.data
// ajix里面的'data.city'传给了'city'
this.city = data.city
// swiperList里面的数据进行传输
this.swiperList = data.swiperList
// iconList里面的数据进行传输
this.iconList = data.iconList
// recommendList里面的数据进行传输
this.recommendList = data.recommendList
// weekendList里面的数据进行传输
this.weekendList = data.weekendList
}
// console.log(res)
}
},
mounted () {
this.getHomeInfo()
}
}
</script>
<style>
</style>
3.创建本地模拟数据
a. 新建’mock’ 文件夹和 'index.json’文件(路径: src/static/mock/index.json)
{
"ret": true,
"data": {
"city":"北京",
"swiperList": [{
"id": "0001",
"imgUrl": "http://img1.qunarzz.com/piao/fusion/1801/1a/94428c6dea109402.jpg_640x200_2cf590d8.jpg"
},{
"id": "0002",
"imgUrl": "http://img1.qunarzz.com/piao/fusion/1802/42/7c92b9a381e46402.jpg_640x200_1cdce2a4.jpg"
},{
"id": "0003",
"imgUrl": "http://img1.qunarzz.com/piao/fusion/1802/51/e78f936a5b404102.jpg_640x200_c14f0b3a.jpg"
},{
"id": "0004",
"imgUrl": "http://img1.qunarzz.com/piao/fusion/1712/91/a275569091681d02.jpg_640x200_0519ccb9.jpg"
}],
"iconList": [{
"id": "0001",
"imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/54/ace00878a52d9702.png",
"desc": "景点门票"
}, {
"id": "0002",
"imgUrl": "http://img1.qunarzz.com/piao/fusion/1711/df/86cbcfc533330d02.png",
"desc": "滑雪季"
}, {
"id": "0003",
"imgUrl": "http://img1.qunarzz.com/piao/fusion/1710/a6/83f636bd75ae6302.png",
"desc": "泡温泉"
}, {
"id": "0004",
"imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/35/2640cab202c41b02.png",
"desc": "动植园"
}, {
"id": "0005",
"imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/d0/e09575e66f4aa402.png",
"desc": "游乐园"
}, {
"id": "0006",
"imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/59/569d3c096e542502.png",
"desc": "必游榜单"
}, {
"id": "0007",
"imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/17/4bd370f3eb1acd02.png",
"desc": "演出"
}, {
"id": "0008",
"imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/7f/b1ea3c8c7fb6db02.png",
"desc": "城市观光"
}, {
"id": "0009",
"imgUrl": "http://img1.qunarzz.com/piao/fusion/1611/a9/ffc620dbda9b9c02.png",
"desc": "一日游"
}],
"recommendList": [{
"id": "0001",
"imgUrl": "http://img1.qunarzz.com/sight/p0/1409/19/adca619faaab0898245dc4ec482b5722.jpg_140x140_80f63803.jpg",
"title": "故宫",
"desc": "东方宫殿建筑代表,世界宫殿建筑典范"
}, {
"id": "0002",
"imgUrl": "http://img1.qunarzz.com/sight/p0/1511/d2/d2aec2dfc5aa771290.water.jpg_140x140_abb362a7.jpg",
"title": "南山滑雪场",
"desc": "北京专业级滑雪圣地"
}, {
"id": "0003",
"imgUrl": "http://img1.qunarzz.com/sight/p0/1501/f4/f467729126949c3a.water.jpg_140x140_ef235b1c.jpg",
"title": "天安门广场",
"desc": "我爱北京天安门,天安门上太阳升"
}, {
"id": "0004",
"imgUrl": "http://img1.qunarzz.com/sight/p0/1501/40/40b2b6c951b28fdd.water.jpg_140x140_1c863e5c.jpg",
"title": "水立方",
"desc": "中国的荣耀,阳光下的晶莹水滴"
}, {
"id": "0005",
"imgUrl": "http://img1.qunarzz.com/sight/p0/201308/23/b283071686e64dfec8d65eac.jpg_140x140_8c5a7c49.jpg",
"title": "温都水城养生馆",
"desc": "各种亚热带植物掩映其间仿佛置身热带雨林"
}],
"weekendList": [{
"id": "0001",
"imgUrl": "http://img1.qunarzz.com/sight/source/1510/6e/1ea71e2f04e.jpg_r_640x214_aa6f091d.jpg",
"title": "北京温泉排行榜",
"desc": "细数北京温泉,温暖你的冬天"
}, {
"id": "0002",
"imgUrl": "http://img1.qunarzz.com/sight/source/1505/aa/7baaf8a851d221.jpg_r_640x214_1431200f.jpg",
"title": "北京必游TOP10",
"desc": "来北京必去的景点非这些地方莫属"
}, {
"id": "0003",
"imgUrl": "http://img1.qunarzz.com/sight/source/1505/9e/21df651e19af5d.jpg_r_640x214_3ea5bb38.jpg",
"title": "寻找北京的皇城范儿",
"desc": "数百年的宫廷庙宇,至今依旧威严霸气"
}, {
"id": "0004",
"imgUrl": "http://img1.qunarzz.com/sight/source/1505/ce/bc89bc2f0e33ea.jpg_r_640x214_3e408453.jpg",
"title": "学生最爱的博物馆",
"desc": "周末干嘛?北京很多博物馆已经免费开放啦"
}, {
"id": "0005",
"imgUrl": "http://img1.qunarzz.com/sight/source/1505/b2/fde1bfcd057a52.jpg_r_640x214_bbf3fa44.jpg",
"title": "儿童剧场,孩子的乐园",
"desc": "带宝贝观看演出,近距离体验艺术的无穷魅力"
}]
}
}
b. 编辑’.gitignore’文件 - - - 不希望该文件内容提交到线上
.DS_Store
node_modules/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# 不会被提交到线上的仓库里
static/mock
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
c. 编辑’index.js’文件(路径: fonfig/index.js) - - - 实现开发环境的路径替换
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
// 配置项 修改访问时候的路径地址
proxyTable: {
'/api': {
// 请求转发到服务器的8080端口上
target: 'http://localhost:8080',
// 替换路径
pathRewrite: {
'^/api': '/static/mock'
}
}
},
三、组件化开发
该页面可分为’Header’、‘Swiper’、‘Icons’、‘Recommend’、'Weekend’五个组件组成
四、定义全局变量、方法、目录别名
1.创建’varibles.styl’文件 (路径: src/assets/styles/varibles.styl)
// 主题色
$bgColor = #00bcd4
// 正文字体
$darkTextColor = #333
// header高度
$headerHight = .86rem
2.创建’mixins.styl’文件 (路径: src/assets/styles/mixins.styl)
// 实现文字溢出的方法
ellipsis()
overflow hidden
white-space nowrap
text-overflow ellipsis
3.编辑’webpack.base.conf.js’文件 (路径: build/webpack.base.conf.js)
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
}
改为
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
// 自定义地添加'styles'的目录名称
'styles': resolve('src/assets/styles')
}
}
五、Header
1.创建’Header.vue’文件
a. 新建’components’、'home’文件夹(路径: src/pages/home/components/Header.vue)
b. 创建’Header.vue’文件
<template>
<div class="Header">
Header
</div>
</template>
<script>
export default {
name: 'HomeHeader'
}
</script>
<style scoped>
</style>
c. 引用’Header.vue’组件
编辑’Home.vue’文件
<template>
<!-- template只能向外暴露一个标签,所以需要在外面再套个盒子 -->
<div>
<home-header :city="city"></home-header>
</div>
</template>
<script>
// 引用Header组件
import HomeHeader from './components/Header'
// 引用'axios'获取'ajix'请求
import axios from 'axios'
export default {
name: 'Home',
// 将注册的组件引用到home中来
components: {
HomeHeader
},
// 所有数据
data () {
return {
city: ''
}
},
methods: {
getHomeInfo () {
// axios.get('/static/mock/index.json')
// 测试环境时候访问的本地'static/mock',上线时候访问的是'api'
axios.get('/api/index.json')
.then(this.getHomeInfoSucc)
},
getHomeInfoSucc (res) {
res = res.data
// 如果后端返回了数值,并且和data的数据相同
if (res.ret && res.data) {
// 定义一个'data'='res.data'
const data = res.data
// ajix里面的'data.city'传给了'city'
this.city = data.city
}
// console.log(res)
}
},
mounted () {
this.getHomeInfo()
}
}
</script>
<style>
</style>
d. 编写’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>
<!-- 实现页面跳转 -->
<router-link to='/city'>
<div class="header-right">
<!-- 城市 -->
{{this.city}}
<span class="iconfont arrow-icon"></span>
</div>
</router-link>
</div>
</template>
<script>
export default {
name: 'HomeHeader',
// 子组件接收传值
props: {
// 切记string要大写,string是字符串的形式
city: String
}
}
</script>
// 运用'stylus'来编写css样式 'scoped'用来限制'style'里面的.header等样式只对当前组件有效
<style lang="stylus" scoped>
// 用'~'引用变量的样式
@import '~styles/varibles'
// @import '../../../assets/styles/varibles' @代表src目录 css中引用其他css样式需要用到'~'
.header
display: flex
line-height: $headerHight
color: #fff
background-color: $bgColor
// background-color: #00bcd4
.header-left
// 'reste.css'中 1rem = html font-size 50px
width: .64rem
float: left
.back-icon
text-align center
font-size .6rem
.header-input
flex: 1
margin-top: .12rem
margin-left: .2rem
padding-left .2rem
height: .64rem
line-height: .64rem
color: #ccc
border-radius: .1rem
background: #fff
.header-right
width: 1.24rem
float: right
text-align: center
// 修改字体颜色
color #fff
.arrow-icon
margin-left -.1rem
font-size .4rem
</style>
五、Swiper
1.创建’Swiper.vue’文件
a. 创建’Swiper.vue’文件
<template>
<div class="Swiper">
Swiper
</div>
</template>
<script>
export default {
name: 'HomeSwiper'
}
</script>
<style scoped>
</style>
b. 引用’Swiper.vue’组件
编辑’Home.vue’文件
<template>
<!-- template只能向外暴露一个标签,所以需要在外面再套个盒子 -->
<div>
<!-- 引用HomeHeader组件 -->
<home-header :city="city"></home-header>
<home-swiper :list='swiperList'></home-swiper>
</div>
</template>
<script>
import HomeHeader from './components/Header'
// 引用轮播图组件
import HomeSwiper from './components/Swiper'
// 引用'axios'获取'ajix'请求
import axios from 'axios'
export default {
name: 'Home',
// 将注册的组件引用到home中来
components: {
HomeHeader,
HomeSwiper
},
// 所有数据
data () {
return {
city: '',
swiperList: []
}
},
methods: {
getHomeInfo () {
// axios.get('/static/mock/index.json')
// 测试环境时候访问的本地'static/mock',上线时候访问的是'api'
axios.get('/api/index.json')
.then(this.getHomeInfoSucc)
},
getHomeInfoSucc (res) {
res = res.data
// 如果后端返回了数值,并且和data的数据相同
if (res.ret && res.data) {
// 定义一个'data'='res.data'
const data = res.data
// ajix里面的'data.city'传给了'city'
this.city = data.city
// swiperList里面的数据进行传输
this.swiperList = data.swiperList
}
// console.log(res)
}
},
mounted () {
this.getHomeInfo()
}
}
</script>
<style>
</style>
c. 安装轮播图插件
npm install vue-awesome-swiper@2.6.7 --save
# 安装的2.6.7版本
d. 导入轮播图插件 - - - 编辑’main.js’(路径: src/main.js)
// 引用轮播图插件
import VueAwesomeSwiper from 'vue-awesome-swiper'
// 引用轮播图插件的css样式
import 'swiper/dist/css/swiper.css'
// 用轮播图插件
Vue.use(VueAwesomeSwiper)
d. 编写’Swiper.vue’样式
<template>
<div class="wrapper">
<!-- 直接引用轮播图插件 -->
<!-- 'v-if'是为了初次创建由完整的数组来创建,而不是空数组来创建(轮播图第一页不是默认的) -->
<!-- <swiper :options="swiperOption" v-if="list.length"> 这种写法不够优雅,模板中不要涉及计算公式 -->
<swiper :options="swiperOption" v-if="showSwiper">
<!-- slides -->
<!-- 轮播图样例 -->
<!-- <swiper-slide>I'm Slide 1</swiper-slide> -->
<!-- <swiper-slide v-for="item of swiperList" :key="item.id"> -->
<swiper-slide v-for="item of list" :key="item.id">
<img class='swiper-img' :src="item.imgUrl">
</swiper-slide>
<!-- Optional controls -->
<div class="swiper-pagination" slot="pagination">
</div>
<!-- 左侧按钮 -->
<!-- <div class="swiper-button-prev" slot="button-prev"></div> -->
<!-- 右侧按钮 -->
<!-- <div class="swiper-button-next" slot="button-next"></div> -->
<!-- 滚动条 -->
<!-- <div class="swiper-scrollbar" slot="scrollbar"></div> -->
</swiper>
</div>
</template>
<script>
export default {
name: 'HomeSwiper',
props: {
// 数组格式,首字母大写
list: Array
},
// 子组件里面定义data,data需要是一个函数--data: function ()--es6可以简写 需要在data里面定义一个'template'了的变量'swiperOption'
data () {
return {
swiperOption: {
// 填写分页内容
pagination: '.swiper-pagination',
loop: true
}
// ,
// swiperList: [
// {id: '0001', imgUrl: 'https://imgs.qunarzz.com/vs_ceph_vcimg/569cae4ae98e9793f7341e85eed73c54.jpeg'
// },
// {id: '0002', imgUrl: 'https://imgs.qunarzz.com/vs_ceph_vcimg/f7813c9431796cc32ae7b7a78447342e.jpeg'
// },
// {id: '0003', imgUrl: 'https://imgs.qunarzz.com/vs_ceph_vcimg/1cfbdaa2682ada2f854ea6114b3677c8.jpeg'
// },
// {id: '0004', imgUrl: 'https://imgs.qunarzz.com/vs_ceph_vcimg/f03f5ac90ae59d0d9c6332a2bfd9782e.jpeg'
// },
// {id: '0005', imgUrl: 'https://imgs.qunarzz.com/vs_ceph_vcimg/b8c4527c41649814cc4cf86880abba54.jpeg'
// }
// ]
}
},
// 创建了个计算公式,可以被引用
computed: {
showSwiper () {
return this.list.length
}
}
}
</script>
<style lang="stylus" scoped>
.wrapper >>> .swiper-pagination-bullet-active
background #fff
.wrapper
width 100%
// height 31.25vm
overflow hidden
height 0
// 图片宽高比例未 100:31.25
padding-bottom 30.47%
background #f5f5f5
// scoped决定了不会影响到其他组件的样式,需要改变的是wrapper的组件样式
// .swiper-pagination-bullet-active
// background:red !imprtant
.swiper-img
width: 100%
</style>
六、Icons
1.创建’Icons.vue’文件
a. 创建’Icons.vue’文件
<template>
<div class="Icons">
Swiper
</div>
</template>
<script>
export default {
name: 'HomeIcons'
}
</script>
<style scoped>
</style>
b. 引用’Icons.vue’组件
编辑’Home.vue’文件
<template>
<!-- template只能向外暴露一个标签,所以需要在外面再套个盒子 -->
<div>
<!-- 引用HomeHeader组件 -->
<home-header :city="city"></home-header>
<home-swiper :list='swiperList'></home-swiper>
<home-icons :list='iconList'></home-icons>
</div>
</template>
<script>
import HomeHeader from './components/Header'
// 引用轮播图组件
import HomeSwiper from './components/Swiper'
// 引用icon(金刚区)组件
import HomeIcons from './components/Icons'
// 引用'axios'获取'ajix'请求
import axios from 'axios'
export default {
name: 'Home',
// 将注册的组件引用到home中来
components: {
HomeHeader,
HomeSwiper,
HomeIcons
},
// 所有数据
data () {
return {
city: '',
swiperList: [],
iconList: []
}
},
methods: {
getHomeInfo () {
// axios.get('/static/mock/index.json')
// 测试环境时候访问的本地'static/mock',上线时候访问的是'api'
axios.get('/api/index.json')
.then(this.getHomeInfoSucc)
},
getHomeInfoSucc (res) {
res = res.data
// 如果后端返回了数值,并且和data的数据相同
if (res.ret && res.data) {
// 定义一个'data'='res.data'
const data = res.data
// ajix里面的'data.city'传给了'city'
this.city = data.city
// swiperList里面的数据进行传输
this.swiperList = data.swiperList
// iconList里面的数据进行传输
this.iconList = data.iconList
}
// console.log(res)
}
},
mounted () {
this.getHomeInfo()
}
}
</script>
<style>
</style>
c. 编写’Icons.vue’样式
<template>
<div class="icons">
<swiper :options="swiperOption">
<swiper-slide
v-for="(page, index) of pages"
:key="index"
>
<!--不再循环iconList了,循环的是pages-->
<div
class="icon"
v-for="item of page"
:key="item.id"
>
<div class="icon-img">
<img class="icon-img-content" :src="item.imgUrl">
</div>
<p class="icon-desc">{{item.desc}}</p>
</div>
</swiper-slide>
</swiper>
</div>
</template>
<script>
export default {
name: 'HomeIcons',
props: {
list: Array
},
data () {
return {
swiperOption: {
autoplay: false
}
}
},
// data () {
// return {
// iconList: [{
// id: '0001',
// imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/piao.png',
// desc: '景点门票'
// },
// {
// id: '0002',
// imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/package.png',
// desc: '度假'
// },
// {
// id: '0003',
// imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/train.png',
// desc: '火车票'
// },
// {
// id: '0004',
// imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/flight.png',
// desc: '机票'
// },
// {
// id: '0005',
// imgUrl: 'https://s.qunarzz.com/homenode/images/touchheader/hotel.png',
// desc: '酒店'
// },
// {
// id: '0006',
// imgUrl: 'https://picbed.qunarzz.com/f5e5770393d759578962e53ee67798c8.png',
// desc: '海外酒店'
// },
// {
// id: '0007',
// imgUrl: 'https://picbed.qunarzz.com/a36d2288f19e54562338f4d8ef986288.png',
// desc: '特价机票'
// },
// {
// id: '0008',
// imgUrl: 'https://picbed.qunarzz.com/1316dc82d1ce6259686d5a68880e5a9d.png',
// desc: '攻略'
// },
// {
// id: '0009',
// imgUrl: 'https://picbed.qunarzz.com/ae617a31e0bd5803d76918b817f6d942.png',
// desc: '自由行'
// },
// {
// id: '0010',
// imgUrl: 'https://picbed.qunarzz.com/377db8cb2143aebf01869c9baad3d325.png',
// desc: '汽车票'
// }]
// }
// },
// 添加一个计算属性,实现对金刚区的图标做一个轮播效果
computed: {
// 定义一个函数
pages () {
// 定义一个数组
const pages = []
// 将iconList循环一遍,可以获取到两个数据'循环项'和它对应的'下标'
// this.iconList.forEach((item, index) => {
this.list.forEach((item, index) => {
// 定义一个'page',代表页数,如果下标数 小于等于 8,page = 0,在第0页
const page = Math.floor(index / 8)
if (!pages[page]) {
pages[page] = []
}
pages[page].push(item)
})
return pages
}
}
}
</script>
<style lang='stylus' scoped>
@import '~styles/varibles.styl'
@import '~styles/mixins.styl'
.icons >>> .swiper-container
// overflow hidden
height 0
padding-bottom 50%
// background red
.icons
margin-top .1rem
.icon
position relative
overflow hidden
float left
width 25%
height 0
padding-bottom 25%
// background green
.icon-img
position absolute
left 0
right 0
top 0
bottom .44rem
box-sizing border-box
padding .1rem
// background blue
.icon-img-content
display block
margin 0 auto
height 100%
.icon-desc
position absolute
left 0
right 0
bottom 0
height .44rem
line-height .44rem
text-align center
color $darkTextColor
ellipsis()
</style>
七、Recommend
1.创建’Recommend.vue’文件
a. 创建’Recommend.vue’文件
<template>
<div class="Recommend">
Recommend
</div>
</template>
<script>
export default {
name: 'HomeRecommend'
}
</script>
<style scoped>
</style>
b. 引用’Recommend.vue’组件
编辑’Home.vue’文件
<template>
<!-- template只能向外暴露一个标签,所以需要在外面再套个盒子 -->
<div>
<!-- 引用HomeHeader组件 -->
<home-header :city="city"></home-header>
<home-swiper :list='swiperList'></home-swiper>
<home-icons :list='iconList'></home-icons>
<home-recommend :list='recommendList'></home-recommend>
</div>
</template>
<script>
import HomeHeader from './components/Header'
// 引用轮播图组件
import HomeSwiper from './components/Swiper'
// 引用icon(金刚区)组件
import HomeIcons from './components/Icons'
// 引用热销推荐
import HomeRecommend from './components/Recommend'
// 引用'axios'获取'ajix'请求
import axios from 'axios'
export default {
name: 'Home',
// 将注册的组件引用到home中来
components: {
HomeHeader,
HomeSwiper,
HomeIcons,
HomeRecommend
},
// 所有数据
data () {
return {
city: '',
swiperList: [],
iconList: [],
recommendList: []
}
},
methods: {
getHomeInfo () {
// axios.get('/static/mock/index.json')
// 测试环境时候访问的本地'static/mock',上线时候访问的是'api'
axios.get('/api/index.json')
.then(this.getHomeInfoSucc)
},
getHomeInfoSucc (res) {
res = res.data
// 如果后端返回了数值,并且和data的数据相同
if (res.ret && res.data) {
// 定义一个'data'='res.data'
const data = res.data
// ajix里面的'data.city'传给了'city'
this.city = data.city
// swiperList里面的数据进行传输
this.swiperList = data.swiperList
// iconList里面的数据进行传输
this.iconList = data.iconList
// recommendList里面的数据进行传输
this.recommendList = data.recommendList
}
// console.log(res)
}
},
mounted () {
this.getHomeInfo()
}
}
</script>
<style>
</style>
c. 编写’Recommend.vue’样式
<template>
<div>
<div class="title">热销推荐</div>
<ul>
<li>
<!-- 底部增加1px边框 -->
<!-- v-for="item of recommendList" -->
<div
class="item border-bottom"
v-for="item of 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>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HomeRecommend',
props: {
list: Array
}
// data () {
// return {
// recommendList: [{
// id: '0001',
// imgUrl: 'https://imgs.qunarzz.com/vs_ceph_vs_tts/9608dc40-1209-4b9d-a73f-1030d1f351fe.gif',
// title: '武汉-昆明 9天跟团游',
// desc: '9天深度游云南|昆大丽版纳体验升级:省内1动1飞|吉普跟拍+雨林野象谷+雪山'
// },
// {
// id: '0002',
// imgUrl: 'https://imgs.qunarzz.com/vs_ceph_b2c_001/8a089740-f383-4210-88cf-6d7c61475304.jpg_r_480x320x95_23b8204f.jpg',
// title: '武汉-恩施 3天跟团游',
// desc: '免票进行时|腾龙洞|夷水丽川|科技激光秀|恩施黄鹤峰林大峡谷|土司城|女儿城'
// },
// {
// id: '0003',
// imgUrl: 'https://imgs.qunarzz.com/vs_ceph_b2c_001/fda85184-bdbe-45e8-80c7-1c2574922d10.jpg_r_480x320x95_7b5db4d1.jpg',
// title: '武汉-武汉欢乐谷 1天跟团游',
// desc: '旅行者:惠游湖北纯玩无购物(金龙水寨+汤池温泉)含导游门票'
// },
// {
// id: '0004',
// imgUrl: 'https://imgs.qunarzz.com/p/tts9/1711/e5/2033e06bdda7cb02.jpg_r_480x320x95_1c9f89aa.jpg',
// title: '武汉-宜昌 2天跟团游',
// desc: '冬季滑雪♥真纯玩🔥神农架精华二日游📣情人泉+昭君别院✔赠雪鞋+雪板+雪仗'
// }]
// }
// }
}
</script>
<style lang="stylus" scoped>
@import '~styles/mixins.styl';
.title
margin-top .2rem
line-height .8rem
background #eee
// 首航缩进
text-indent .2rem
.item
overflow hidden
display flex
height 1.9rem
backgroud red
.item-img
width 1.7rem
height 1.7rem
padding .1rem
.item-info
flex 1
padding .1rem
// 限定最小宽度,实现文字溢出效果
min-width 0
.item-title
line-height .54rem
font-size .32rem
ellipsis()
.item-desc
line-height .4rem
color #ccc
ellipsis()
.item-button
line-height .44rem
color #fff
margin-top .2rem
padding 0 .2rem
border-radius .6rem
background #ff9300
</style>
八、Weekend
1.创建’Weekend.vue’文件
a. 创建’Weekend.vue’文件
<template>
<div class="Weekend">
Weekend
</div>
</template>
<script>
export default {
name: 'HomeWeekend'
}
</script>
<style scoped>
</style>
b. 引用’Weekend.vue’组件
编辑’Home.vue’文件
<template>
<!-- template只能向外暴露一个标签,所以需要在外面再套个盒子 -->
<div>
<!-- 引用HomeHeader组件 -->
<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>
import HomeHeader from './components/Header'
// 引用轮播图组件
import HomeSwiper from './components/Swiper'
// 引用icon(金刚区)组件
import HomeIcons from './components/Icons'
// 引用热销推荐
import HomeRecommend from './components/Recommend'
// 引用周末去哪儿
import HomeWeekend from './components/Weekend'
// 引用'axios'获取'ajix'请求
import axios from 'axios'
export default {
name: 'Home',
// 将注册的组件引用到home中来
components: {
HomeHeader,
HomeSwiper,
HomeIcons,
HomeRecommend,
HomeWeekend
},
// 所有数据
data () {
return {
city: '',
swiperList: [],
iconList: [],
recommendList: [],
weekendList: []
}
},
methods: {
getHomeInfo () {
// axios.get('/static/mock/index.json')
// 测试环境时候访问的本地'static/mock',上线时候访问的是'api'
axios.get('/api/index.json')
.then(this.getHomeInfoSucc)
},
getHomeInfoSucc (res) {
res = res.data
// 如果后端返回了数值,并且和data的数据相同
if (res.ret && res.data) {
// 定义一个'data'='res.data'
const data = res.data
// ajix里面的'data.city'传给了'city'
this.city = data.city
// swiperList里面的数据进行传输
this.swiperList = data.swiperList
// iconList里面的数据进行传输
this.iconList = data.iconList
// recommendList里面的数据进行传输
this.recommendList = data.recommendList
// weekendList里面的数据进行传输
this.weekendList = data.weekendList
}
// console.log(res)
}
},
mounted () {
this.getHomeInfo()
}
}
</script>
<style>
</style>
c. 编写’Recommend.vue’样式
<template>
<div>
<div class="title">热销推荐</div>
<ul>
<li>
<!-- 底部增加1px边框 -->
<!-- v-for="item of recommendList" -->
<div
class="item border-bottom"
v-for="item of 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>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HomeRecommend',
props: {
list: Array
}
// data () {
// return {
// recommendList: [{
// id: '0001',
// imgUrl: 'https://imgs.qunarzz.com/vs_ceph_vs_tts/9608dc40-1209-4b9d-a73f-1030d1f351fe.gif',
// title: '武汉-昆明 9天跟团游',
// desc: '9天深度游云南|昆大丽版纳体验升级:省内1动1飞|吉普跟拍+雨林野象谷+雪山'
// },
// {
// id: '0002',
// imgUrl: 'https://imgs.qunarzz.com/vs_ceph_b2c_001/8a089740-f383-4210-88cf-6d7c61475304.jpg_r_480x320x95_23b8204f.jpg',
// title: '武汉-恩施 3天跟团游',
// desc: '免票进行时|腾龙洞|夷水丽川|科技激光秀|恩施黄鹤峰林大峡谷|土司城|女儿城'
// },
// {
// id: '0003',
// imgUrl: 'https://imgs.qunarzz.com/vs_ceph_b2c_001/fda85184-bdbe-45e8-80c7-1c2574922d10.jpg_r_480x320x95_7b5db4d1.jpg',
// title: '武汉-武汉欢乐谷 1天跟团游',
// desc: '旅行者:惠游湖北纯玩无购物(金龙水寨+汤池温泉)含导游门票'
// },
// {
// id: '0004',
// imgUrl: 'https://imgs.qunarzz.com/p/tts9/1711/e5/2033e06bdda7cb02.jpg_r_480x320x95_1c9f89aa.jpg',
// title: '武汉-宜昌 2天跟团游',
// desc: '冬季滑雪♥真纯玩🔥神农架精华二日游📣情人泉+昭君别院✔赠雪鞋+雪板+雪仗'
// }]
// }
// }
}
</script>
<style lang="stylus" scoped>
@import '~styles/mixins.styl';
.title
margin-top .2rem
line-height .8rem
background #eee
// 首航缩进
text-indent .2rem
.item
overflow hidden
display flex
height 1.9rem
backgroud red
.item-img
width 1.7rem
height 1.7rem
padding .1rem
.item-info
flex 1
padding .1rem
// 限定最小宽度,实现文字溢出效果
min-width 0
.item-title
line-height .54rem
font-size .32rem
ellipsis()
.item-desc
line-height .4rem
color #ccc
ellipsis()
.item-button
line-height .44rem
color #fff
margin-top .2rem
padding 0 .2rem
border-radius .6rem
background #ff9300
</style>
更多推荐
已为社区贡献7条内容
所有评论(0)