Vue全家桶 + webpack 构建单页应用初体验
文章指南
主題
? 承接這上一篇Vue + Webpack 構(gòu)建模塊化開發(fā)框架詳解,我們知道了如何使用webpack對vue進(jìn)行打包,從而開始我們的前端模塊化開發(fā)之路,這一篇在上一篇的基礎(chǔ)上講解 Vue全家桶(vue+vuex+vue-router+axios) + webpack 構(gòu)建一個(gè)單頁應(yīng)用Demo
前提
? 閱讀本篇內(nèi)容之前,除了需要掌握上一篇內(nèi)容中的前提部分的知識,還需要了解以下內(nèi)容?
- Vue全家桶系列,掌握vuex,vue-router以及axios ,不了解請移步官方教程axios-npm,vuex,vue-router
vuex : vuex是一種集中式狀態(tài)管理模式,什么意思呢?我們在模塊化開發(fā)過程中,我們以組件來作為模塊單位,模塊之間存在于不同的命名空間,作用域互不干預(yù),這樣保證了我們模塊之間變量函數(shù)名稱等不會沖突,但是有時(shí)候我們我們需要組件之間共享一些數(shù)據(jù)或者狀態(tài),我們通常的做法是傳參,但是傳參的做法至少有兩個(gè)弊端,一是麻煩(尤其是當(dāng)需要傳遞的參數(shù)很多時(shí)),二是不好管理且冗余(給多個(gè)組件傳參就需要多份參數(shù)列表,而且容易出錯(cuò))。vuex提供的集中式管理就解決了這個(gè)問題,通過把要共享的數(shù)據(jù)或狀態(tài)集中起來管理,別的組件需要時(shí)就去訪問變更,大大提高了可維護(hù)性和開發(fā)效率
vue-router : vue-router是一個(gè)前端路由管理器,這個(gè)和后端常聽說的路由有些不同(個(gè)人覺得),這里的路由管理器更像是一個(gè)組件注冊器,vue-router為分散的組件注冊一個(gè)路由或者叫地址也未嘗不可,以方便我們控制組件的層級嵌套關(guān)系以及隱藏還是顯示,這樣我們可以很方便高效的構(gòu)建單頁應(yīng)用
axios : axios 和 jquery.ajax/vue-resource一樣 , 都是HTTP異步請求的工具,axios和vue-resource的API很像,但是個(gè)人覺得,axios的API更豐富一些
正文
?本文的小Demo大概功能就是一個(gè)登陸的功能,我們這里app.vue封裝了一個(gè)登陸組件,success.vue封裝了一個(gè)提示面板,通過vuex來集中管理登陸狀態(tài),用vue-router來路由提示面板,用axios來異步提交到一個(gè)跨域的服務(wù)器(這里后臺服務(wù)是nginx+php提供,所以在dev-server中要設(shè)置一個(gè)反向代理,也就是nginx來代理我們的dev-server的請求從而解決axios跨域問題)
先來看看我們的項(xiàng)目結(jié)構(gòu) [自定義的]
這里的目錄設(shè)置,并不是一成不變的金科玉律,也不一定是最好的,讀者可以根據(jù)自己的想法設(shè)定文件結(jié)構(gòu),了解如何配置單入口單出口的webpack.config.js,可以看我的上一篇文章(開頭提到了),或者移步webpack官方網(wǎng)站。本篇內(nèi)容,不再講解過多webpack配置,和上一篇是基本相同的,下面主要講解 Vue全家桶相關(guān)內(nèi)容
index.js
import Vue from 'vue'; import Router from './routers/index-router'; import Store from './stores/index-store'; import App from './components/App.vue';var app = new Vue({ //創(chuàng)建一個(gè)Vue實(shí)例router : Router, //加入路由配置store : Store, //加入狀態(tài)管理components : {App} //加入App組件 }).$mount('#app'); //掛載節(jié)點(diǎn)需要注意的是,路由和狀態(tài)都需要加入一個(gè)vue實(shí)例中去才有意義。這里有一點(diǎn)很有意思,就是在路由router中注冊的組件(success.vue)依然可以訪問到狀態(tài)store實(shí)例,而官方教程上并沒有特別強(qiáng)調(diào)這一點(diǎn),在下面我們可以看到這個(gè)有趣的事情
stores/index-store.js
import Vuex from 'vuex'; import Vue from 'vue'; import axios from 'axios';Vue.use(Vuex); //在vue中加入Vuex插件 const Store = new Vuex.Store({ //實(shí)例化一個(gè)Storestate : { //這里是我們需要集中管理的登陸狀態(tài)account : "ads",password : "123456",islogin : null},mutations : { // 這是唯一可以變更state的途徑,需要通過一個(gè)提交updateAccount(state,payload){ //具有載荷的mutationstate.account = payload.account},updatePassword(state,payload){state.password = payload.password},islogin(state,payload){if(payload == 1){state.islogin = true}else if(payload == 0){state.islogin = false}}},actions : { //這是可以支持異步執(zhí)行提交的actionslogin (context,payload){//這里是去訪問我們的反向代理服務(wù)器上的一個(gè)php文件axios.get('/index.php',{params : {account : payload.account,password : payload.password}}).then(function(response){if(response.data.code == 'success'){//變更store狀態(tài)context.commit('islogin',1) //這里做了在異步邏輯中的狀態(tài)提交}else{context.commit('islogin',0)}}).catch(function(error){console.log(error)alert('fail')})}} })export default Store我們這里的Store有三個(gè)屬性,state是我們需要集中管理的狀態(tài)或者數(shù)據(jù), mutations是維護(hù)變更我們狀態(tài)的一個(gè)方式, actions是為了在異步邏輯中提交狀態(tài)的一個(gè)中轉(zhuǎn)站,需要注意的是:
在實(shí)例化Store之前,必須先 Vue.use(Vuex) ,先在vue中加入Vuex插件這里需要說一下的是,如何開啟dev-server的proxy,讓nginx來代理axios的請求,也就是跨域訪問了(因?yàn)閐ev-server跑的是8080端口,nginx跑的是80端口,不設(shè)置代理的話瀏覽器將拒絕跨域訪問),感覺很深奧,其實(shí)很簡單,我們需要修改一下webpack.config.js中devServer的配置 :
webpack.config.js
devServer : {contentBase : './dist',watchContentBase : true,compress : true,port : 8080,hot : true,inline : true, //開啟頁面自動刷新open : true,proxy : {'/index.php' : {target : 'http://localhost:80/phpinfo.php',secure : false}}}然后,我們的axios在配置url時(shí)使用 /index.php,就可以相當(dāng)于訪問http://localhost:80/phpinfo.php
routers/index-router.js
import VueRouter from 'vue-router'; import Vue from 'vue'; import success from '../components/success.vue';// 組件注冊路由,這里success組件注冊路由是'/app' var routes = [{path : '/app',component : success} ] Vue.use(VueRouter); //在vue中加入VueRouter插件 var Router = new VueRouter({ //實(shí)例化一個(gè)routerroutes //這里的寫法相當(dāng)于 routes:routes })export default Router;這里的路由只注冊了一個(gè)組件,vue-router的能力遠(yuǎn)不止如此,還可以嵌套定義組件的層級關(guān)系,更多到官方文檔了解 ,路由器和狀態(tài)管理器一樣都是vue官方核心插件,使用前都需要先 Vue.use(VueRouter) ,我們其實(shí)可以看到,這里把路由和狀態(tài)分別從vue實(shí)例中抽離出來,單獨(dú)管理,通過暴露實(shí)例Store Router,加入到vue實(shí)例中去,這樣可以方便debug和后期維護(hù)
components/App.vue 和 components/success.vue
App.vue
<template><div><input type="text" v-model="account"><input type="password" v-model="password"><button type="button" @click="login">show</button></div> </template> <script>export default {data : function(){return {account : "",password : ""}},created : function(){this.account = this.$store.state.accountthis.password = this.$store.state.password},watch : { //偵聽屬性account : function(){ //當(dāng)accout改變就立即提交狀態(tài)this.$store.commit('updateAccount',{account : this.account})},// 當(dāng)password改變就立即提交狀態(tài)password : function(){this.$store.commit('updatePassword',{password : this.password})}},methods : {login : function(){ //通過分發(fā)到action,來異步請求登錄服務(wù),并變更狀態(tài)this.$store.dispatch('login',{account : this.account,password : this.password})this.$router.push('/app');//同時(shí)顯示登陸狀態(tài)}}} </script> <style scoped>input {height: 40px;width: 300px;border: 1px solid blue;box-shadow: none;} </style>success.vue
<template><div><p>{{islogin}}</p></div> </template> <script>export default {computed : { //計(jì)算屬性//動態(tài)響應(yīng)狀態(tài)的變更islogin : function(){var islogin = this.$store.state.isloginif(islogin == null){return 'No option'}else if(islogin == true){return 'Login Success'}else if(islogin == false){return 'Login Fail'}}}} </script> <style scoped>p {height: 40px;text-align: center;} </style>templates/index.html
<!DOCTYPE html> <html> <head><meta charset="utf-8"><title>index</title> </head> <body><div id="app"><!-- App組件渲染出口 --><App></App><!-- 注冊路由的組件渲染出口 --><router-view></router-view></div> </body> </html>總結(jié)
好了,到此為止,代碼基本完成,我們來理一理,vue+vuex+vue-router以及組件之間是如何配合工作的?
用戶在App.vue組件中輸入,v-model雙向綁定了App組件中的data,App組件中的偵聽屬性發(fā)現(xiàn)data改動,立即向vuex的Store實(shí)例提交了狀態(tài)變更,當(dāng)用戶點(diǎn)擊show,App組件中methods.login事件被觸發(fā),它向Store實(shí)例發(fā)起一個(gè)分發(fā),并導(dǎo)航到/app,Store的action收到分發(fā)調(diào)用axios去異步請求位于localhost:80下的php后臺服務(wù),得到的登陸狀態(tài)立即提交,與此同時(shí),Router去渲染/app路由對應(yīng)的組件到模板中去,于是我們就可以看到一個(gè)動態(tài)響應(yīng)式的狀態(tài)提示了
總結(jié)
以上是生活随笔為你收集整理的Vue全家桶 + webpack 构建单页应用初体验的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: django学习(2)----APP
- 下一篇: IC攻城狮求职宝典 01 2018年IC