前端的大體流程:

????????首先是Login登錄組件,當輸入用戶名和密碼之后,發送post請求到后端,然后根據返回的數據的是否正常,如果正常,將返回的token以及用戶名保存到sessionStorage中,并使用導航守衛進行跳轉到主頁面。主頁面中有默認頁面,目前沒有做,本打算默認頁面是顯示所有服務的服務狀態以及可以重啟按鈕等操作的,除了默認按鈕之外就是就是應用名(*寶和*神)。然后當點擊這兩個應用名之后,會顯示相對應的服務名,服務名下面是一個表格,這個表格是公共組件的,里面的數據是從Vuex這個公共組件里面獲取的,也就是當你點擊服務名的時候會將相應的服務名添加到vuex中,這樣做的好處是當你點擊*神的時候,下面的公共組件也會顯示*寶的服務名,當點擊*寶的時候也會顯示*神的服務名。


疑問:對于前端的頁面認證,我使用的是給路由中添加元數據,然后再主入口組件中使用全局守衛進行判斷這個元數據,如果滿足判斷是否已經登錄????????????(去seessionStorage中取值),如果沒有登錄,使用導航守衛跳轉到登錄頁面。

問題:前端已經做了登錄頁面驗證,后端是否還需要使用DRF中的登錄認證組件進行登錄頁面驗證?

如下,定義在入口組件中的全局守衛,相當于一個看門狗,每個請求都會經過這個全局守衛,對元數據是auth:true進行驗證。

image.png


下來根據主頁面來說說主體思路:

1555317885449822.png (1189?446)


先看主入口文件部分內容,導入了很多東西,可以進行全局引用:

import?Vue?from?'vue'
import?App?from?'./App'import?router?from?'./router'????????????????????????#這是路由組件//?elementUI?導入
import?ElementUI?from?'element-ui';
import?'element-ui/lib/theme-chalk/index.css';
//?調用插件
Vue.use(ElementUI);//引入全局的組件
import?Public?from?'./components/Public/Public'????????#這是上圖中所說的公共組件Vue.component(Public.name,Public);//引入Vuex,進行狀態管理????????????????????????????????#這是Vuex,進行狀態管理
import?store?from?'./store'//導入axios????????????????????????????????????????????#這是axios,以后再其他地方使用this.$http.?的方式引用
import?*?as?api?from?'./restful/api'
console.log(api)
Vue.prototype.$http=api;//導入全局樣式
import?'../static/global/global.css'

下來是路由組件:路由組件中children,字體意思是這個組件有孩子組件,這個children是前端同事幫我加的。和自己之前寫的有點差別,不過覺得這個更規范。

