后端開發(fā)寫Vue(iView使用總結(jié))

本文適用有前端基礎(chǔ)但沒有Vue基礎(chǔ)的讀者。

作為一個正正經(jīng)經(jīng)的后端開發(fā),雖然早年自稱過全棧野哭,但是隨著前端技術(shù)發(fā)展的越來越快,技術(shù)棧越來越多幻件,現(xiàn)在已經(jīng)不敢自稱全棧拨黔。

早年搭建管理后臺都是采用bootstrap,由后端渲染頁面绰沥。但是有很多東西是后端渲染無法做到的篱蝇。偶然發(fā)現(xiàn)一個組件庫——iView贺待,這是一個高質(zhì)量的vue組件庫,涵蓋了你可以想象到的任何組件零截。但是因?yàn)橹皼]有vue基礎(chǔ)麸塞,所以踩了很多坑,這里總結(jié)一下涧衙。

0x00如何跳轉(zhuǎn)頁面

由這個問題就引出了vue-router哪工。它是一個前端路由,也就是說弧哎,通過它進(jìn)行的跳轉(zhuǎn)操作是并沒有經(jīng)過后端的雁比。

<router-link to="/foo">Go to Foo</router-link>
this.$router.push({ path: '/user', params: { userId: 123 }})

上面是兩種頁面跳轉(zhuǎn)方式,其中push的方式最常見撤嫩,這里為了方便理解使用了path偎捎,在實(shí)際應(yīng)用中路由表會給每個路由分配一個name,在push的時候就可以直接push name進(jìn)去了序攘。

參考文檔:https://router.vuejs.org/

0x01如何獲取參數(shù)

上面說了跳轉(zhuǎn)茴她,如果跳轉(zhuǎn)的時候帶了參數(shù),那么如何獲取到傳遞過來的參數(shù)呢两踏?

this.$route.params['id']
this.$route.query.id

0x02如何變更數(shù)據(jù)

這里就要了解雙向綁定這個東西了败京。何為雙向綁定?

其實(shí)簡單來說就是在vue中也會有model和view的概念梦染。雙向綁定就是針對他們來說,當(dāng)我們用JavaScript代碼更新Model時朴皆,View就會自動更新帕识。當(dāng)用戶變更了View,Model的數(shù)據(jù)也自動被更新了遂铡,這種情況就是雙向綁定肮疗。

舉個例子就是,當(dāng)用戶填寫表單數(shù)據(jù)的時候扒接,表單數(shù)據(jù)變更了伪货,這個時候model里的數(shù)據(jù)也同步變更了,這種方式就避免了早期原生js代碼中那種還得通過dom結(jié)構(gòu)自行去獲取form表單的數(shù)據(jù)再拼接數(shù)據(jù)钾怔。

同樣碱呼,在表格中,如果你要刪除一行表格需要如何操作呢宗侦?在沒有雙向綁定之前你需要分別去刪除dom結(jié)構(gòu)中的dom和數(shù)據(jù)中相應(yīng)的行數(shù)據(jù)愚臀。而現(xiàn)在,你只需要刪除掉數(shù)據(jù)中的行數(shù)據(jù)矾利,dom結(jié)構(gòu)壓根不需要你關(guān)心姑裂。當(dāng)然這個只是例子馋袜,實(shí)際應(yīng)用中一般都是重新調(diào)用接口刷新全部數(shù)據(jù),表格dom也會全部重新刷新舶斧。

0x03如何在表格中渲染自定義內(nèi)容

在一個表格中我們經(jīng)常需要渲染一些復(fù)雜的內(nèi)容欣鳖,這里就需要用到reader函數(shù)。

{
  columns: [
    {
        title: 'Type',
        key: 'type',
        width: 160
    },
    {
        title: '操作',
        key: 'action',
        width: 100,
        render: (h, params) => {
            return h('div', [
                h('Button', {
                    props: {
                        type: 'primary',
                        size: 'small'
                    },
                    style: {
                        marginRight: '5px'
                    },
                    on: {
                        click: () => {
                            this.show(params.index)
                        }
                    }
                }, '查看')
            ]);
        }
    }
  ]
}

