Vue-cli搭建移动端项目
程序员文章站
2024-03-14 10:10:22
...
Vue-cli搭建移动端项目
项目介绍
1.仿照去哪儿 APP做的移动端项目
2.可以进行移动端的屏幕适配
3.使用Vue脚手架工具和webpack打包工具构建项目
4.使用预处理语言less编写部分css样式
5.使用iview框架实现轮播图效果以及各种图标的引用
6.使用Vuex以及Vuerouter实现组件与组件之间的通信
7.使用了axios技术请求数据资源
项目目录结构
组件目录
首页界面效果
- 搜索栏组件
<template>
<div id="pageHeader">
<div class="head-l"><Icon type="ios-arrow-back" id="backIcon"/></div>
<div>
<input type="text" class="head-c" placeholder="请输入景点/城市/游玩主题"></input>
</div>
<div class="head-r">
<!-- <router-link> 标签-->
<router-link to="/selCity">{{this.$store.state.city}}<Icon type="md-arrow-dropdown" id="dropIcon" />
</router-link>
</div>
</div>
</template>
<script>
export default({
name:'pageHeader',
data:function(){
return{
name:'去哪儿'
}
}
})
</script>
- 轮播图组件使用iview框架实现
<template>
<div id="banner">
<Carousel v-model="value1" loop :radius-dot="radiusDot" :autoplay="autoplay"
:autoplay-speed="autoplaySpeed">
<CarouselItem>
<img src="../common/images/banner1.jpg" alt="">
</CarouselItem>
<CarouselItem>
<img src="../common/images/banner2.jpg" alt="">
</CarouselItem>
<CarouselItem>
<img src="../common/images/banner3.jpg" alt="">
</CarouselItem>
<CarouselItem>
<img src="../common/images/banner4.jpg" alt="">
</CarouselItem>
</Carousel>
</div>
</template>
<script>
export default({
name:'banner',
data:function(){
return{
value1:0,
height:"100px",
radiusDot:true,
autoplay: true,
autoplaySpeed: 2000,
repara:'',
}
},
props:['para'],
mounted:function(){
console.log(this.para);
}
})
</script>
<style lang="less" scoped>
.h(@px){
height:unit(@px/37.5,rem);
}
.w(@px){
width:unit(@px/37.5,rem);
}
.marginTop(@top){
margin-top:unit(@top/37.5,rem);
}
#banner{
.w(375);
.h(100);
img{
.w(375);
.h(100);
}
}
</style>
- “猜你喜欢”组件使用axios发送请求并将获得的数据渲染进DOM层中
<template>
<div id="guessYouLike">
<div class="like-top">
<img src="http://img1.qunarzz.com/piao/fusion/1711/89/ebc329f16c55bb02.png" alt="">
<span>猜你喜欢</span>
</div>
<div class="like-list">
<router-link :to="'/single/'+list.name" class="like-list-item" v-for="list in lists" tag="div">
<div class="left">
<img v-bind:src="list.img" class="picBig">
<div v-if="list.type==1">
<div class="picSmall-type1">随买随用</div>
</div>
<div v-else-if="list.type==2">
<div class="picSmall-type2">可定明日</div>
</div>
</div>
<div class="right">
<div class="desc">
<p class="name">{{list.name}}</p>
<p>
<span class="level">
<Rate allow-half disabled v-model="list.level" class="rate">
</Rate>
</span>
<span class="comment">{{list.commNum}}条评论</span>
</p>
<p class="price">¥<span class="priceCon">{{list.price}}</span>起</p>
</div>
<div class="area">{{list.address}}</div>
<div class="bottom">{{list.desc}}</div>
</div>
</router-link>
</div>
<div class="like-more">
<a href="#" title="">查看所有产品</a>
</div>
</div>
</template>
<script>
export default({
data:function(){
return{
valueCustomText:5,
lists:[],
}
},
mounted:function(){
var url="http://localhost:8080/static/guessyoulike.json"
this.$axios.get(url,{})
.then((res)=>{
//console.log(res);//此时得到的数据是经过拦截器初步处理过的
this.lists=res.data.guessyoulikeLists;
})
.catch((err)=>{
console.log(err);
})
}
})
</script>
- “周末去哪”组件使用axios发送请求并将获得的数据渲染进DOM层中
<template>
<div id="weekendGo">
<div class="weekend-title" ref="go">周末去哪儿</div>
<div class="weekend-list">
<div class="weekend-list-item" v-for="list in lists">
<a href="#">
<img v-bind:src="list.img" alt="">
<p class="item-topic">{{list.title}}</p>
<p class="item-desc">{{list.desc}}</p>
</a>
</div>
</div>
</div>
</template>
<script>
export default({
name:'weekengGo',
data:function(){
return{
message:'hello',
lists:[],
}
},
mounted:function(){
var url="http://localhost:8080/static/guessyoulike.json"
this.$axios.get(url,{})
.then((res)=>{
//console.log(res);//此时得到的数据是经过拦截器初步处理过的
this.lists=res.data.weekendgowhereLists;
})
.catch((err)=>{
console.log(err);
})
}
})
</script>
详情页面效果
- 点击“猜你喜欢”中的选项会跳转到详情界面。(使用Vuerouter来传参,通过this.$router.paramName来获取参数从而动态加载详情界面 )
详情页代码主要是引入多个组件
<template>
<div id="single">
<singleBanner></singleBanner>
<weekRefereer></weekRefereer>
<activity></activity>
</div>
</template>
<script>
import singleBanner from 'components/singles/singleBanner.vue'
import weekRefereer from 'components/singles/weekReferee.vue'
import activity from 'components/singles/activity.vue'
export default({
name:'single',
components:{singleBanner,weekRefereer,activity},
mounted:function(){
},
//当从缓存中读取数据时触发该生命周期函数
activated:function(){
console.log(this.$route.params.sightName);
}
})
</script>
核心组件部分(使用keep-alive组件实现从缓存中读取数据)
//在APP.vue中添加<keep-alive>组件
<template>
<div id="app">
<!-- 从缓存中读取数据 -->
<keep-alive>
<router-view/><!-- 路由匹配到的组件将渲染在这里 -->
</keep-alive>
</div>
</template>
<template>
<div id="single">
<div class="single_title" ref="single_title">
<div @click="sel(item)" class="title" v-for="item in selItems" :class=" item==activeItem?'active':'' ">{{item}}</div>
</div>
<div class="single_con">
<div class="single_con_item" v-for="item in achorLinks" :ref="item.name">
<div v-for="content1 in item.con">
<div class="itemTitle" >
<Icon type="ios-paper" id="ticketIcon" />
<span>{{content1.name2}}</span>
</div>
<div v-for="content2 in content1.con">
<div class="itemTitle" @click="content2.state=!content2.state">
{{content2.name3}}
<span class="price">¥78</span>
<span v-if="!content2.state"><Icon type="ios-arrow-down" class="down" /></span>
<span v-else-if="content2.state"><Icon type="ios-arrow-up" class="down" /></span>
</div>
<div class="itemCon" v-if="content2.state">
<div class="weekList-item">
<div class="left">
<p class="ticket">天津方特欢乐世界成人夜场门票</p>
<p class="time"><img src="https://img1.qunarzz.com/piao/fusion/1804/25/792e9929973a9902.png" alt="">可定9月7日</p>
<span class="tip">条件退</span>
</div>
<div class="right">
<p class="price">¥<span class="priceCon">78</span></p>
<p class="order"><a href="#">预定</a></p>
</div>
</div>
<div class="weekList-item">
<div class="left">
<p class="ticket">天津方特欢乐世界成人夜场门票</p>
<p class="time"><img src="https://img1.qunarzz.com/piao/fusion/1804/25/792e9929973a9902.png" alt="">可定9月7日</p>
<span class="tip">条件退</span>
</div>
<div class="right">
<p class="price">¥<span class="priceCon">78</span></p>
<p class="order"><a href="#">预定</a></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <detailInfo :ticket="ticket"></detailInfo> -->
</div>
</template>
<script>
import detailInfo from 'components/singles/detail-info.vue'
export default({
name:'single',
data:function(){
return{
activeItem:'门票',
selItems:['门票','一日游','景区服务'],
ticket:[{name:'儿童票',children:[{name:'儿童半价票'},{name:'儿童全价票'}]},
{name:'成人票'},
{name:'学生票'}],
achorLinks:[{name:'门票',con:[{name2:'夜场',con:[{name3:'夜场成人票',state:false}]},{name2:'日场',con:[{name3:'儿童票',state:false},{name3:'大学生票',state:false},{name3:'成人票',state:false}]}]},{name:'一日游',con:[{name2:'一日游',con:[{name3:'【天津出发】方特欢乐世界一日游',state:false}]}]},{name:'景区服务',con:[{name2:'电子讲解',con:[{name3:'方特欢乐世界电子导游讲解',state:false}]}]}],
state:false,
}
},
components:{detailInfo},
methods:{
scrollChange:function(){
let top=document.documentElement.scrollTop;
let obj=this.$refs.single_title;
let offTop=this.$refs.single_title.offsetTop;
if(top>=offTop){
console.log(obj);
obj.className="single_title hello";
}else{
obj.className="single_title";
}
},
sel:function(item){
//console.log(item);
this.activeItem=item;
},
showChild:function(){
this.state=!this.state;
}
},
mounted:function(){
},
//当从缓存中读取数据时触发该生命周期函数
activated:function(){
window.addEventListener('scroll',this.scrollChange);
},
//当离开这个组件时撤销这个事件
deactivated:function(){
window.removeEventListener('scroll',this.scrollChange);
}
})
</script>
选择城市页面效果
点击字母按钮,页面自动跳转到相应字母开头的城市列表(使用锚点链接实现)
选中某个城市跳转回主界面,主界面右上角城市相应改变(使用Vuex实现)
选择城市并点击
城市改变
主界面中主要包含了多个组件
<template>
<div id="selcity">
<selCityHeader @toselCity="which"></selCityHeader>
<!-- <search></search> -->
<template v-if="isChina==true">
<chinaCity :sendData="message"></chinaCity>
</template>
<template v-else-if="isChina==false">
<forgeinCity></forgeinCity>
</template>
</div>
</template>
<script>
import selCityHeader from 'components/selCityHeader'
import chinaCity from 'components/chinaCity'
import forgeinCity from 'components/forgeinCity'
import search from 'components/search'
export default({
name:'selCity',
data:function(){
return{
isChina:true,
message:'hello to children',
inputCon:"",
}
},
components:{selCityHeader,chinaCity,forgeinCity,search},
methods:{
which:function(data){
//console.log(data);
if(data=='china'){
this.isChina=true;
}else if(data=='forgein'){
this.isChina=false;
}
}
},
watch:{
inputCon:function(val,oldval){
console.log(val);
}
}
})
</script>
核心组件(选择城市并跳转回主页面)
<template>
<div id="selCityCon">
<!-- 热门城市 -->
<div id="hotCity">
<h2>热门城市</h2>
<ul>
<li v-for="(city,index) in citys" :class="index % 3==1?'center':''" @click="goHome(city)">
<a href="#" title="">{{city}}</a>
</li>
</ul>
</div>
<div class="clearfix"></div>
<!-- 字母排序 -->
<div id="wordRank">
<h2>字母排序</h2>
<ul>
<li v-for="(word,index) in words">
<a :href="'#'+word" title="">{{word}}</a>
</li>
</ul>
</div>
<div class="clearfix"></div>
<!-- 城市名称列表 -->
<div id="citylist">
<div class="citylist-item" v-for="city in citylist">
<h2 :id="city.word">{{city.word}}</h2>
<div class="citylist-item-content">
<ul>
<li v-for="(item,index) in city.con" :class="(index % 4==1 || index % 4==2 ||index % 4==0) ?'border-r':''">
<a href="#" title="">{{item}}</a>
</li>
</ul>
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
</template>
<script>
export default({
name:'hotCity',
data:function(){
return{
citys:[],
words:['A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','S','T','W','X','Y','Z'],
citylist:[],
}
},
props:['sendData'],//用于接收父组件传递过来的数据
mounted:function(){
var url="http://localhost:8080/static/citylist.json"
this.$axios.get(url,{})
.then((res)=>{
//console.log(res);//此时得到的数据是经过拦截器初步处理过的
this.citylist=res.data.allcitys;
this.citys=res.data.hotcitys;
//console.log(res.data)
console.log(this.sendData);//访问父组件传过来的数据
})
.catch((err)=>{
console.log(err);
})
},
methods:{
goHome:function(name){
/*this.$store.commit('changecity',name)*/
this.$store.dispatch('acchange',name);
this.$router.push('/')
}
}
})
</script>
上一篇: 新手学习spring boot第三课