基于 “vue、UI組件庫” 打造網(wǎng)易新聞應(yīng)用

一、項(xiàng)目創(chuàng)建與啟動(dòng)

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

二、功能需求分析

  • 頭部
  • 頂部Tab導(dǎo)航
  • 幻燈片呢
  • 新聞列表
    1. 下拉刷新
    2. 上拉加載更多
  • 底部導(dǎo)航

三、Vux(UI組件庫)

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

基于webpack+vue-loader+vux可以快速開發(fā)移動(dòng)端頁面,配合vux-loader方便你在WeUI的基礎(chǔ)上定制需要的樣式。
vux-loader保證了組件按需使用,因此不用擔(dān)心最終打包了整個(gè)vux的組件庫代碼。

  • 安裝

    • npm i -S vux
      npm i -D less less-loader(需要配置后綴,base.conf.js)
extensions: ['.js', '.vue', '.json','.less']
  • 報(bào)錯(cuò)(基礎(chǔ)差勁的我解決了一天呵呵呵)

屏幕快照 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="網(wǎng)易"
          :left-options="{showBack:true,backText:'back'}"
    ></x-header>
    
    • Slots(插槽)
    <x-header
         :left-options="{showBack:true,backText:'back'}"
     >
         //插槽:比title便于管理、編寫
         <div>網(wǎng)易</div>
       </x-header>
    
    • Events
    • Methods
  • 組件內(nèi)導(dǎo)入方法

//烤串
 <view-box></view-box>
//導(dǎo)入組件(駝峰)
 import { ViewBox,XHeader } from 'vux';
 export default {
  name: 'App',
  components: {
  //注冊組件
    ViewBox,
    XHeader
  }
}

實(shí)現(xiàn)步驟

1. 制作整體布局:布局組件-ViewBox(該組件為100%高布局)

  - 介紹
    - 該組件為vux的基本布局容器,建議其他組件包含在該組件內(nèi)部使用。
  - 導(dǎo)入
    - import {ViewBox } from 'vux';
    - @import '~vux/src/styles/reset.less'  (樣式重置,可直接在style標(biāo)簽導(dǎo)入)
  - 注意:此處導(dǎo)入的是less,所以style標(biāo)簽必須加lang屬性,值為less
<view-box></view-box>
<style lang="less">
  @import '~vux/src/styles/reset.less';
</style>

2. 制作頂部:布局組件-XHeader

- 介紹
    - 頂部組件
- 導(dǎo)入
    - import {XHeader} from 'vux'

(現(xiàn)在程序終于跑起來了,在此之前我調(diào)了好久原因就是配置錯(cuò)了,詳細(xì)的的解決已在上面?zhèn)渥⒘藒)
- 在index.html中設(shè)置meta標(biāo)簽

//將這個(gè)頂部部導(dǎo)航作為view-box的插槽
  <x-header
    slot="header"
    :left-options="{showBack:false,backText:'back'}"
  >
    <div slot="left">直播</div>
    <div>網(wǎng)易</div>
    <div slot="right">搜索</div>
</x-header>

3.制作底部導(dǎo)航:底部導(dǎo)航組件-Tabbar,TabbarItem

    - 介紹
        - 底部切換導(dǎo)航組件
    - 導(dǎo)入
        - import {Tabbar,TabbarItem} from 'vux'
//將這個(gè)底部導(dǎo)航作為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組件
  - 導(dǎo)入
    - import {Tab,TabItem} from 'vux'
      - 設(shè)置容器div.my-tab
      - TabItem的selected屬性
<tab class="tab">
        //selected : 默認(rèn)選中
        <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>
//設(shè)置寬度之后,會自動(dòng)計(jì)算,為每個(gè)元素自動(dòng)分配
.tab{
    width:600px;
}

5.為tab選項(xiàng)卡添加自動(dòng)回彈效果:組件-Scroller

    - 介紹
        - 自定義滾動(dòng)組件
    - 導(dǎo)入
        - 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

    - 介紹
        - 輪播圖組件
    - 導(dǎo)入
        - import {Swiper} from 'vux'
            - 設(shè)置數(shù)據(jù): :list='slideData'
            - 設(shè)置當(dāng)前顯示項(xiàng) :v-model='slideIndex'
  <swiper 
        :list='swiperList'  //綁定數(shù)據(jù)(圖片,圖片信息等)
        v-model="swiperIndex"
        :loop='true'  //設(shè)置無縫滾動(dòng)
      >
  </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"
        }
      ],
      //設(shè)置默認(rèn)顯示第幾個(gè)
      swiperIndex:1
    };
  }

6.制作跑馬燈新聞效果:組件-Marquee,MarqueeItem

    - 介紹
        - 滾動(dòng)(跑馬燈)組件
    - 導(dǎo)入
        - import {Marquee,MarqueeItem} from 'vux'
        - 通過v-for指令設(shè)置item
<marquee class="my-marquee">
        <marquee-item>111</marquee-item>
        <marquee-item>222</marquee-item>
        <marquee-item>333</marquee-item>
</marquee>

7.制作圖文列表 : 組件-Panel

    - 介紹
        - 圖文列表組件
    - 導(dǎo)入
        - import {Panel} from 'vux'
            - 設(shè)置數(shù)據(jù): :list='list'
            - 設(shè)置樣式: class='panel-list'
  <panel
    :list='dataList'
  >
  </panel>
