欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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技术请求数据资源

项目目录结构
Vue-cli搭建移动端项目
组件目录
Vue-cli搭建移动端项目

首页界面效果
Vue-cli搭建移动端项目

  • 搜索栏组件
<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层中
    Vue-cli搭建移动端项目
<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层中
    Vue-cli搭建移动端项目
<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来获取参数从而动态加载详情界面 )
Vue-cli搭建移动端项目
Vue-cli搭建移动端项目

详情页代码主要是引入多个组件

<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实现)
Vue-cli搭建移动端项目
选择城市并点击
Vue-cli搭建移动端项目
城市改变
Vue-cli搭建移动端项目

主界面中主要包含了多个组件

<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>