【別貪心】vue-news

首先放下作者大大的github地址:https://github.com/Alicecss/vue-news
接下來我們一起來看項目,看下項目的項目效果

接下來我們一起來看項目哇
不同的作者大大我們會發現項目的架構都是不一樣的

//index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>news</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
//main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from "./vuex/store"
import axios from "axios"
import lazy from "vue-lazyload"
import "./commons/styl/index.styl"
import videoPlayer from "vue-video-player"
import vueawesomeswiper from "vue-awesome-swiper"
let imgs=require("./commons/imgs/loading.gif")
Vue.use(vueawesomeswiper)
Vue.use(videoPlayer)
Vue.prototype.$axios=axios
Vue.use(lazy,{
  error:"",
  loading:imgs
})
Vue.config.productionTip = false

new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})
router.push("/news")
//app.vue
<template>
  <div id="app">
    <!--<div class="tab">
      <div class="tab-item">
        <router-link to="/news">新聞</router-link>
      </div>
      <div class="tab-item">
        <router-link to="/movies">天氣</router-link>
      </div>
      <div class="tab-item">
        <router-link to="/Recommend">推薦</router-link>
      </div>
      <div class="tab-item">
        <router-link to="/myself">我的</router-link>
      </div>
    </div>-->
      <router-view ></router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style lang="stylus" scoped>
 /* .tab
    position absolute
    z-index 100
    display flex
    bottom  0
    width 100%
    left 0
    border-top 1px solid rgba(7,17,27,0.1)
    background-color white
    .tab-item
      flex 1
      text-align center
      padding 10px 0
      & a
        text-decoration none
        color rgb(7,17,27)
        &.router-link-active
          color red*/
</style>
//router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import news from "../components/news"
import movies from "../components/weather.vue"
import Recommend from "../components/Recommend.vue"
import myself from "../components/myself"
import newsdetail from "../components/news/newsdetail.vue"
import suitable from "../components/weather/suitable.vue"
import search from "../components/searchs.vue"

Vue.use(Router)

export default new Router({
  routes: [
    {
      path:"/news",
      component:news
    },
    {
      path:"/movies",
      component:movies
    },{
      path:"/Recommend",
      component:Recommend
    },{
      path:"/myself",
      component:myself
    },
    {
      path:"/newsdetail",
      component:newsdetail
    },
    {
      path:"/search",
      component:search
    },
    {
      path:"/suitable",
      component:suitable
    }
  ]
})

//router.vue
<template>
    <div class="router">
      <div class="tab">
        <div class="tab-item">
          <router-link to="/news">新聞</router-link>
        </div>
        <div class="tab-item">
          <router-link to="/movies">天氣</router-link>
        </div>
        <div class="tab-item">
          <router-link to="/Recommend">推薦</router-link>
        </div>
        <div class="tab-item">
          <router-link to="/myself">我的<sup v-show="promt!=0">+</sup></router-link>
        </div>
      </div>
    </div>
</template>
<script>
    export default {
        components: {},
      data(){
            return{

            }
      },
      computed:{
        promt(){
        return this.$store.state.follow.length
        }
      }
    }
</script>
<style lang="stylus" scoped>
  .tab
    position fixed
    z-index 100
    display flex
    bottom  0
    width 100%
    left 0
    border-top 1px solid rgba(7,17,27,0.1)
    background-color white
    .tab-item
      flex 1
      text-align center
      padding 10px 0
      & a
        text-decoration none
        color rgb(7,17,27)
        &.router-link-active
          color red
      sup
        color red
        height 10px
</style>
//eleheader.vue

<template>
  <div class="eleheader" @click="searchs">
    <div class="header">
      <input  type="text" class="text" placeholder="新聞/推薦">
    </div>
  </div>
</template>

<script>
  export default {
    name: "eleheader",
    methods: {
      searchs(){
        this.$router.push("/search")
      }
    }
  }
</script>

<style scoped lang="stylus">
  .header
    width 100%
    height 50px
    padding 10px 20px
    box-sizing border-box
    .text
      border-radius 30px
      background-color rgba(7, 17, 27, 0.1)
      border none
      outline none
      width 100%
      height 30px
      text-align center
</style>
//switches.vue
<template>
  <div class="switches">
    <ul class="tab">
      <li class="tab-item"
          v-for="item,index in tabs" :key="index"
          @click="newslist(index)"
          :class="index==list?'active':''">
        {{item}}
      </li>
    </ul>
  </div>