屏幕快照 2018-02-22 下午10.32.35.png

8.獲取遠(yuǎn)程數(shù)據(jù)

  接口
    - 首屏推薦新聞數(shù)據(jù)
      http://3g.163.com/touch/jsonp/sy/recommend/0-9.html
     (點(diǎn)擊network => preview,這樣就格式化顯示數(shù)據(jù),foucs(焦點(diǎn)圖)和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']
                  每次切換這個(gè)數(shù)組項(xiàng),確保每次拿到不同的數(shù)據(jù)
    - 推薦新聞更多數(shù)據(jù)
        - http://3g.163.com/touch.jsonp/sy/recommend/'+start結(jié)束(開始)+'-'+end()+'.html'

數(shù)據(jù)交互 - vue-jsonp

    - 插件介紹
        - https://www.npmjs.com/package/vue-jsonp
        - 安裝:npm i -S vue-jsonp
    - 導(dǎo)入(在main.js入口文件中)
        - import VueJsonp from 'vue-jsonp'
        - Vue.use(VueJsonp)
    - 使用
        - 組件中 : this.$jsonp(請求地址,請求對象,返回promise對象)
1.首屏加載

過程分析 : 在我們的應(yīng)用當(dāng)中,首先第一次加載的時(shí)候,組件創(chuàng)建的時(shí)候(creat鉤子),就會發(fā)送第一個(gè)請求,請求到首屏幻燈片數(shù)據(jù)和新聞列表數(shù)據(jù)。
注: 當(dāng)組件創(chuàng)建的時(shí)候,creat就會執(zhí)行。
此處學(xué)到一個(gè)新的知識點(diǎn)運(yùn)用:當(dāng)拿到數(shù)據(jù)后,可以先用filter過濾出自己想要的數(shù)據(jù),然后再用map方法映射出一個(gè)自己需要的數(shù)據(jù)格式。

  created () {
        //首屏輪播圖數(shù)據(jù),請求成功之后填充swiperList對象,過濾,只要null
        /* 
        {
           url: "javascript:",
           img: "https://static.vux.li/demo/1.jpg",
           title: "送你一朵fua"
        }
        */
//先過濾需要的數(shù)據(jù),然后map映射出需要的數(shù)據(jù)格式
        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
            }
          })
        })
  }
 //首屏新聞列表的數(shù)據(jù),拿list的數(shù)據(jù)
        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
            }
          })
         })
//滾動(dòng)新聞
        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
            }
          })
        })
可以看到,新聞列表的樣式需要調(diào)整
2.下拉刷新

第三方組件 : vue-scroller

   - 介紹
      - 自定義滾動(dòng)條刷新加載組件
        - https://www.npmjs.com/package/vue-scroller
   - 安裝
      - npm i vue-scroller -S
  <!-- 內(nèi)容區(qū)域,用vue-scroller組件包起來 -->
      <scroller 
        class="my-scroller" 
        :on-refresh="refresh"
        :on-infinite="infinite">
        <!-- 輪播圖 -->
        <swiper 
          :list='swiperList'
          v-model="swiperIndex"
          :loop='true'
          ref="myRef"
        >
        </swiper>
        <!-- 滾動(dòng)新聞 -->
        <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: {
    //下拉數(shù)據(jù)加載 : 新聞列表
    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()
      })
    },
    //上拉數(shù)據(jù)加載
    infinite(){
    
    }
  }
2.上拉加載更多

這里注意:不是副高之前的新聞列表,而是需要和之前的拼接起來。比如新建一個(gè)數(shù)組,然后新建一個(gè)新聞列表標(biāo)簽,將新獲取的數(shù)據(jù)添加進(jìn)去。

methods: {
    //下拉數(shù)據(jù)加載 : 新聞列表
    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)
        //第二批數(shù)據(jù)加載
        start += 10;
        end = start + 9;
        this.$refs.myRef.finishInfinite()
      })
    }
  }

總結(jié)

  • 1.上拉下拉加載更多,主要用到是第三方組件(自定義滾動(dòng)條刷新加載組件) : vue-scroller
<scroller 
  //下拉 : refresh里請求一次接口
  :on-refresh="refresh"
 //上拉 : infinite方法里請求一次接口
  :on-infinite="infinite">
  <!-- content goes here -->
</scroller>

遇到類似需求,首先需要明白上拉下拉的時(shí)候請求數(shù)據(jù),然后在下拉的時(shí)候是不是覆蓋之前的數(shù)據(jù),而是拼接。

  • 2.新學(xué)到的知識點(diǎn)。
    如果拿到一串?dāng)?shù)據(jù),用這個(gè)數(shù)據(jù)生成自己想要的格式 : 首先用filter過濾數(shù)據(jù),然后用map方法映射一個(gè)新的數(shù)據(jù)。
  • 3.遇到的技術(shù)難點(diǎn)
    3-1 :上拉下拉刷新的時(shí)候,數(shù)據(jù)出來了,但是loading圖片沒有消失,原因是:需要調(diào)用this.$refs.myRef.finishInfinite(),表示已經(jīng)結(jié)束請求。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容