上面的代碼是一個表格的columns茴厉,這里可以看到在操作這一列中我們渲染了一個按鈕泽台,重點(diǎn)在h函數(shù),他的第一個參數(shù)是標(biāo)簽名呀忧,最后一個參數(shù)是標(biāo)簽中間的Text师痕,中間的參數(shù)是標(biāo)簽的屬性和事件之類。需要注意的是而账,中間的參數(shù)是可以省略的胰坟,也就是只有兩個參數(shù)∨⒎基本屬性可以寫在props里笔横;css可以寫在style里,注意采用駝峰寫法咐吼;事件寫在on里吹缔。

還有需要注意的是:h函數(shù)是可以互相嵌套的,就是通過這種嵌套組合不同的dom結(jié)構(gòu)锯茄。當(dāng)然這種方式其實(shí)并不友好厢塘,還有更方便的方式是jsx,通過jsx你可以直接在render函數(shù)里返回一個dom肌幽,這里就不展開講了晚碾。

0x04如何格式化日期

實(shí)際開發(fā)中后端接口有時候會返回UTC時間,那么如何優(yōu)雅的對其進(jìn)行格式化呢喂急。答案是moment格嘁。npm install moment 然后在main.js里添加如下代碼即可

Vue.prototype.$moment = moment;
Vue.filter('moment', function(value, formatString) {
    formatString = formatString || 'YYYY-MM-DD HH:mm:ss';
    return moment(value).format(formatString)
})

if (!String.prototype.moment) {
    String.prototype.moment = function(formatString) {
        formatString = formatString || 'YYYY-MM-DD HH:mm:ss';
        return moment(this).format(formatString)
    };
}

在使用的時候,如果是在dom結(jié)構(gòu)中廊移,用法是{{ data.time | moment }}糕簿。
如果是在js中,用法是params.row.create_time.moment()

0x05如何提交數(shù)據(jù)

原先vue官方推薦的網(wǎng)絡(luò)庫是vue-resource狡孔,現(xiàn)在已經(jīng)改成axios了懂诗。一樣npm install axios,然后再main.js中加入如下代碼

Vue.prototype.$http = axios;

這樣步氏,你就可以在任意vue文件中通過下面這種方式使用了

this.$http.get('/api/stacks/').then((response) => {
    console.log(response.data)
})

this.$http.post('/api/stacks/').then((response) => {
    console.log(response.data)
}).catch((e) => {
    console.log(e)
})

當(dāng)然响禽,這真是基本用法,在復(fù)雜應(yīng)用中,為了方便后期維護(hù)最好還是封裝一下芋类。

參考文檔:https://github.com/axios/axios

0x06箭頭函數(shù)

通過上面的幾段代碼不知道你有沒有發(fā)現(xiàn)一個東西

render: (h, params) => {
},
click: () => {
   this.show(params.index)
}

這個其實(shí)也是一種函數(shù)的形式隆嗅,一般情況下你可能更習(xí)慣用傳統(tǒng)的function,但是你沒有想過為什么很多示例中都用箭頭函數(shù)侯繁?

<script>
    export default {
        data () {
            return {
                stacks: []
            }
        },
        methods: {
            envList: function (groupID) {
                this.$http.get('/api/stacks/').then((response) => {
                    this.stacks = response.data
                    console.log(this.stacks)
                })
            },
        }
    }
</script>

就像上面的代碼胖喳,如果不用箭頭函數(shù)會怎樣?

<script>
    export default {
        data () {
            return {
                stacks: []
            }
        },
        methods: {
            envList: function (groupID) {
                this.$http.get('/api/stacks/').then(function(response) {
                    this.stacks = response.data
                    console.log(this.stacks)
                })
            },
        }
    }
</script>

如果你運(yùn)行上面這段代碼你就會發(fā)現(xiàn)報錯了贮竟。在傳統(tǒng)的function中this是訪問不到data中return的數(shù)據(jù)的丽焊。

0x07如何組件化

組件化有兩個好處,一是代碼復(fù)用咕别,二是解耦技健。
最常見的需求是把模態(tài)框組件化,這樣就可以避免模態(tài)框的代碼耦合在頁面的代碼中惰拱。

<script>
    export default {
        props: {
            title: ''
        },
        data() {
            return {
                show: false,
                loading: false,
            }
        },
        methods: {
            open: function (id) {
                this.show = true;

                if (id !== undefined) {
                    group.getById(id, (body) => {
                        this.formValidate = body.data;
                    })
                }
            },
            submit: function (name) {
            },
        }
    }
</script>