</template>
<script>
  export default {
    name: 'switches',
    props: {
      tabs: {type: Array, default: null},
      list:{type:Number}
    },
    methods:{
      newslist(index){
          this.$emit('newschange',index)
      }
    }
  }
</script>
<style lang="stylus" scoped>
  .switches
    width 100%
    .tab
      display flex
      width 100%
      .tab-item
        padding 5px 0
        text-align center
        flex 1
        &.active
          color red
</style>
//switches.vue
<template>
  <div class="switches">
    <ul class="tab">
      <li class="tab-item"
          v-for="item,index in tabs" :key="index"
          @click="newslist(index)"
          :class="index==list?'active':''">
        {{item}}
      </li>
    </ul>
  </div>
</template>
<script>
  export default {
    name: 'switches',
    props: {
      tabs: {type: Array, default: null},
      list:{type:Number}
    },
    methods:{
      newslist(index){
          this.$emit('newschange',index)
      }
    }
  }
</script>
<style lang="stylus" scoped>
  .switches
    width 100%
    .tab
      display flex
      width 100%
      .tab-item
        padding 5px 0
        text-align center
        flex 1
        &.active
          color red
</style>

//scroll.vue
<template>
  <div ref="wrapper" class="wrapper">
     <slot></slot>
  </div>
</template>
<script>
  import BScroll from "better-scroll"
  export default {
    props: {
      probeType: {
        type: Number, default: 3
      },
      click: {
        type: Boolean, default: false
      },
      scrollX: {
        probeType: Boolean, default: false
      },
      beforeScroll: {
        type: Boolean, default: false
      },
      pullup: {
        type: Boolean, default: false
      },
      pulldown: {
        type: Boolean, default: false
      },
      listenScroll: {
        type: Boolean, default: false
      },
      refreshDelay: {
        type: Number, default: 20
      },
      data: {
        type: Array, default: null
      }
    },
    methods: {
      _initScroll(){
        if (!this.$refs.wrapper) {
          return
        }
        this.scroll = new BScroll(this.$refs.wrapper, {
          click: this.click,
          probeType: this.probeType,
          scrollX: this.scrollX
        })
        if (this.listenScroll){
            this.scroll.on('scroll',(pos)=>{
                this.$emit('scroll',pos)
            })
        }
        if(this.pullup){
            this.scroll.on('scrollEnd',()=>{
                if (this.scroll.y<=this.scroll.maxScrollY+50){
                    this.$emit('scrollToEnd')
                }
            })
        }
        if (this.beforeScroll){
            this.scroll.on('beforeScroll',()=>{
                this.$emit('beforeScroll')
            })
        }
      }
    },
    mounted(){
        setTimeout(()=>{
            this._initScroll()
        },20)
    },
    watch:{
        data(){
            setTimeout(()=>{
                this.scroll.refresh()
            },20)
        }
    }
  }
</script>
<style lang="stylus" scoped>
.wrapper
  width 100%
  height 100%
</style>
//newlist.vue
<template>
  <div class="newslist">
  <ul class="news">
    <li class="news-item border-1px"
        v-for="item,index in newss"
        @click="enterdetail(item)"
        style="height: 100px" :key="index">
      <div class="lft">
        <div class="title">{{item.title}}</div>
        <div class="bottom-content">
          <span class="name">{{item.author_name}}</span>
          <span class="date">{{item.date}}</span>
        </div>
      </div>
      <div class="rig">
        <img width="100" v-lazy="item.thumbnail_pic_s" alt="">
      </div>
    </li>
  </ul>
</div>
</template>

<script>
  export default {
    props: ['types'],
    name: "newlist",
    data(){
      return {
        newss: {}
      }
    },
    created(){
        this.news()
    },
    methods: {
      // 進入詳情頁
      enterdetail(item){
        this.$store.state.newlist=item
        console.log('item1111111',item)
        /*console.log(this.$store.state.newlist)*/
        this.$router.push("/newsdetail")
      },
      //news列表傳值
      news(){
        let types=String(this.types)
        /*let host = '/api/'+'guoji'+'&key=939994f1f415919a9348ba7d7f5b1b93'*/
        let host='/api/'+types
        this.$axios.get(host).then((res) => {
          this.newss = res.data.data.result.data
        }).catch((error) => {
          console.log(error)
        })
      }
    }
  }
</script>

