以前我寫了一篇《利用Cordova,jqurey與wp-rest-api製做一個屬於本身博客的移動APP》,使用的是jQuery mobile的方式進行web app的開發,今天我就說一下使用vuejs 與 wp-reset-api開發一個web app的方法。
先看看作好之後的效果吧:
css
安裝方法請自行去官方網站查看html
一、直接打開nodejs的命令窗口輸入如下命令:
npm install -g vue-cli //全局安裝vue-cli
vue init webpack egtch //生成項目名爲egtch的模板,這裏的項目名egtch隨你本身寫
輸入這個目錄後會出現以下所示
vue
? Project name 本身填寫一個項目名稱 ? Project description (A Vue.js project)
這裏是項目描述,隨便填寫 ? Author 這個是開發者信息,會自動獲取,也能夠本身設置html5Runtime + Compiler: recommended for most users Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-specific HTML) are
ONLY allowed in .vue files - render functions are required elsewherenode看到這個,直接回車跳過 ? Install vue-router? (Y/n)
//這裏選擇y,安裝vue-router(路由)功能,以便咱們進行相應的開發。 ? Use ESLint to lint your
code? (Y/n) //若是你想要使用eslint提示,那麼你選擇y,不知道這個是什麼東西的同窗,直接選擇n吧。 ? Setup
unit tests with Karma + Mocha? //這兩個是js測試框架,選擇n ? Setup e2e tests with
Nightwatch? (Y/n) //這個也直接選擇nlinux
二、以上步驟都完成後,即將看到以下的提醒哦webpack
vue-cli · Generated "egtch". To get started: cd egtch npm install npm
run dev 三、而後咱們在執行如下命令 cd egtch //進入項目所在目錄 npm install //初始化安裝依賴
這樣咱們在回來看咱們的目錄結構,將在egtch目錄下生成以下目錄結構 vue-cli項目目錄git
npm run dev //在瀏覽器中運行當前的vue項目
這樣就能夠看到vue-cli默認的一個頁面展示在咱們眼前了,以下圖:
vue-cli演示頁面
github
四、在咱們開發中會用到vue-resource與stylus
咱們能夠經過命令 npm install vue-resource -save來進行下載vue-resource安裝
npm install stylus -save
固然也能夠修改egtch根目錄下的packge.json文件中的代碼後,在執行npm install,修改如圖
packge.json修改
web
而且修改
"devDependencies": { ………… "css-loader": "^0.26.1", //在這個下面添加stylus //必需要添加2個關於stylus的依賴庫 "stylus-loader": "^2.5.0", "stylus": "0.52.4", ………… }
(官方地址http://v2.wp-api.org/)
好比,若是想要獲取wordpress中最新的文章,你能夠直接在瀏覽器中輸入: http://www.egtch.com/wp-json/...,你們能夠經過本站的相關api去訪問 若是想獲取指定的文章(按文章ID),能夠輸入: http://www.egtch.com/wp-json/... 獲取第一頁的文章 http://www.egtch.com/wp-json/... 第二頁page=2以此類推 更多關於wp-rest-api用法,請參考官方文檔api
一、打開根目錄下的index.html,修改title,而且在head中增長手機端設備支持代碼
而且導入reset.css(自行到網上尋找適合本身的reset.css),而且將其放在static目錄中
二、在main.js中引入vue-resource
import VueResource from 'vue-resource' Vue.use(VueResource)
三、在src/assets下新建一個css目錄,並在目錄下創建一個public.styl文件,其代碼以下
注意:使用stylus中,縮進必須正確,不然就會出現嚴重的問題
font-rem($num) font-size ($num/16)rem bg-change($color) background $color body background #CCC font-family "Microsoft Yahei","Helvetica Neue",Helvetica,Arial,sans-serif font-weight lighter height 100% h1,h2,h3,h4,h5,h6 font-weight 400 color black border-left 2px #CCC solid margin 10px 0 padding 0 0 0 8px line-height 1 font-rem(18) //手機端真正實現1px的線 .line width 90% margin 0 auto flex 1 position relative top -6px border-bottom 1px solid #F2F2F2 .line-k width 100% margin 10px auto 0 auto flex 1 position relative top -6px border-bottom 1px solid #F2F2F2 .codecolorer-container width 90% background #f2f2f2 margin 0 auto color dimgrey overflow auto border 1px #CCC solid padding 3% font-rem(14) .wp-caption text-align center
四、修改src目錄下的App.vue以下
<template> <div id="app"> <top></top> <transition :name="$router.app.pageTransition"> <router-view></router-view> </transition> <bottom></bottom> </div> </template> <script> import Top from './components/Top.vue' import Bottom from './components/Bottom.vue' export default { components:{ 'top':Top, 'bottom':Bottom } } </script> <style lang="stylus" rel="stylesheet/stylus"> @import "./assets/css/public.styl" @import "./assets/css/font-awesome.min.css" #app width 100% height 100% display table overflow auto /*right start*/ .slide-right-enter-active transition all .4s ease .slide-right-enter opacity 0.9; transform translate3d(100%, 0, 0) .slide-right-leave transform translate3d(0, 0, 0) .slide-right-leave-active transition all .4s ease opacity .5 transform translate3d(-20%, 0, 0) /*right end*/ /*left start*/ .slide-left-enter-active transition all .4s ease; transform translate3d(0%, 0, 0); z-index 1998 .slide-left-enter opacity .5 transform translate3d(-20%, 0, 0) z-index 1998 .slide-left-leave transform translate3d(0, 0, 0) .slide-left-leave-active transition all .4s ease opacity 0.9 transform translate3d(100%, 0, 0) /*left end*/ .slide-fade-enter-active transition all .4s ease .slide-fade-leave-active transition all .4s ease .slide-fade-enter, .slide-fade-leave-active opacity 0 .slide-fade-enter padding-top 80% .slide-fade-leave-active padding-top -100% </style>
五、咱們在src目錄下的commponents目錄下創建一個Posts.vue來獲取,代碼以下:
<template> <div class="po"> <div class="posts"> <div class="box" v-for="(item, index) in posts"> <div class="post"> <router-link :to="{path:'/article',query: {id:posts[index].id}}">{{posts[index].title.rendered}}</router-link> <div class="line-k"></div> <div class="posts-img" v-html="getFirstImg(posts[index].content.rendered)"></div> <div class="description" v-html="replaceDS(posts[index].excerpt.rendered)"></div> </div> </div> <a id="pre" @click="pre"><i class="fa fa-angle-left" aria-hidden="true"></i>PREVIOUS</a> <a id="next" @click="next">NEXT<i class="fa fa-angle-right" aria-hidden="true"></i></a> </div> </div> </template> <style lang="stylus" rel="stylesheet/stylus"> @import "../assets/css/public.styl" @import "../assets/css/font-awesome.min.css" .po background #ffffff width 100% .posts width 100% height 100% overflow auto margin 40px auto 68px auto & a color darkcyan padding 5px border-radius 2px &#pre float left font-rem(18) padding 5px 10px 10px 10px line-height 32px & i font-rem(28) margin-right 10px float left &#next float right font-rem(18) padding 5px 10px 10px 10px line-height 32px & i font-rem(28) margin-left 10px float right .box width 100% margin 10px auto background #ffffff padding 10px 0 line-height 1.5 border-bottom 6px solid #F2F2F2 .post width 96% margin 0 auto & a color darkcyan background none font-rem(18) margin 0 auto 5px auto padding 5px 0 .posts-img width 90% margin 0 auto padding 5px 0 0 0 & > img max-width 100% border 2px solid #CCC border-radius 5px .description font-rem(16) padding-top 5px color dimgrey </style> <script> export default{ name:'iposts', data() { return{ apiUrl:'http://www.egtch.com/wp-json/wp/v2/posts', posts:{}, page: 1, show: false } }, created(){ this.getPosts(this.page) }, watch: { // 若是路由有變化,會再次執行該方法 'page': 'getPosts' }, methods:{ getPosts(p){ if(p<1){ p = 1 } this.$http.get(this.apiUrl+'?page='+p).then(response => { // get body data response = response.body if(response.length > 0){ this.posts = response document.getElementById('next').style.display='block'; } if(response.length < 10){ document.getElementById('next').style.display='none'; } //alert(response); //console.log(this.posts); //alert(this.page) }) }, //獲取class對象 $class(domclass){ var odiv = document.getElementsByTagName("*"); var aResult = []; //定義一個空數組,用來存放與目標className相同的元素 for(var i = 0; i<odiv.length; i++) {//這個是遍歷頁面中全部元素而後拿他們的class進行對比。若是和咱們傳進來的domclass這個參數同樣就把他放進數組 aResult中。 if(odiv[i].className == domclass) { aResult.push(oDiv[i]); //獲取到的元素推動數組中 } return aResult; //返回這個放進了domclass元素的數組 } }, getFirstImg(strs){ var content = strs; var str = /<img [^>]*src=['"]([^'"]+)([^>]*>)/gi; var src = str.exec(content); if(src===null || src===undefined || src===[]) { src=''; }else { src = src[0]; src = src.replace(/ height="\d+"/g, ''); src = src.replace(/ width="\d+"/g, ''); } /*document.getElementById('imgs').src = src; console.log(src); alert(src)*/ return src; }, replaceDS(str){ /*[…]*/ var dc = str.replace(/\[…\]/g, ''); return dc; }, next(){ scrollTo(0,0); this.page++; this.showClose(); }, pre(){ scrollTo(0,0); this.page--; }, showClose(){ this.show = !this.show; } } } </script>
六、創建一個Article.vue獲取文章內容
<template> <div class="artic"> <div class="article" v-if="article"> <div class="box"> <div class="title">{{article.title.rendered}}</div> <div class="line-k"></div> <div class="content" v-html="replaceImgHW(article.content.rendered)"></div> </div> </div> </div> </template> <style lang="stylus" rel="stylesheet/stylus"> @import "../assets/css/public.styl" .artic background #ffffff width 100% .article width 100% height 100% overflow auto margin 40px auto 68px auto display block background #ffffff .box width 100% margin 0 auto line-height 2.5 .title font-weight 600 text-align center margin 0 auto 10px auto font-rem(20) background darkcyan color #f2f2f2 .content font-rem(16) word-break break-all color dimgrey padding 8px & img max-width 90% border 1px #ccc solid border-radius 5px margin-left 5% .wp-caption width 100% text-align center & img max-width 90% border 1px #ccc solid border-radius 5px </style> <script> export default{ name:'iarticle', data() { return{ apiUrl:'http://www.egtch.com/wp-json/wp/v2/posts/', article:{}, id: this.$route.query.id } }, created(){ this.getArticle(); }, watch: { // 若是路由有變化,會再次執行該方法 'this.id': 'getArticle' }, methods:{ getArticle(){ // GET /someUrl this.$http.get(this.apiUrl+this.id).then(response => { // get body data response = response.body this.article = response //alert(response); //console.log(this.article); //alert(this.id) }) }, replaceImgHW(strs){ var st1 = strs.replace(/ height="\d+"/g,''); var st2 = st1.replace(/ width="\d+"/g,''); var st3 = st2.replace(/width: \d+px/g,''); var st4 = st3.replace(/ style/g,''); var st5 = st4.replace(/=""/g,''); var st = st5.replace(/href=/g,'target="_blank" href='); return st; } } } </script>
七、再新建一個Categories.vue讀取分類
<template> <div class="cats"> <div class="categories" v-if="categories"> <div v-for="(item, index) in categories"> <div class="categories-item" v-if="categories[index].parent != 0"> <router-link :to="{path:'/postcat',query: {id:categories[index].id}}"><span v-html="icoIn[index]"></span><span>{{categories[index].name}}</span><span class="cat">{{categories[index].slug}}</span><i class="fa fa-angle-right" aria-hidden="true"></i></router-link> </div> </div> </div> </div> </template> <script> /*import Vue from 'vue' import VueResource from 'vue-resource' Vue.use(VueResource)*/ export default { data() { return{ categories:{}, catUrl:'http://www.egtch.com/wp-json/wp/v2/categories?per_page=15', icoIn:{} } }, created(){ this.getCat() this.icoIn = [ '<i class="fa fa-html5" aria-hidden="true"></i>', '<i class="fa fa-coffee" aria-hidden="true"></i>', '<i class="fa fa-code" aria-hidden="true"></i>', '<i class="fa fa-file-code-o" aria-hidden="true"></i>', '<i class="fa fa-sticky-note-o" aria-hidden="true"></i>', '<i class="fa fa-linux" aria-hidden="true"></i>', '<i class="fa fa-sun-o" aria-hidden="true"></i>', '<i class="fa fa-superscript" aria-hidden="true"></i>', '<i class="fa fa-caret-square-o-down" aria-hidden="true"></i>', '<i class="fa fa-caret-square-o-down" aria-hidden="true"></i>', '<i class="fa fa-caret-square-o-down" aria-hidden="true"></i>', '<i class="fa fa-caret-square-o-down" aria-hidden="true"></i>', '<i class="fa fa-sort-alpha-asc" aria-hidden="true"></i>', '<i class="fa fa-caret-square-o-down" aria-hidden="true"></i>', '<i class="fa fa-caret-square-o-down" aria-hidden="true"></i>' ] }, methods:{ getCat(){ this.$http.get(this.catUrl).then(response => { response = response.body; this.categories = response; }); } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style lang="stylus" rel="stylesheet/stylus"> @import "../assets/css/public.styl" .cats background #ffffff width 100% .categories width 95% height 100% overflow auto margin 48px auto 68px auto display block .categories-item text-align center width 100% height 60px background #ffffff border-bottom 1px #f2f2f2 solid float left display block & > a display block color #000 height 100% padding 10px 0 font-rem(16) & span float left padding-left 5px line-height 40px &.cat color #CCC font-rem(14) & i font-rem(14) color darkcyan & i float right padding-right 10px font-rem(24) color #CCC line-height 40px </style>
八、創建一個Postcat.vue來獲取分類目錄下的文章
<template> <div class="psc"> <div class="postcat"> <div class="box" v-for="(item, index) in postcat"> <div class="post"> <router-link :to="{path:'/article',query: {id:postcat[index].id}}">{{postcat[index].title.rendered}}</router-link> <div class="line-k"></div> <div class="postcat-img" v-html="getFirstImg(postcat[index].content.rendered)"></div> <div class="description" v-html="replaceDS(postcat[index].excerpt.rendered)"></div> </div> </div> <a id="ipre" @click="ipre"><i class="fa fa-angle-left" aria-hidden="true"></i>PREVIOUS</a> <a id="inext" @click="inext">NEXT<i class="fa fa-angle-right" aria-hidden="true"></i></a> </div> </div> </template> <style lang="stylus" rel="stylesheet/stylus"> @import "../assets/css/public.styl" @import "../assets/css/font-awesome.min.css" .psc background #ffffff width 100% .postcat width 100% height 100% overflow auto margin 40px auto 68px auto display block & a color darkcyan padding 5px border-radius 2px &#ipre float left font-rem(18) padding 5px 10px 10px 10px line-height 32px & i font-rem(28) margin-right 10px float left &#inext float right font-rem(18) padding 5px 10px 10px 10px line-height 32px & i font-rem(28) margin-left 10px float right .box width 100% margin 10px auto background #ffffff padding 10px 0 line-height 1.5 border-bottom 6px solid #F2F2F2 .post width 96% margin 0 auto & a color darkcyan background none font-rem(18) margin 0 auto 5px auto padding 5px 0 .postcat-img width 90% margin 0 auto padding 5px 0 0 0 & > img max-width 100% border 2px solid #CCC border-radius 5px .description font-rem(16) padding-top 5px color dimgrey </style> <script> export default{ name:'ipostcat', data() { return{ postcatUrl:'http://www.egtch.com/wp-json/wp/v2/posts?categories='+this.$route.query.id+'&page=', postcat:{}, ipage: 1, show: false } }, created(){ this.getPostcat(this.ipage) }, watch: { // 若是路由有變化,會再次執行該方法 'ipage': 'getPostcat' }, methods:{ getPostcat(p){ // GET /someUrl if(p<1){ p = 1 } this.$http.get(this.postcatUrl+p).then(response => { // get body data response = response.body if(response.length > 0){ this.postcat = response document.getElementById('inext').style.display='block'; } if(response.length < 10){ document.getElementById('inext').style.display='none'; } //alert(response); //console.log(this.postcat); //alert(this.ipage) }) }, getFirstImg(strs){ var content = strs; var str = /<img [^>]*src=['"]([^'"]+)([^>]*>)/gi; var src = str.exec(content); if(src===null || src===undefined || src===[]) { src=''; }else { src = src[0]; src = src.replace(/ height="\d+"/g, ''); src = src.replace(/ width="\d+"/g, ''); } /*document.getElementById('imgs').src = src; console.log(src); alert(src)*/ return src; }, replaceDS(str){ /*[…]*/ var dc = str.replace(/\[…\]/g, ''); return dc; }, inext(){ scrollTo(0,0); this.ipage++; }, ipre(){ scrollTo(0,0); this.ipage--; }, showClose(){ this.show = !this.show; } } } </script>
以上咱們就能夠完成了得到文章以及分類目錄下的文章的相關代碼。看上去是否是很簡單,使用vuejs確實可讓咱們省去不少的DOM操做。
更多代碼和實例,請直接查看本項目在github中的實例地址爲:
https://github.com/king2088/V...,若是你喜歡本實例,請記得在github上給我加星哦!
演示地址:
http://www.egtch.com/VueEgtch/本程序會後續還會進行相應的更新維護,但願你們關注,也但願你們關注vuejs