# 網頁實作(1) 登入頁面 ###### tags: `VueJS` `golang` 最近開始想嘗試製作看看網頁,雖然沒有什麼方向,但先從大多數網站都有的登入開始製作看看吧! 首先登入頁面一般都會有帳號跟密碼的輸入,由於本人不是前端專業,就先簡單用bootstrap+Vue弄一個出來吧! 如果不知道怎麼安裝及使用Vue的話請走[這邊](https://hackmd.io/@JiFang/HyCMXJ9tu) ## 起步 ```htmlembedded= <!-- components/Login.vue --> <template> <div> <b-form @submit="onSubmit"> <b-form-group class="input-block" label="Account" label-for="input-1" valid-feedback="ok!" :invalid-feedback="invalidFeedback" > <b-form-input id="input-1" v-model="user.username" placeholder="Your username" :state="usernameState" required ></b-form-input> </b-form-group> <b-form-group class="input-block" label="Password" label-for="input-2"> <b-form-input id="input-2" v-model="user.password" type="password" placeholder="Your password" required ></b-form-input> </b-form-group> <b-button type="submit" variant="primary">Submit</b-button> </b-form> <router-link id="signUp" to="/">Or sign up here!</router-link> </div> </template> ``` ```css= .input-block { text-align: left; } #signUp { font-size: 12px; } </style> ``` 畫面會長這樣 ![](https://i.imgur.com/dbGpvId.png) 其實外層有多包一層,讓它看起來好看一點,不過不贅述。 ## 綁定資料 ### 1. 輸入綁定 首先要先把輸入的資料跟js綁在一起 ```javascript= export default { data() { return { user: { username: "", password: "", }, loginStatus: "", }; }, ``` 再來我想要判斷帳號輸入是否超過4個字,可以透過bootstrap來做 ```javascript= computed: { invalidFeedback() { return "Enter at least 4 characters."; }, usernameState() { return this.user.username.length > 3; }, }, ``` 這樣invalidFeedback可以判斷輸入的字數並給予提示,usernameState可以給框框一個紅色警示外框。 ### 2. 方法綁定 最後按下submit的時候我們必須要跟後端做串接,需要使用到Vue官方推薦使用的套件`axios`來做API的互動。 #### 安裝 ```bash= npm install --save axios vue-axios ``` 在`main.js`中導入 ```javascript= import axios from 'axios' import VueAxios from 'vue-axios' Vue.use(VueAxios, axios) ``` 這樣就可以使用了!繼續接下去實作! ```javascript= methods: { async onSubmit(event) { event.preventDefault(); await this.axios .post("http://localhost:5050/api/login", JSON.stringify(this.user)) .then((response) => { this.$router.push("/"); this.loginStatus = response.status; }) .catch((error) => { this.loginStatus = error.response.status; alert("Wrong username or password!"); this.user.password = ""; }); }, }, ``` 其實看一看上面的方法就類似爬蟲去抓API的概念,只是我們把它放到網頁上而已(**而且可以直接異步操作!**)。 另外有看到`this.$router`是在成功登入後協助我們導向到首頁的機制。 之後應該會實作成功登入後導向到前一頁,比較符合UX。 這個localhost:5050是我這邊已經實作了一個簡單的後端,程式碼也不難,是使用golang的gin實作。 ```go= import ( "net/http" "github.com/gin-gonic/gin" ) type LoginCommand struct { Username string `json:"username"` Password string `json:"password"` } func Login(ctx *gin.Context) { var loginCmd LoginCommand ctx.BindJSON(&loginCmd) if loginCmd.Username == "max" && loginCmd.Password == "123" { ctx.JSON(http.StatusOK, gin.H{"status": "ok"}) } else { ctx.JSON(http.StatusUnauthorized, gin.H{"status": "wrong auth"}) } } ``` ## 遇到的問題 當前端在跟後端溝通時,會發生一個叫做[CORS](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/CORS)的錯誤 在gin的框架中可以使用middleware來解決這個問題。 ```go= package middleware import "github.com/gin-gonic/gin" func CORSMiddleware() gin.HandlerFunc { return func(c *gin.Context) { c.Writer.Header().Set("Access-Control-Allow-Origin", "*") c.Writer.Header().Set("Access-Control-Allow-Credentials", "true") c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With") c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(204) return } c.Next() } } ``` 寫好之後再router添加middleware即可 ```go= router := gin.Default() router.Use(middleware.CORSMiddleware()) ``` ## 心得 說真的看了上面的一堆東西之後,前端的功好像比後端來得多...只是本人又非前端專業,可能會寫得不太好。 下次來實作cookie登入,搭配後端回傳,順便建立一個簡單的資料庫來玩玩!