<style scoped lang="stylus">
  @import "./../../commons/styl/base.styl"
  .newslist
    .news
      .news-item
        display flex
        padding 10px 10px
        font-size 14px
        color rgb(7, 17, 27)
        border-1px(rgba(7, 17, 27, 0.2))
        .title
          font-size 14px
          margin-top 10px
        .bottom-content
          position: absolute
          left 10px
          bottom 5px
          font-size 12px
          color rgba(7, 17, 27, 0.5)
          .name
            display inline-block
            margin-right 20px
        .lft
          flex 7
        .rig
          flex 3
          text-align center
          padding-top 10px
          img
            margin auto auto
</style>

接下來看movies頁面

//weather.vue


<template>
  <div class="movies">
    <routers></routers>
    <div class="header" @click="tabss">
      <span class="name" >{{weathers.citys}}</span>
      <div class="selects" v-show="tabs==false">廣州</div>
    </div>
    <div>
      <div class="main" v-if="weathers.realtime">
        <div v-if="weathers.realtime.weather">
          <div class="info">{{weathers.realtime.weather.info}}</div>
          <div class="temperature">{{weathers.realtime.weather.temperature}}</div>
          <div class="wind">
            <span>{{weathers.realtime.wind.direct}}</span>
            <span>{{weathers.realtime.wind.power}}</span>
          </div>
          <div class="pm25">
            <div class="number">{{Number(weathers.pm25.pm25.curPm) +
            Number(weathers.pm25.pm25.level) +
            Number(weathers.pm25.pm25.pm10) +
            Number(weathers.pm25.pm25.pm25)}}
              <span>{{weathers.pm25.pm25.quality}}</span>
            </div>
          </div>
        </div>
      </div>
      <div class="everydate" v-for="item,index in weathers.weather">
        <div class="item">{{item.date}}</div>
        <div class="item">{{item.info.day[1]}}</div>
        <div class="item">{{item.info.dawn[2]}}<sup>。</sup>~ {{item.info.day[2]}}<sup>。</sup></div>
      </div>
      <div class="suitable" v-if="weathers.life">
        <div class="suitable-item" @click="suichange(0)">
          <p>穿衣指數</p>
          <p>{{weathers.life.info.chuanyi[0]}}</p>
        </div>
        <div class="suitable-item" @click="suichange(1)">
          <p>紫外線指數</p>
          <p>{{weathers.life.info.ziwaixian[0]}}</p>
        </div>
        <div class="suitable-item" @click="suichange(2)">
          <p>運動指數</p>
          <p>{{weathers.life.info.yundong[0]}}</p>
        </div>
        <div class="suitable-item" @click="suichange(3)">
          <p>洗車指數</p>
          <p>{{weathers.life.info.xiche[0]}}</p>
        </div>
        <div class="suitable-item" @click="suichange(4)">
          <p>感冒指數</p>
          <p>{{weathers.life.info.ganmao[0]}}</p>
        </div>
        <div class="suitable-item" @click="suichange(5)">
          <p>空調指數</p>
          <p>{{weathers.life.info.kongtiao[0]}}</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  import scroll from "../base/scroll.vue"
  import routers from "../base/routers.vue"
  export default {
    name: "movies",
    components: {scroll,routers},
    data(){
      return {
          tabs:true,
        playerOptions: {},
        weathers: {},
      }
    },
    methods: {
      tabss(){
          if(this.tabs==true){
              this.tabs=false
          }else{
              this.tabs=true
          }
      },
      // 點擊儲存數據
      suichange(num){
        let info = this.weathers.life.info
        if (num == 0) {
          this.$store.state.suitable= info.chuanyi
          this.$store.state.suitable.push('穿衣指數')
        } else if (num == 1) {
          this.$store.state.suitable = info.ziwaixian
          this.$store.state.suitable.push('紫外線指數')
        } else if (num == 2) {
          this.$store.state.suitable = info.yundong
          this.$store.state.suitable.push('運動指數')
        } else if (num == 3) {
          this.$store.state.suitable = info.xiche
          this.$store.state.suitable.push('洗車指數')
        } else if (num == 4) {
          this.$store.state.suitable = info.ganmao
          this.$store.state.suitable.push('感冒指數')
        } else if (num == 5) {
          this.$store.state.suitable = info.kongtiao
          this.$store.state.suitable.push('空調指數')
        }
        this.$router.push('/suitable')
      }
    },
    created(){
      this.$nextTick(() => {
        this.$axios.get('/api/shenzhen').then((res) => {
          res = res.data
          this.weathers = res.data.result
          console.log(res.data.result)
        }).catch((error) => {
          console.log(error)
        })
      })
    }
  }
