vue 頭條 demo 寫在前面
總結一下寫 demo 過程中 遇到的一些問題,方便自己的學習總結!如有錯誤,還請指正!
一直想學習使用 vue ,并準備以后在實際項目使用,之前跟著慕課網 黃軼 老師 敲了一下 餓了么商品購買頁的demo
ele效果預覽
該 demo 借鑒自 hcy1996-github 這個項目,但內部內容,布局風格,完全不同,只為共同學習,共同交流
數據接口 直接打開 今日頭條 網頁版 ,在 network 分析了下,直接 copy 過來的
還有很多功能沒有實現,后期在完善吧!
項目地址:github-項目地址
預覽效果: demo預覽效果
建議在 chrome 瀏覽器查看(不知道為什么在手機上數據請求,一個勁卡死,不知道是不是因為今日頭條接口的原因)
演示頭部添加 rem 布局
引入 reset.css
使用 阿里媽媽圖標庫,index.html 引入
使用 css 預處理器 sass安裝 node-sass sass-loader npm install node-sass sass-loader --save-dev
使用
參考文章: http://www.jianshu.com/p/67f52071657d
app.vue
底部導航欄欄 ==> 剛開始時用的 vux 的 tabbar tabbar-item 組件,發現有需求實現不了,剛開始還改了源碼,最后實在受不了了
就用 vue-router roter-link 自己寫了
底部導航欄 四個按鈕分別對應 四個組件
由于自己對 vue-router 理解還欠火候,所以遇到了一個問題
routes 數組里面的內容對應的就是 組件 ,
path 選項對應的是路由路徑,初始時沒有路由嵌套 即為 index
components 選項對應該路由對應的組件,由于組件已經全部通過 import 引入了,所以不需要寫路徑了
底部通用 tab 導航欄
本想多帶帶抽出一個 bottom.vue 組件呢,但在左右切換的滑動樣式中,表現并不好,因為希望底部導航欄不滑動這才符合人的預期需求
所以最終還是選擇不抽離這個組件,直接寫在了 app.vue 里面了
通用樣式庫 common scss 目錄 base.scss mixin.scss 通過 一個 index.scss 導入
引入 axios ,由于 axios 不支持jsonp,所以還得引入 jsonp
npm install axios jsonp --save
在 common/js/ajax.js 下使用這兩個庫
import axios from "axios"
import jsonp from "jsonp"
將 ajax 請求,封裝在 一個通用的 js 文件里,方便統一處理 ajax
即前后端協作時 定義的一些返回值代表的意義,都可以在此方法里統一處理
遇到個問題不知道怎么解決
我想有 loading.vue 組件,就是可以在通用的 ajax.js 文件里引用,
問題是,我發現 當加載 ajax.js 文件時 ,loading.vue 組件 import 不進來的,所以無法使用
但我又想要 當用統一 ajax 處理的時候,統一執行 loading
最終我想了一個下下策,把 loading組件的內容直接寫在了index.html 文件里,這樣就可以加載到了,就可以在 ajax處理的時候集中使用 loading.vue 了
不僅 loading 組件,還有 通用彈框組件,(就是想在一個通用的 js 文件里,每次只要在使用的地方 import 這個 js 文件,就能使用這些 通用組件,而不必每次都要 import 這些組件)
現在的解決辦法太渣,看以后能不能想到什么好的辦法
如果各位大大,有什么好的方法,希望能告知 小弟 一聲
index.vue 文件頂部 x-header 組件 ,感覺使用不夠靈活
不知道如何 自定義左右圖標
因為 vux 的 icon 是引自 icon圖標css庫
右側icon 是我引用 阿里媽媽圖標庫里面的圖標的
標簽導航一欄 本來是用 vux 的scroller 組件寫的,但看到官方文檔上寫 ,此組件已不在維護,且不建議開發者繼續使用
自己按著 demo 用了一下發現不知道 如何 refresh,就放棄了
自己 用 better-scroll 處理滾動 tab 標簽欄橫線滾動沒碰到問題
新聞內容列表滾動也是用的 better-scroll 碰到了一個問題,
下拉刷新的logo 總是無法藏在 列表后面,無論怎么設置 z-index
最后才發現問題,自己還真的是蠢,列表容器沒寫背景顏色,自然永遠都能看到loading圖標
在糾結的過程中也發現了幾個問題:
移動端百分比布局時:html,body一定要設置寬高百分比,不然會遇到很多坑
better-scroll 滾動容器一定要有明確的寬高,建議最好用絕對定位,背景顏色,overflow:hidden
最大的一個坑,列表總是有一部分滾動不上來,碰到這個問題,首先想到:
列表高度是否大于容器高度
refresh 時機不對最終,發現確實時是 refresh 時機不對,
但接下來糾結的時刻到了,無論放在哪都不對,最終寫了 setTimeout(fn,3000),可以正常工作,但這肯定不是解決辦法
最后想到:因為列表中的圖片容器高度,是靠圖片撐開的,但圖片加載的比較慢所以 better-scroll 計算不到準確的高度,
解決辦法:圖片容器高度事先寫死,完美的解決了
圖片懶加載 vue-lazyload 插件,超好用
懶加載引用的圖片地址:loading 圖片
如果 在js 引用靜態圖片,因為webpack 不會解析 js 文件里的圖片,
所以要用 import 引用 import logo from "./assets/loading.gif"
或是把圖片放在頂層的 static 目錄里
微信左右滾動效果(切換底部tab時)---以下是通用思路在 全局路由 beforeEach(function(to,from,next){***}) 鉤子里 要做下面的事情
假如待切換的組件為 index1,index2
在 sessionStorage 里面 創建 一個 __router__ 值
__router__的值包括:count, transitionName , to.path ,from.path
count 初識值為 0;
transitionName 初始值為 ""
to.path 初始值為 undefined
form.path 初始值為 undefined
首次進入時 to.index(index1) 為空 執行 else
count++
判斷 to.path !== "/" && history[to.path] = historyCount
history["transitionName"] = "forward"; 為前進狀態
此時: index1:1,count:1
二次 進入(路由已跳轉過一次) 此時 to.path 依舊 為 undefined ,而 from.path 為 to.path 的值
繼續走 else 里面,重復上面的步驟 此時 index2:2,count2,index1:1
在繼續點第一個 tab 相當于回到第一個 tab
此時:to.path == index1, from.path == index2
假如 :!fromIndex || parseInt(toIndex) > parseInt(fromIndex
或:toIndex === "0" && fromIndex === "0"
為 forward 前進狀態
否則: 為 reserve 后退狀態
這樣就能判斷是前進狀態還是后退狀態,就可以用樣式控制滾動方向了
Do not bb ,show me code
router.beforeEach(function (to, from, next) { let history = window.sessionStorage.__router__; if(!history){ history = {}; }else{ history = JSON.parse(history); } let historyCount = history.count * 1; //記錄走過的 tab 頁數量 const toIndex = history[to.path]; // 要去的索引 const fromIndex = history[from.path]; //要離開的索引 if (toIndex) { if (!fromIndex || parseInt(toIndex) > parseInt(fromIndex) || (toIndex === "0" && fromIndex === "0")) { history["transitionName"] = "forward"; } else { history["transitionName"] = "reverse"; } } else { //第一次沒有記錄session-storage 的情況 ++historyCount; history["count"] = historyCount; to.path !== "/" && (history[to.path] = historyCount); history["transitionName"] = "forward"; } history = JSON.stringify(history); window.sessionStorage.__router__ = history; if (//http/.test(to.path)) { let url = to.path.split("http")[1]; window.location.href = `http${url}` } else { next() } });遇到問題(2017-08-10)
當第一次進入頁面時 ,如果不是處在第一個 tab 時,history 里面記錄的索引就會出現錯亂現象
解決辦法:事先設置好 首頁出現的四個 tab 的索引,設置好 初始的 count 為 4
這樣就不會發生索引錯亂現象
切換時的一個小問題當左右華東切換時,要注意將各個 tab 頁頂層設置 ,position:absolute,這樣才會排在同一排,否則會出現一上一下的現象
具體實現查看 github-項目地址 里面的 main.js app.vue通過 watch 選項監測 $route 動態的改變transitionName 的值
sessionStorage 和 localStorage 本地存儲問題watch: { "$route" (to, from) { console.log(to,from); this.transitionName = JSON.parse(window.sessionStorage.__router__).transitionName; } }, 樣式: //微信切換樣式 ,左右滾動 //前進動畫樣式 .forward-enter-active,.forward-leave-active{ transition: all 0.3s; } .forward-enter{ transform: translateX(100%); } .forward-leave-to{ transform: translateX(-100%); } // 后退動畫樣式 .reverse-enter-active,.reverse-leave-active{ transition: all 0.3s; } .reverse-enter{ transform: translateX(-100%); } .reverse-leave-to{ transform: translateX(100%); }
sessionStorage 本地會話存儲,會話結束-瀏覽器關閉(不包括刷新頁面,恢復頁面),存儲結果清除
localStorage 本地存儲,除非手動清除,否則永不清除
大小傳說 5M
方法1:getItem(key),setItem(key,value),clear()
方法2:利用 . 或 [] 語法,訪問或設置
事件:
如果你監聽storage變更事件你就會發現,當數據發生變化時本頁是監聽不到storage事件變更消息的。而同域的其他打開的頁面反而監聽到了該消息。悲劇不?
解決辦法百度
storage只能存儲字符串 不能存儲其他類型數據存儲對象,讀取對象:
let history = window.sessionStorage.__router__; if(!history){ history = {}; }else{ //讀取 history = JSON.parse(history); } //存儲 history = JSON.stringify(history); window.sessionStorage.__router__ = history;activated 鉤子
在
keep-alive 組件在第二次渲染時不會觸發 create mounted updated 鉤子
但是會觸發 activated 鉤子
使用場景: 列表頁==> 詳情頁的切換
第一次從列表頁進詳情頁時會加載數據 觸發 created,mounted,updated 鉤子
第二次以上鉤子就不會被觸發了, 需要加上一個 activated 生命周期鉤子,在里面加載請求數據
路由跳轉時 需要用到 動態路由 即在 路徑后面加個 id
我用query 進行傳遞參數,如果不主動傳遞參數,跳轉后的子頁面刷新時數據就丟失了(原計劃用 vuex 做收藏功能)
index.js {path: "/newsDetails/:key", name: "newsDetails",component:newsDetails },
導航寫法:
或者//路由外鏈
列表頁 ==> 詳情頁
從列表頁到詳情頁不適合用嵌套路由嵌套路由寫法
因為其是兩個多帶帶的頁面,并不會同時出現在一屏上
route.js
{path: "/index", name:"index", component: index, children:[ {path: "/index/newsDetails/:id", name: "newsDetails",component:newsDetails }, ] }
index.vue
路由傳參:to = ""index/newsDetails" + item.source_url"
不僅僅傳遞一個動態路由id還可以 通過 params 和 query進行傳遞,但都會顯示在 url上
列表頁 ==> 將該項所有參數傳遞到詳情頁,可以現將對象數據 序列化為字符串,放在 query li
在詳情頁時,取值時反序列化,繼而可以在詳情頁里面使用
由于數據是存在 url 里 故可以在刷新頁面仍可以拿到數據
路由小結路由中的三個基本概念: route routes router
route 一條路由(單條路由的走向) routes 一組路由(靜止的一組路由的集合)
router 是一種機制相當于一個管理者(當用戶點擊時 去 routes 去執行相應的路由)
普通路由
動態路由
嵌套路由
編程式導航
組件內的掛載到 根實例上的兩個對象 路由源信息對象: this.$route 和 路由實例對象 this.$router
父子組件通訊父組件 => 子組件
父組件傳遞:
簡寫方式(直接傳值)數組形式 ==> : props:["flag"]
默認值寫法: 對象形式
props:{ flag:{ type:Bollean, dafault(){ return false; } } }
子組件 ==> 父組件
v-on 綁定 子組件派發而來的事件
父組件接收:
-
methods:{ scroll_to(childmsg){ //執行 。。。 childmsg 為子組件向父組件傳遞的參數 } }
子組件
methods:{ xxx(){ this.$emit("scrolltoTop","aaa向父組件傳遞的參數") } }
注意不能直接使用 $on 監聽子組件拋出的事件,而必須在模板里使用 v-on 綁定收藏頁 ==> vuex
在詳情頁進行 收藏/取消 操作
將該操作的數據存在 vuex 里,然后存在 localStorage 里,
store.js 里建一個 newsItem字段,值為數組,然后通過 mutations 操作,
向數組里添加或刪除元素
在收藏組件里進行渲染
原計劃收藏頁的新聞是可以 收藏/取消收藏的收藏 存進vuex,取消收藏從vuex里刪除
但今日頭條的數據結構感覺有點亂
想著真實開發中,后臺肯定會返回一個字段告訴該條新聞本人是否已經收藏過
只做了收藏,暫無取消收藏功能,收藏之后存進 vuex ==> localstorage
bug ==> 同一條新聞可重復收藏
vuex 操作流程
store.js
import Vue from "vue" import Vuex from "vuex" import mutations from "./mutations" Vue.use(Vuex); const store = new Vuex.Store({ state:{ //數據管理中心 count:0, }, mutations, //使用處進行 commit getters:{ //外界在此處獲得 vuex 數據 nowTime(state){ return new Date() - 0 + "-" + state.count; } } }); export default store;
mutations.js
//全局觸發事件 export default { increment (state){ // 只有通過此處的方法才能改變vuex 內的數據 state.count++; }, decrement (state){ state.count--; }, }
使用的時候 引入 import {mapState,mapMutations,mapGetters} from "vuex"
然后通過 this.$store 對象進行操作
vuex 待續。。。 處理資源js 引用圖片 必須用 import 導入 import logo.png from "相對路徑"
放在 src 目錄里的文件都是交由 webpack 處理的
放在 static 目錄里面的文件 webpack 不會處理,而是在 build 之后,直接拷貝 相應目錄里
所以在 項目里如果要引用 static 目錄里的文件 必須要使用絕對路徑 /static/[filename]
main.js 里 引用 圖片懶加載 的加載中圖片時 路徑必須為 "./static/img/loading.gif"(我也不知道原因)
具體可參考此回答: vue static目錄資源使用
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/87403.html
摘要:這是用高仿今日頭條的移動端項目,結合了原生的部分功能以及網頁版。前言本人是今日頭條的重度用戶,在學習過程中,在上看到了很多高仿的好項目。因為數據原因,首頁請求的數據接口來自網頁版今日頭條,修改了一些參數收藏頁面數據由本地文件獲取。 vue-toutiao 這是用 vue.js 2.0 高仿 今日頭條 的移動端項目,結合了原生app的部分功能以及網頁版。 前言 本人是 今日頭條 的重度用...
摘要:前言上次初學用寫了個后臺管理,這次便尋思寫個移動端的項目。便有了這次的這個項目。然后通過來判斷如何動畫具體處理異步用來書寫跟配置還有一些零零散散的知識點,就不介紹了,具體可以到上查看。個人博客在線觀看地址 前言 上次初學用 react 寫了個后臺管理,這次便尋思寫個移動端的項目。便有了這次的這個項目。 這個項目以前寫了個 vue 的版本。有興趣的可以 點擊進入 模擬數據用的是 Eas...
摘要:但由于這里僅僅是實現一個,因此存儲功能僅通過一個單例類來模擬實現。 本文旨在通過重寫GridView,配合系統彈窗實現仿今日頭條的頻道編輯頁面 注:由于代碼稍長,本文僅列出關鍵部分,完整工程請參見【https://github.com/G9YH/YHChannelEdit】 在開始講解盜版的實現方案前,讓我們先來看看正版與盜版的實際使用效果對比,首先是正版 showImg(https:...
閱讀 1827·2021-10-20 13:49
閱讀 1367·2019-08-30 15:52
閱讀 2873·2019-08-29 16:37
閱讀 1041·2019-08-29 10:55
閱讀 3076·2019-08-26 12:14
閱讀 1655·2019-08-23 17:06
閱讀 3240·2019-08-23 16:59
閱讀 2550·2019-08-23 15:42