zoukankan      html  css  js  c++  java
  • 【别贪心】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>
    

    总的来说,作者大大的项目是非常的轻巧,里面还是有一些很有技术性处理的的呢

  • 相关阅读:
    git 查看远程分支、本地分支、删除本地分支
    iOS edgesForExtendedLayout、extendedLayoutIncludesOpaqueBars、automaticallyAdjustsScrollViewInsets属性详解
    【iOS开发】UIWebView与JavaScript(JS) 回调交互
    iOS打印Debug日志的方式
    iOS项目上传到AppStore步骤流程
    IOS开发之实现App消息推送(最新)
    DKNightVersion 的实现 --- 如何为 iOS 应用添加夜间模式
    用Session实现验证码
    HTTP中Get与Post、ViewState 原理
    ASP.NET获取服务器文件的物理路径
  • 原文地址:https://www.cnblogs.com/smart-girl/p/13395873.html
Copyright © 2011-2022 走看看