</script>

<style scoped lang="stylus">
  .movies
    .header
      width 100%
      padding 5px 10px
      height 30px
      color blue
      position fixed
      background white
      border 1px solid rgba(7,17,27,0.1)
      left 0
      top 0
      .selects
        position absolute
        left 0
        top 42px
        width 100%
        height 50px
        background white
        padding 0 10px
      .name
        position absolute
        left 50%
        margin-left -25px
        width 50px
        font-size 20px
    .main
      margin-top 60px
      margin-bottom 30px
      text-align center
      color blue
      .info
        margin 10px 0
        font-size 20px
        font-weight 700
      .temperature
        font-size 100px
        font-family 'Adobe 黑體 Std R'
        font-weight 700
      .wind
        span:first-child
          padding-right 10px
      .pm25
        margin-top 10px
        font-size 15px
        line-height 15px
        .number
          padding 3px 5px
          display inline-block
          width 60px
          border 1px solid blue
          border-radius 10px
    .everydate
      display flex
      .item
        margin 5px 0
        text-align center
        flex 1
        &:nth-child(2)
          color rgba(7.17 .27 .0 .5)
    .suitable
      margin-bottom 50px
      display flex
      width 100%
      overflow auto
      justify-content space-around
      flex-wrap wrap
      .suitable-item
        box-sizing border-box
        margin 10px 0
        border-radius 5px
        height 100px
        text-align center
        line-height 100px
        flex 0 0 30%
        background linear-gradient(#00a0e9, blue)
        color white
        p
          height 30%
</style>
//suitable.vue
<template>
  <div class="suitable">
    <div class="header" @click="backshang">
      {{suitables[2]}}
    </div>
    <div class="main">
      <div class="title">{{suitables[0]}}</div>
      <div class="wrapper">{{suitables[1]}}</div>
    </div>
  </div>
</template>
<script>
  export default {
    components: {},
    data(){
      return {

      }
    },
    methods:{
      backshang(){
          this.$router.back(-1)
      }
    },
    computed:{
      suitables(){
        console.log('this.$store.state.suitable',this.$store.state.suitable)
        return this.$store.state.suitable
      }
    },
    created(){

    }
  }
</script>
<style lang="stylus" scoped>
.suitable
  background rgba(7,17,27,0.1)
  height 100%
  .header
    background white
    font-size 16px
    color rgba(7,17,27,0.8)
    padding 10px 10px
  .main
    margin 20px 10px 20px 10px
    background white
    padding 10px
    .title
      color red
      font-size 25px
</style>

//Recommend.vue
<template>
  <div class="Recommend">
    <routers></routers>
    <eleheader></eleheader>
    <scroll
      class="scroll"
      :click="true"
      :probeType="3">
      <div class="newslist">
        <div class="banner" >
          <banner :imgs="imgs"></banner>
        </div>
        <newslist :types="'fire'"></newslist>
      </div>
    </scroll>
  </div>
</template>
<script>
  import eleheader from "../components/news/eleheader.vue"
  import banner from "../base/banner.vue"
  import routers from "../base/routers.vue"
  import scroll from "./../base/scroll.vue"
  import newslist from "./news/newlist.vue"
  export default {
    components: {newslist, scroll,routers,banner,eleheader},
    name: "Recommend",
    data(){
      return {
          imgs:['../../static/imgs/1.jpg','../../static/imgs/2.jpg',
            '../../static/imgs/3.jpg','../../static/imgs/4.jpg',
            '../../static/imgs/5.jpg']
      }
    },
    computed:{
      swiper() {
        return this.$refs.mySwiper.swiper
      }

    },
    mounted() {
      /*this.swiper.slideTo(1, 1000, false)*/
    },
    created(){
      this.$nextTick(() => {
        let host = '/R2/' + '%e5%a5%a5%e5%b7%b4%e9%a9%ac'
        this.$axios.get(host).then((res) => {
        }).catch((error) => {
          console.log(error)
        })
      })
    }
  }
</script>
<style scoped lang="stylus">
  .Recommend
    .header
      width 100%
      height 50px
      padding 10px 20px
      box-sizing border-box
      .text
        border-radius 30px
        background-color rgba(7, 17, 27, 0.1)
        border none
        outline none
        width 100%
        height 30px
        text-align center
    .scroll
      position absolute
      top 50px
      bottom 50px
      overflow hidden
      .newslist
        position relative
        .banner
          width 100%
          height 180px
          .swiper-wrapper
            position: relative
            width 100%
</style>

//myself.vue
<template>
  <div class="myself">
    <routers></routers>
    <div class="myself-title">
      <img class="img1" src="./../commons/imgs/brand.jpg" alt="">
      <img class="img2" src="./../commons/imgs/brand.jpg" alt="">
      <div class="myself-bottom">
        <div class="tab">
          <div class="tab-item">
            <p>0</p>
            <p>發表</p>
          </div>
          <div class="tab-item">
            <p>{{promt}}</p>
            <p>關注</p>
          </div>
          <div class="tab-item">
            <p>0</p>
            <p>粉絲</p>
          </div>
          <div class="tab-item">
            <p>0</p>
            <p>獲贊</p>
          </div>
        </div>
      </div>
    </div>
    <div class="search">
      <ul class="info">
        <Li class="info-item border-1px" v-for="item,index in info"
            :key="index"
            @click="tabs(item,index)"
        >
          <span>{{item}}</span>
          <span class="prompt" v-if="index==1" v-show="promt!=0">+{{promt}}</span>
        </Li>
      </ul>
    </div>
    <div class="component" v-show="shows==1">
      <follow @shows="showschange"></follow>
    </div>
    <div class="component" v-show="shows==4">
      <mobile @shows="showschange"></mobile>
    </div>
    <div class="component" v-show="shows==0">
      <zip-code @shows="showschange"></zip-code>
    </div>
    <div class="component" v-show="shows==2">
      <loves @shows="showschange" ref="love"></loves>
    </div>
    <div class="component" v-show="shows==5">
      <mobile-location @shows="showschange" ref="love"></mobile-location>
    </div>
  </div>
</template>

<script>
  import follow from "./myself/follow.vue"
  import routers from "../base/routers.vue"
  import loves from "./myself/loves.vue"
  import zipCode from "./myself/zipCode.vue"
  import widgets from "./myself/widgets"
  import mobile from "./myself/mobile.vue"
  import mobileLocation from  "./myself/mobileLocation.vue"
  export default {
    name: "myself",
    components: {mobile,zipCode,loves,mobileLocation,routers,follow},
    data() {
      return {
          // 控制收藏小圖標

        shows: null,
        info: ['全國郵編查詢', '歷史/收藏', '愛情術語', '身份證查詢', '號碼吉凶', '號碼歸屬地', '匯率']
      }
    },
    computed:{
      promt(){
          return this.$store.state.follow.length
      }
    },
    methods: {
        // 子組件改變shows的值,並返回myself界面
        showschange(shows){
            this.shows=shows

        },
      //獲取點擊對應index
      tabs(item, index){
          this.shows=index
        /*console.log(index)*/
        if(index==2){
            console.log(index)
          if(this.$refs.love.datas){
            this.$refs.love.datas()
            /*console.log(this.$refs.love)*/
          }
        }
      }
    }
  }
</script>

<style scoped lang="stylus">
  @import "./../commons/styl/base.styl"
  .myself
    blur 10px
    .myself-title
      background rgba(173, 176, 170, 0.5)
      padding 80px 20px
      position relative
      .img1
        position absolute
        left 0
        top 0
        height 100%
        width 100%
        opacity 0.3
        z-index -1
      .img2
        height 50px
        width 50px
        border-radius 50%
      .myself-bottom
        position absolute
        left 0
        bottom 0
        width 100%
        margin 10px 0
        .tab
          display flex
          .tab-item
            text-align center
            flex 1
            p:nth-child(2)
              font-size 12px
              color rgba(7, 17, 27, 0.5)
    .search
      .info
        background rgba(7, 17, 27, 0.2)
        .info-item
          padding 15px 20px
          background white
          border-1px(rgba(7, 17, 27, 0.1))
          .prompt
            position absolute
            right 20px
            display inline-block
            height 30px
            width 30px
            line-height 30px
            color red
            text-align center
            background rgba(7,17,27,0.1)
            border-radius 20px
          &:nth-child(2)
            margin-bottom 10px
            border none
    .component
      position fixed
      top 0
      left 0
      background white
      width 100%
      height 100%
</style>

總的來說,作者大大的項目是非常的輕巧,裏面還是有一些很有技術性處理的的呢

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章