組件的代碼其實(shí)跟普通頁面的代碼差別不大雌贱。就是多了一個props,里面包含了這個組件的屬性偿短。比如這里定義了一個title欣孤,那么在使用的時候你就可以傳一個title進(jìn)來。

<ModalCreation ref="modalCreation" @on-success="refreshList" title="創(chuàng)建服務(wù)"></ModalCreation>

可以看到昔逗,這個組件還提供了一個on-success的事件降传,那么這是怎么做到的呢?

其實(shí)也很簡單勾怒,只需要在組件內(nèi)執(zhí)行this.$emit('on-success', body.data.id);即可發(fā)送一個事件出來婆排。

那么如何優(yōu)雅的調(diào)起組件呢?

$refs.modalCreation.open()

0x08Vue到底是什么

官方的介紹是:它是一套用于構(gòu)建用戶界面的漸進(jìn)式框架笔链。 但是對于初學(xué)者來說還是云里霧里泽论。這里的重點(diǎn)其實(shí)是構(gòu)建,簡單來說就是你按照vue的方式寫html卡乾、css和js,然后它會幫你編譯成瀏覽器可以運(yùn)行的js文件缚够。從本質(zhì)上說幔妨,前端技術(shù)還是html、css和js這三大件谍椅,早期前端開發(fā)是直接寫原生js代碼误堡,現(xiàn)在是用vue或者react的方式。其實(shí)跟后端常見的MVC結(jié)構(gòu)類似雏吭,早期PHP也是直接寫原生PHP锁施,每個php文件里各種include、require,后來才有的各種框架悉抵,像Yaf肩狂、TP等。

0x09如何部署

這個問題的答案其實(shí)有很多種姥饰。它是由你的系統(tǒng)架構(gòu)決定的傻谁。但是在將如何部署之前需要先講一個概念——SPA(單頁面應(yīng)用)。

SPA即一個html列粪,全站只有一個html审磁,內(nèi)容如下

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <title>Chons</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <link rel="stylesheet" href="/dist/main.css">
</head>

<body>
    <div id="app"></div>
    <script type="text/javascript" src="/dist/vendors.js"></script>
    <script type="text/javascript" src="/dist/main.js"></script>
</body>
</html>

Vue編譯出來的文件其實(shí)初始的html就只有上面這一點(diǎn)。也就是說岂座,服務(wù)端只需要渲染這一個html文件态蒂,其他所有的事兒都交給js去處理了。

說回如何部署费什,實(shí)際上要做的事就是在服務(wù)端輸出這個html文件和css钾恢、js。

一般來說吕喘,在前后端分離的架構(gòu)中赘那,這部分代碼是屬于前端的工作,那么前端工程師們通常會用node來渲染html氯质。

而如果你是前后端自己一個人開發(fā)募舟,你可以直接使用后端服務(wù)來輸出這個html。

這里有一個坑是前后端路由問題闻察。前端路由實(shí)際上有三種模式拱礁,具體解釋如下:

### mode

*   類型: `string`

*   默認(rèn)值: `"hash" (瀏覽器環(huán)境) | "abstract" (Node.js 環(huán)境)`

*   可選值: `"hash" | "history" | "abstract"`

    配置路由模式:

    *   `hash`: 使用 URL hash 值來作路由。支持所有瀏覽器辕漂,包括不支持 HTML5 History Api 的瀏覽器呢灶。

    *   `history`: 依賴 HTML5 History API 和服務(wù)器配置。查看 [HTML5 History 模式](https://router.vuejs.org/zh-cn/essentials/history-mode.html)钉嘹。

    *   `abstract`: 支持所有 JavaScript 運(yùn)行環(huán)境鸯乃,如 Node.js 服務(wù)器端。**如果發(fā)現(xiàn)沒有瀏覽器的 API跋涣,路由會自動強(qiáng)制進(jìn)入這個模式缨睡。**

hash模式實(shí)際上是采用錨的方式,也就是你見過的一些后臺網(wǎng)站的網(wǎng)址是http://www.ybc.com/#/user/home

這種模式的路由你可以只在服務(wù)端配置根路徑/的路由輸出html就可以了陈辱,因?yàn)椴徽?號后面輸入什么都會打到后端路由的根路徑下奖年。

但是,如果你想去掉#號呢沛贪,那就需要使用history模式陋守,這種模式就要求服務(wù)端所有的路由全部輸出那個html震贵。

