用weexplus從0到1寫一個(gè)app(2)-頁面跳轉(zhuǎn)和文章列表及文章詳情的編寫

說明

結(jié)束連續(xù)幾天的加班,最近的項(xiàng)目終于告一段落,今天抽點(diǎn)時(shí)間開始繼續(xù)寫我這篇拖了很久的《用weexplus從0到1寫一個(gè)app》系列文章。寫這篇文章的時(shí)候,weexplus的作者已經(jīng)把weexplus重構(gòu)了一下,可以同時(shí)打包出web端和native端,我這邊的ui界面和項(xiàng)目結(jié)構(gòu)也跟著做了一點(diǎn)變化。這里有weexplus官方放出的一個(gè)電影APP的demo,有需要的可以去下載看看,然后順便給weexplus一個(gè)star吧!

新版UI展示

文章可能會(huì)很長(zhǎng),在此分幾篇文章來寫,先占個(gè)坑:

開始寫代碼

頁面跳轉(zhuǎn)和接收參數(shù)

在第一篇的文章《環(huán)境搭建和首頁編寫》中已經(jīng)寫好了首頁的代碼,現(xiàn)在要從首頁的某個(gè)文章跳轉(zhuǎn)到文章詳情應(yīng)該怎么做呢?在vue里我們知道是用vue-router來跳轉(zhuǎn),weexplus中也給我們封裝好了類似的導(dǎo)航控制器navigator。具體使用請(qǐng)看navigtor模塊文檔

  • 頁面?zhèn)鲄?shù)跳轉(zhuǎn)

主要用后面這段navigator.pushParam('跳轉(zhuǎn)路徑String','傳遞的參數(shù)Object'),如果不需要傳參數(shù)直接用navigator.push('跳轉(zhuǎn)路徑String')就好了。以下為示例代碼:

//commponet/home/news.vue省略n多代碼
const navigator = weex.requireModule("navigator");//先引入navigator模塊
gotonews(item) {
    if (item.category) {
        if (item.category.name == "專題") {
            //navigator傳參數(shù)跳轉(zhuǎn)頁面
            navigator.pushParam(
              "root:/busi/news/list.js", {
                cid: item.id,
                from: "zhuanti"
              }
            );
          }
          if (item.category.name != "專題") {
            navigator.pushParam("root:/busi/news/detail.js", {
              id: item.id
            });
          }
        } else {
          navigator.pushParam("root:/busi/news/detail.js", {
            id: item
        });
    }
},
  • 接收參數(shù)
//busi/news/detail.vue省略n多代碼
const navigator = weex.requireModule("navigator");//先引入navigator模塊
created(options) {
    const globalEvent = weex.requireModule("globalEvent");
    globalEvent.addEventListener("onPageInit", () => {
        const query = navigator.param();//接收上一個(gè)頁面?zhèn)鬟f的參數(shù)
        this.query = query;
    });
},

文章列表和文章詳情

先來看文章列表和文章詳情的UI界面:

文章列表和文章詳情的UI界面

下面拆解一下界面布局:

文章列表和文章詳情的UI界面

文章列表界面

可以從分解圖中看到文章列表大體上分為三個(gè)部分:文章標(biāo)題,文章封面,文章發(fā)布時(shí)間。下面廢話少說,show my coding!

文章列表數(shù)據(jù)結(jié)構(gòu)
"article_list": [
    {
        "id": "7019",//文章id
        "title": "Super Star吉他譜_S.H.E_彈唱譜掃弦版",//文章標(biāo)題
        "haslitpic": 1,
        "pic": {
            "src": "/180203/21562a414_lit.jpg",
            "url": "/180203/21562a414_lit.jpg"
        },//文章封面
        "description": "Super Star吉他譜,掃弦版編配",//文章簡(jiǎn)介
        "pubdate": "2018-02-03 21:55:23",//文章發(fā)布時(shí)間
        "category": {
            "name": "圖片譜"http://文章分類
        },
    }]