import?Vue?from?'vue'
import?Router?from?'vue-router'Vue.use(Router)import?HelloWorld?from?'@/components/AppName/HelloWorld'
import?CaiBao?from?'@/components/CaiBao/CaiBao'
import?HeShen?from?'@/components/HeShen/HeShen'
import?Login?from?'@/components/Login/Login'
import?ServiceStatus??from?'@/components/ServiceStatus/ServiceStatus'export?default?new?Router({linkActiveClass:?"is-active",mode:?'history',routes:[{path:'/',?????????????????????????????????????????????#首先是去找Login組件name:'login',component:Login},{path:'/heyan/detailpage',????????????????????#登錄成功后,登錄組件中會使用導航守衛跳轉到這個name:'HelloWorld',component:HelloWorld,children:[{path:?'/',?????????????????????????????#這個是我在開始時說的那個默認顯示頁面,想用python-ansible-api顯示組件相關信息,還沒做??????????????????????????????????name:?'ServiceStatus',component:ServiceStatus,},{path:'/caibao/:userId',???????????????#當在HelloWorld組件中點擊router-link時跳轉到這里name:'caibao',component:CaiBao,meta:{//如果是true,表示訪問該組件時需要登錄????????#前面說的元數據auth:true}},{path:'/heshen/:userId',????????????#和上面的一樣name:'heshen',component:HeShen,meta:{//如果是true,表示訪問該組件時需要登錄auth:true}},]},]})


App組件中只有一行router-view,和Login組件對應,提供出口。


Login組件:? loginHandler方法是點擊登錄按鈕觸發的,this.$http.userLogin(params)這個是發送axios請求,并攜帶參數,這種發送axios請求的方式之前說到的。然后根據返回的值判斷是否要健token和用戶名存放到sessionStroage,還有就是跳轉到HelloWorld組件中。

methods:{loginHandler(){let?params?=?{username:this.username,pwd:md5(this.password),};console.log(params);this.$http.userLogin(params).then(res=>{console.log(res);if?(!res.data?=="")?{sessionStorage.setItem('access_token',res.data);sessionStorage.setItem('username',res.username);this.$router.push('/heyan/detailpage');}}).catch(err=>{console.log(err);})},}

HelloWorld組件:根據鉤子函數,當這個組件創建的時候會發送一個get請求從而從數據庫中獲取到相應的應用名,然后根據for循環顯示到頁面中,最后使用router-link進行跳轉到路由中的children部分。需要傳遞路由參數params。

<script>
export?default?{name:?'LuffyHeader',data(){return{AppnameList:[],}},created()?{this.getAppnameList();console.log(123)},methods:{getAppnameList(){this.$http.appnameList().then(res=>{//?console.log(res);this.AppnameList?=?res}).catch(err=>{console.log(err);});},}};
</script>

helloworld組件中有兩個子組件里面的代碼是大體相同的,只說一個CaiBao這個組件。

CaiBao組件:當進入這個組件之后首先使用鉤子函數created發送一個get請求,主要是獲取到根據應用的id獲取到相應的服務名。public是公共組件(也是表格),當點擊服務名的時候調用StorageServer方法,我將這個服務名保存到vuex中,起先我是直接保存為數組,后來發現以后如果獲取到分支之后,分支如何和服務名建立關系,所以此處我使用let聲明了一個對象,對面里面保存了服務名和分支名,起先默認是空的。除此之外為了一個服務只保存一次,我將vuex里面中指循環出來,并將服務名保存到一個新的數組中,然后判斷點擊的服務名是否在這個數組中,如果不在添加進去。

<template><div><div?id="test"><el-row><el-button?class="button-style"?type="primary"?v-for='(server,index)?in?servicelist'?:key="server.id"?@click="StorageServer(server.title)">{{server.title}}</el-button></el-row></div><public?/></div>
</template><script>export?default?{name:?"Caibao",data()?{return?{servicelist:?[],}},created()?{this.GetServiceList();},methods:?{GetServiceList()?{//?console.log(this.$route)this.$http.ServiceList(this.$route.params.userId).then(res?=>?{this.servicelist?=?res;//?console.log(this.servicelist)}).catch(err?=>?{console.log(err)})},StorageServer(servername)?{var??StoreService?=?[];let?ServerNameAndBanrch?=?{'servername':"",'branch':null};this.$store.state.ServerNameAndBanrch.forEach(function?(item,index)?{????#這里我使用for循環的方式將vuex值循環出來,然后將服務名追加到#新的數組,如果新增的服務名不在這里,使用dispatc提交到vuex中。StoreService.push(item.servername)});if(StoreService.indexOf(servername)>?-1)?return;ServerNameAndBanrch.servername?=?servername;this.$store.dispatch('addserver',ServerNameAndBanrch);}}}
</script>

下來時public組件,數據到放到了vuex,那應該到拿出來了吧。首先還是使用create進行方法在組件創建的時候去vuex中拿一次數據,然后我們應該實時的監聽vuex中的值,當新增了新的任務之后,我們要實時的顯示到public組件中,所以我使用watch針對vuex中這個數據屬性進行了實時的監聽,然后把新到的數據顯示到頁面中。

<script>export?default?{name:?"Public",data()?{return?{input10:'',tableData:?[/*{servername:?'zyp',branch:"master",},*/]}},created()?{if(this.$store.state.ServerNameAndBanrch.length>0){this.$store.state.ServerNameAndBanrch.map(item?=>{let?obj={};obj.servername?=?item.servername;obj.branch?=?item.branch;this.tableData.push(obj)})}},watch:{'$store.state.ServerNameAndBanrch':{handler:function?()?{this.dataVuex()},deep:?true}},methods:{dataVuex(){console.log(this.$store.state.ServerNameAndBanrch);this.tableData?=?[];if(this.$store.state.ServerNameAndBanrch.length>0){this.$store.state.ServerNameAndBanrch.map(item?=>{let?obj={};obj.servername?=?item.servername;obj.branch?=?item.branch;this.tableData.push(obj)});console.log(this.tableData)}},/*顯示分支:將服務名傳遞到后端執行shell并返回執行結果*/ObtainBranch(index,servername){console.log('test',servername.servername)},/*刪除選項*/serverDelete(index,servername){this.$store.state.ServerNameAndBanrch.splice(index,1)}}}

說了很多,其實真正的功能還沒有說到,也就是上述截圖中的獲取分支,打包,還有重啟這幾個按鈕,這幾個按鈕的代碼沒有寫,但是使用的技術已經測試通過了,下面使用單獨的一篇來進行說明。


針對第一次下前端代碼的感悟:

  1. 第一次寫一定要邏輯清晰,否則就像我一樣修修改改很多次。

  2. js中的基本操作一定要熟悉,如對數組,對象的操作。

  3. 還有就是router-view的使用,曾經自閉了很多次