美文网首页
基于 “vue、UI组件库” 打造网易新闻应用

基于 “vue、UI组件库” 打造网易新闻应用

作者: 谷子多 | 来源:发表于2018-02-20 23:58 被阅读0次

    一、项目创建与启动

    • 安装vue-cli : vue init webpack vue-example

    二、功能需求分析

    • 头部
    • 顶部Tab导航
    • 幻灯片呢
    • 新闻列表
      1. 下拉刷新
      2. 上拉加载更多
    • 底部导航

    三、Vux(UI组件库)

    注:[可参考此文章](https://www.cnblogs.com/zy-review/p/7151938.html

    基于webpack+vue-loader+vux可以快速开发移动端页面,配合vux-loader方便你在WeUI的基础上定制需要的样式。
    vux-loader保证了组件按需使用,因此不用担心最终打包了整个vux的组件库代码。

    • 安装

      • npm i -S vux
        npm i -D less less-loader(需要配置后缀,base.conf.js)
    extensions: ['.js', '.vue', '.json','.less']
    
    • 报错(基础差劲的我解决了一天呵呵呵)

    屏幕快照 2018-02-21 下午9.12.10.png

    解决

    1. 安装vux-loader : npm install vux-loader --save-dev
    2. 配置build/webpack.base.conf.js,如下:
    • API:
    const vuxLoader = require('vux-loader')
    const webpackConfig = originalConfig // 原来的 module.exports 代码赋值给变量 webpackConfig
    
    module.exports = vuxLoader.merge(webpackConfig, {
      plugins: ['vux-ui']
    })
    
    屏幕快照 2018-02-21 下午11.46.41.png
    • Vue组件库

      • 组件分类
        • 功能型
        • UI型
        • 混合型
    • 组件基本使用

      • 四大要素
        • Props(属性)
      <x-header
            title="网易"
            :left-options="{showBack:true,backText:'back'}"
      ></x-header>
      
      • Slots(插槽)
      <x-header
           :left-options="{showBack:true,backText:'back'}"
       >
           //插槽:比title便于管理、编写
           <div>网易</div>
         </x-header>
      
      • Events
      • Methods
    • 组件内导入方法

    //烤串
     <view-box></view-box>
    //导入组件(驼峰)
     import { ViewBox,XHeader } from 'vux';
     export default {
      name: 'App',
      components: {
      //注册组件
        ViewBox,
        XHeader
      }
    }
    

    实现步骤

    1. 制作整体布局:布局组件-ViewBox(该组件为100%高布局)

      - 介绍
        - 该组件为vux的基本布局容器,建议其他组件包含在该组件内部使用。
      - 导入
        - import {ViewBox } from 'vux';
        - @import '~vux/src/styles/reset.less'  (样式重置,可直接在style标签导入)
      - 注意:此处导入的是less,所以style标签必须加lang属性,值为less
    
    <view-box></view-box>
    <style lang="less">
      @import '~vux/src/styles/reset.less';
    </style>
    

    2. 制作顶部:布局组件-XHeader

    - 介绍
        - 顶部组件
    - 导入
        - import {XHeader} from 'vux'
    

    (现在程序终于跑起来了,在此之前我调了好久原因就是配置错了,详细的的解决已在上面备注了~)
    - 在index.html中设置meta标签

    //将这个顶部部导航作为view-box的插槽
      <x-header
        slot="header"
        :left-options="{showBack:false,backText:'back'}"
      >
        <div slot="left">直播</div>
        <div>网易</div>
        <div slot="right">搜索</div>
    </x-header>
    

    3.制作底部导航:底部导航组件-Tabbar,TabbarItem

        - 介绍
            - 底部切换导航组件
        - 导入
            - import {Tabbar,TabbarItem} from 'vux'
    
    //将这个底部导航作为view-box的插槽
     <tabbar slot="bottom">
      <tabbar-item>
        <img src="./assets/icon_nav_button.png" slot="icon" alt="">
          <span slot="label">首页</span>        
      </tabbar-item>
      <tabbar-item>
        <img src="./assets/icon_nav_article.png" slot="icon" alt="">
        <span slot="label">推荐</span>        
      </tabbar-item>
      <tabbar-item>
        <img src="./assets/icon_nav_msg.png" slot="icon" alt="">
        <span slot="label">我的</span>        
      </tabbar-item>
    </tabbar>
    
    屏幕快照 2018-02-22 上午1.22.28.png

    4.制作tab切换:组件-Tab、TabItem

      - 介绍
        - tab组件
      - 导入
        - import {Tab,TabItem} from 'vux'
          - 设置容器div.my-tab
          - TabItem的selected属性
    
    <tab class="tab">
            //selected : 默认选中
            <tab-item selected>推荐</tab-item>
            <tab-item>要闻</tab-item>
            <tab-item>游戏</tab-item>
            <tab-item>科技</tab-item>
            <tab-item>娱乐</tab-item>
            <tab-item>体育</tab-item>
    </tab>
    //设置宽度之后,会自动计算,为每个元素自动分配
    .tab{
        width:600px;
    }
    

    5.为tab选项卡添加自动回弹效果:组件-Scroller

        - 介绍
            - 自定义滚动组件
        - 导入
            - import {Scroller} from 'vux'
                - :lock-y/x='true' (锁定X/Y轴是否可以拖拽)
    
      //soroller组件外面必须包div
         <scroller :lock-y="true" >
            <div class="tab">
              <tab>
                <tab-item selected>推荐</tab-item>
                <tab-item>要闻</tab-item>
                <tab-item>游戏</tab-item>
                <tab-item>科技</tab-item>
                <tab-item>娱乐</tab-item>
              <tab-item>体育</tab-item>
              </tab>
            </div>
          </scroller>
    

    6.添加轮播图:组件-Swiper

        - 介绍
            - 轮播图组件
        - 导入
            - import {Swiper} from 'vux'
                - 设置数据: :list='slideData'
                - 设置当前显示项 :v-model='slideIndex'
    
      <swiper 
            :list='swiperList'  //绑定数据(图片,图片信息等)
            v-model="swiperIndex"
            :loop='true'  //设置无缝滚动
          >
      </swiper>
      data() {
        return {
          swiperList: [
            {
              url: "javascript:",
              img: "https://static.vux.li/demo/1.jpg",
              title: "送你一朵fua"
            },
            {
              url: "javascript:",
              img: "https://static.vux.li/demo/2.jpg",
              title: "送你一辆车"
            },
            {
              url: "javascript:",
              img: "https://static.vux.li/demo/5.jpg",
              title: "送你一次旅行",
              fallbackImg: "https://static.vux.li/demo/3.jpg"
            }
          ],
          //设置默认显示第几个
          swiperIndex:1
        };
      }
    

    6.制作跑马灯新闻效果:组件-Marquee,MarqueeItem

        - 介绍
            - 滚动(跑马灯)组件
        - 导入
            - import {Marquee,MarqueeItem} from 'vux'
            - 通过v-for指令设置item
    
    <marquee class="my-marquee">
            <marquee-item>111</marquee-item>
            <marquee-item>222</marquee-item>
            <marquee-item>333</marquee-item>
    </marquee>
    

    7.制作图文列表 : 组件-Panel

        - 介绍
            - 图文列表组件
        - 导入
            - import {Panel} from 'vux'
                - 设置数据: :list='list'
                - 设置样式: class='panel-list'
    
      <panel
        :list='dataList'
      >
      </panel>
    
    屏幕快照 2018-02-22 下午10.32.35.png

    8.获取远程数据

      接口
        - 首屏推荐新闻数据
          http://3g.163.com/touch/jsonp/sy/recommend/0-9.html
         (点击network => preview,这样就格式化显示数据,foucs(焦点图)和list(首屏新闻)
        - 推荐下拉刷新
          http://3g.163.com/touch/jsonp/sy/recommend/0-9.html
            - miss : '00'
            - refresh : ['A','B01','B02','B03','B04','B05','B06','B07','B08','B09','B10']
                      每次切换这个数组项,确保每次拿到不同的数据
        - 推荐新闻更多数据
            - http://3g.163.com/touch.jsonp/sy/recommend/'+start结束(开始)+'-'+end()+'.html'
    

    数据交互 - vue-jsonp

        - 插件介绍
            - https://www.npmjs.com/package/vue-jsonp
            - 安装:npm i -S vue-jsonp
        - 导入(在main.js入口文件中)
            - import VueJsonp from 'vue-jsonp'
            - Vue.use(VueJsonp)
        - 使用
            - 组件中 : this.$jsonp(请求地址,请求对象,返回promise对象)
    
    1.首屏加载

    过程分析 : 在我们的应用当中,首先第一次加载的时候,组件创建的时候(creat钩子),就会发送第一个请求,请求到首屏幻灯片数据和新闻列表数据。
    注: 当组件创建的时候,creat就会执行。
    此处学到一个新的知识点运用:当拿到数据后,可以先用filter过滤出自己想要的数据,然后再用map方法映射出一个自己需要的数据格式。

      created () {
            //首屏轮播图数据,请求成功之后填充swiperList对象,过滤,只要null
            /* 
            {
               url: "javascript:",
               img: "https://static.vux.li/demo/1.jpg",
               title: "送你一朵fua"
            }
            */
    //先过滤需要的数据,然后map映射出需要的数据格式
            this.$jsonp('http://3g.163.com/touch/jsonp/sy/recommend/0-9.html').then(data=>{
              this.swiperList = data.focus.filter( item => {
                return item.addata === null
              }).map(item=>{
                return {
                  url : item.link,
                  img : item.picInfo[0].url,
                  title : item.title
                }
              })
            })
      }
     //首屏新闻列表的数据,拿list的数据
            this.$jsonp('http://3g.163.com/touch/jsonp/sy/recommend/0-9.html').then(data=>{
              this.dataList = data.list.map( item=> {
                return {
                  src:item.picInfo[0].url,
                  title:item.title,
                  desc:item.digest,
                  url: item.link
                }
              })
             })
    //滚动新闻
            this.$jsonp('http://3g.163.com/touch/jsonp/sy/recommend/0-9.html').then(data=>{
              this.marquee = data.live.map( item=> {
                return {
                  title:item.title,
                  url: item.link
                }
              })
            })
    
    可以看到,新闻列表的样式需要调整
    2.下拉刷新

    第三方组件 : vue-scroller

       - 介绍
          - 自定义滚动条刷新加载组件
            - https://www.npmjs.com/package/vue-scroller
       - 安装
          - npm i vue-scroller -S
    
      <!-- 内容区域,用vue-scroller组件包起来 -->
          <scroller 
            class="my-scroller" 
            :on-refresh="refresh"
            :on-infinite="infinite">
            <!-- 轮播图 -->
            <swiper 
              :list='swiperList'
              v-model="swiperIndex"
              :loop='true'
              ref="myRef"
            >
            </swiper>
            <!-- 滚动新闻 -->
            <marquee class="my-marquee">
              <marquee-item v-for="item in marquee">
                <a :href="item.url"> {{item.title}}</a>
              </marquee-item>
            </marquee>
            <!-- 新闻列表 -->
            <panel
              :list='dataList'>
            </panel>
          </scroller>
         methods: {
        //下拉数据加载 : 新闻列表
        refresh(){
          this.$jsonp('http://3g.163.com/touch/jsonp/sy/recommend/0-9.html',{
            miss : '00',
            refresh : getRefreshKey()
          }).then(data=>{
           this.dataList = data.list.map( item=> {
                return {
                  src:item.picInfo[0].url,
                  title:item.title,
                  desc:item.digest,
                  url: item.link
                }
            })
            //**停止下拉刷新**
            this.$refs.myRef.finishPullToRefresh()
          })
        },
        //上拉数据加载
        infinite(){
        
        }
      }
    
    2.上拉加载更多

    这里注意:不是副高之前的新闻列表,而是需要和之前的拼接起来。比如新建一个数组,然后新建一个新闻列表标签,将新获取的数据添加进去。

    methods: {
        //下拉数据加载 : 新闻列表
        refresh(){
          getRefreshKey();//对key自增
          this.$jsonp('http://3g.163.com/touch/jsonp/sy/recommend/0-9.html',{
            miss : '00',
            refresh : keyValue
          }).then(data=>{
            
           this.dataList = data.list.filter(item => {
             return item.addata === null && item.picInfo[0]
           }).map( item=> {
                return {
                  src:item.picInfo[0].url,
                  title:item.title,
                  desc:item.digest,
                  url: item.link
                }
            })
            //停止下拉刷新
            this.$refs.myRef.finishPullToRefresh()
            //this.$vux.toast.text('hello', 'center')
            this.$vux.toast.show({
              text: '加载成功'
            })
    
          })
        },
        //加载更多
        infinite(){
          if(!initLoaded){
            this.$refs.myRef.finishInfinite()
            return
          }
      
          this.$jsonp(`http://3g.163.com/touch/jsonp/sy/recommend/${start}-${end}.html`,{
            miss : '00',
            refresh : keyValue
          }).then(data=>{
           
            var dataList = data.list.filter(item => {
             return item.addata === null && item.picInfo[0]
           }).map( item=> {
                return {
                  src:item.picInfo[0].url,
                  title:item.title,
                  desc:item.digest,
                  url: item.link
                }
            })
            this.moreDataList = this.moreDataList.concat(dataList)
            //第二批数据加载
            start += 10;
            end = start + 9;
            this.$refs.myRef.finishInfinite()
          })
        }
      }
    

    总结

    • 1.上拉下拉加载更多,主要用到是第三方组件(自定义滚动条刷新加载组件) : vue-scroller
    <scroller 
      //下拉 : refresh里请求一次接口
      :on-refresh="refresh"
     //上拉 : infinite方法里请求一次接口
      :on-infinite="infinite">
      <!-- content goes here -->
    </scroller>
    

    遇到类似需求,首先需要明白上拉下拉的时候请求数据,然后在下拉的时候是不是覆盖之前的数据,而是拼接。

    • 2.新学到的知识点。
      如果拿到一串数据,用这个数据生成自己想要的格式 : 首先用filter过滤数据,然后用map方法映射一个新的数据。
    • 3.遇到的技术难点
      3-1 :上拉下拉刷新的时候,数据出来了,但是loading图片没有消失,原因是:需要调用this.$refs.myRef.finishInfinite(),表示已经结束请求。

    相关文章

      网友评论

          本文标题:基于 “vue、UI组件库” 打造网易新闻应用

          本文链接:https://www.haomeiwen.com/subject/vlcntftx.html