列表布局代碼

weex默認(rèn)是flex布局,css方面就很簡(jiǎn)單了,對(duì)flex不熟悉的推薦看一下阮一峰的flex文章,在這里就不貼代碼了。

//component/news-item.vue省略n多代碼
<template>
  <div class="news-items">
    <div v-if="type==1" class="item-box" @click="gotonews(item.id)" v-for="(item,index) in newsItems" :key="index">
      <div class="item-left">
        <text class="left-text">{{item.title}}</text>
        <div class="left-line"></div>
        <text class="left-time" v-if="item.category && item.category.name && item.category">{{item.category.name}}</text>
        <text class="left-time" v-else>{{item.pubdate}}</text>
      </div>
      <div class="item-right">
        <img :src="item.pic.src" mode="aspectFill" class="litpic">
      </div>
    </div>
    <div class="item-box2" v-if="type==2" @click="gotonews(item.id)">
      <img :src="item.pic.src" mode="aspectFill" class="litpic2" />
      <!-- <img src="../../static/assets/nav1.png" mode="aspectFill" class="litpic2"> -->
      <text class="box2-text">{{item.title}}</text>
    </div>
  </div>
</template>

<script>
  const navigator = weex.requireModule("navigator");
  
  export default {
    name: 'news-item',
    props: {
      item: {
        pic: {
          default: ''
        },
        title: {
          default: ''
        },
        publishTime: {
          default: ''
        },
      },
      type: {
        default: 1
      },
      newsItems: {
        type: Array,
        default: []
      }
    },
    methods: {
      gotonews(item) {
        //省略代碼
      },
    }
  }
</script>

<style lang="less" scoped>
</style>

在這里需要注意幾個(gè)點(diǎn):

  • 一個(gè)是在weex中文字必須被<text></text>標(biāo)簽包住才能給到樣式否則無效,并且<text></text>標(biāo)簽不能多層嵌套;
  • 另外圖片標(biāo)簽<img/>有個(gè)resize屬性默認(rèn)是stretch會(huì)按照?qǐng)D片區(qū)域的寬高比例縮放圖片可能圖片會(huì)變形,這里有三個(gè)屬性分別是contain(縮放圖片以完全裝入<image>區(qū)域,可能背景區(qū)部分空白)、cover(縮放圖片以完全覆蓋<image>區(qū)域,可能圖片部分看不見)、stretch(默認(rèn)值. 按照<image>區(qū)域的寬高比例縮放圖片)。具體表現(xiàn)樣式參見weex文檔image組件。

文章詳情界面

同樣可以從分解圖中看到文章詳情大體上分為兩個(gè)個(gè)部分:文章標(biāo)題,文章內(nèi)容(富文本)

文章列表數(shù)據(jù)結(jié)構(gòu)
"article": {
    "id": 7019,//文章id
    "cid": "2",//分類id
    "title": "Super Star吉他譜_S.H.E_彈唱譜掃弦版",//文章標(biāo)題
    "author": "愛尚吉他",
    "haspic": 1,
    "pic": {
        "url": "/21562a414_lit.jpg"http://封面
    },
    "keywords": "Super,Star,吉他,S.H.E,彈唱,譜掃,弦版",//關(guān)鍵詞
    "description": "Super Star吉他譜,掃弦版編配",//描述
    "pubdate": "2018-02-03 21:55:23",
    "postime": "1517666123",
    "good": "0",
    "bad": "0",
    "favorite": "0",
    "comments": 0,
    "body": "Super ",//文章詳情(富文本)
}
詳情布局代碼
//busi/news/detail.vue省略n多代碼
<template>
  <div class="app" style="background-color: #fff">
    <my-header title="文章詳情" @rightClick="refresh">
      <image slot="right" src="root:img/assets/refresh.png" style="width:40px;height:40px;position:absolute;right:30px;bottom:30px;"/>
    </my-header>
    <scroller>
      <div class="publish">
        <text class="title">{{item.title==''?'愛尚吉他':item.title}}</text>
        <div class="sub">
          <text class="author theme-font">{{item.author}}</text>
          <text class="line">|</text>
          <text class="pubdate">{{item.pubdate}}</text>
        </div>
      </div>
      <div class="content-box">
        <rich-text :content="item.body"></rich-text>
      </div>
      <div class="border-b-5"></div>
      <title-item v-if="aboutItems.length>0" title="相關(guān)閱讀"></title-item>
      <news-item v-if="aboutItems.length>0" :newsItems="aboutItems"></news-item>
      <title-item title="推薦譜單" url="root:busi/topic/list.js?type=2"></title-item>
      <topic-item showLength="4" type="2"></topic-item>
      <homeSinger-item></homeSinger-item>
      <back-item v-if="show"></back-item>
    </scroller>
  </div>