0x0A開發(fā)環(huán)境下如何訪問靜態(tài)文件

如果你是采用后端渲染的方式,那么為了統(tǒng)一流程水评,在開發(fā)環(huán)境下也是需要由后端代理前端路由猩系。那么問題就來了,線上環(huán)境時npm run build打包出來的靜態(tài)文件之碗,直接掛載靜態(tài)文件所在目錄就行了蝙眶。那在開發(fā)環(huán)境還沒有打包,如何訪問到正在開發(fā)的靜態(tài)文件呢褪那?這里就有一個webpack-dev-server的坑幽纷。

在開發(fā)環(huán)境下當(dāng)你執(zhí)行npm run dev的時候?qū)嶋H上是啟動了webpack提供的一個簡易web-server,即webpack-dev-server博敬。它的作用是就是把編譯好的靜態(tài)文件掛載起來讓你能夠訪問友浸。所以你會發(fā)現(xiàn)你無論如何也找不到開發(fā)過程中生成的靜態(tài)文件,因?yàn)樗揪蜎]有輸出出來偏窝,而是在內(nèi)存中收恢。

好在webpack-dev-server還是提供了一個方式可以讓我們看到這些文件 http://localhost:8080/webpack-dev-server 如下圖:

image.png

找到這些靜態(tài)文件就好辦了,既然沒有生成文件祭往,那我們只能在后端服務(wù)中代理這些靜態(tài)文件

func main() {
    app := neo.App()
    app.Conf.Parse("conf/local.toml")
    api.Register(app)

    indexTpl := "index.html"
    if conf.Tree.GetEnv() == ENV {
        app.Get("/static/*", func(ctx *neo.Ctx) (int, error) {
            resp, err := http.Get("http://localhost:8080" + ctx.Req.URL.String())
            if err != nil {
                log.Println(err.Error())
            }
            respBody, err := ioutil.ReadAll(resp.Body)
            ctx.Res.Header().Set("Content-Type", resp.Header.Get("Content-Type"))
            return resp.StatusCode, ctx.Res.Raw(respBody)
        })
    } else {
        indexTpl = "index_prod.html"
        app.Serve("/static", "./assets/dist/static")
    }

    app.Templates("./assets/dist/*")
    app.Region().Get("*", func(ctx *neo.Ctx) (int, error) {
        return 200, ctx.Res.Tpl(indexTpl, nil)
    })

    app.Start()
}

0x0B結(jié)語

前端的技術(shù)棧實(shí)在是太零散了伦意,幾乎每走一步都是坑。越來越佩服前端大牛們了~

我是閆大伯硼补,一直在踩坑驮肉,踩完后端踩前端
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市已骇,隨后出現(xiàn)的幾起案子离钝,更是在濱河造成了極大的恐慌,老刑警劉巖褪储,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卵渴,死亡現(xiàn)場離奇詭異,居然都是意外死亡鲤竹,警方通過查閱死者的電腦和手機(jī)浪读,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辛藻,“玉大人瑟啃,你說我怎么就攤上這事】” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵屁奏,是天一觀的道長岩榆。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么勇边? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任犹撒,我火速辦了婚禮,結(jié)果婚禮上粒褒,老公的妹妹穿的比我還像新娘识颊。我一直安慰自己,他們只是感情好奕坟,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布祥款。 她就那樣靜靜地躺著,像睡著了一般月杉。 火紅的嫁衣襯著肌膚如雪刃跛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天苛萎,我揣著相機(jī)與錄音桨昙,去河邊找鬼。 笑死腌歉,一個胖子當(dāng)著我的面吹牛蛙酪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播翘盖,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼桂塞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了最仑?” 一聲冷哼從身側(cè)響起藐俺,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泥彤,沒想到半個月后欲芹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吟吝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年菱父,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片剑逃。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡浙宜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蛹磺,到底是詐尸還是另有隱情粟瞬,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布萤捆,位于F島的核電站裙品,受9級特大地震影響俗批,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜市怎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一岁忘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧区匠,春花似錦干像、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至揩懒,卻和暖如春什乙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背已球。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工臣镣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人智亮。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓日杈,卻偏偏與公主長得像愉豺,于是被迫代替她去往敵國和親爱榕。 傳聞我的和親對象是個殘疾皇子臊诊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359

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