</template>

<script>
  import myHeader from "../../component/header.vue";//頭部組件
  import titleItem from "../../component/title-item.vue";//標(biāo)題組件
  import newsItem from "../../component/news-item.vue";
  import backItem from "../../component/back-item.vue";
  import richText from "../../component/rich-text.vue";//富文本
  import topicItem from "../../component/vtopic-item.vue";
  import homeSingerItem from "../../component/home/singer.vue";//歌手列表組件

  const navigator = weex.requireModule("navigator");
  const modal = weex.requireModule("modal");
  
  import apis from "./../util/api";
  import {
    htmlTOJson
  } from "./../util/util";//解析富文本
  import request from "./../util/request";//數(shù)據(jù)請(qǐng)求封裝
  
  export default {
    components: {
      titleItem,
      newsItem,
      backItem,
      richText,
      myHeader,
      topicItem,
      homeSingerItem
    },
    data() {
      return {
        item: {
          body: [{
              type: "icon",
              src: ""
            },
            {
              type: "text",
              value: "",
              theme: "yellow"
            }
          ],
          title: "",
          pubdate: "",
          pic: "",
          author: "",
          normalBody: ""
        },
        show: false,
        aboutItems: [],
        query: {}
      };
    },
    created(options) {
      const globalEvent = weex.requireModule("globalEvent");
      globalEvent.addEventListener("onPageInit", () => {
        const query = navigator.param();//拿到傳遞的參數(shù)
        this.query = query;
        this.refresh();
      });
    },
    methods: {
      refresh(){
        this.loadData(this.query.id);
      },
      loadData(id) {
        //請(qǐng)求初始數(shù)據(jù)
        const that = this;
        let arr = [];
        let data = request.get(apis.articleDetails, {
          id: id
        }).then(data => {
          //數(shù)據(jù)組裝
        });
      },
      gotonews(id) {
        // console.log(id);
        navigator.pushParam("./detail.js", {
          id: id
        });
        // this.loadData(id);
      },
      share() {}
    }
  };
</script>

<style src="../../css/style.css"></style>

<style scoped></style>

在這里需要注意幾個(gè)點(diǎn):

  • weex目前對(duì)富文本支持不太友好,官方是有個(gè)richtext組件,但是需要前端自己重新解析富文本內(nèi)容為指定的格式,具體參見richtext文檔,對(duì)這一塊目前我這邊也沒有完美的解決方案,這里只有幾個(gè)思路:1.按照官方的按照richtext組件需要的數(shù)據(jù)結(jié)構(gòu)前端自己解析;2.寫一個(gè)H5頁面顯示富文本,任何用webview嵌入;3.接口返回?cái)?shù)據(jù)按照richtext組件需要的數(shù)據(jù)結(jié)構(gòu)處理好數(shù)據(jù)。

一點(diǎn)私貨

基于同一套u(yù)i開發(fā)出來的吉他自學(xué)小助手小程序版已經(jīng)上線喜歡彈吉他的小伙伴可以關(guān)注一波 https://minapp.com/miniapp/8327/

更多

更多前端技術(shù)分享請(qǐng)關(guān)注我的博客:https://hurely.github.io

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容