Background: The Gin framework of Golang was used to develop API interfaces of internal back-end of operation and maintenance, providing json-type data response to the outside world. However, the data format of this method is not friendly when browsers access data (because it is an API interface, they usually need to use tools such as postman to verify the interface to return data). To try to use Golang template to combine html for data rendering, but also found that the lack of aesthetic. Then I decided to use the front-end framework to render the back-end data. Because of the advantages of the vue framework, such as simplicity, two-way data binding and so on, I decided to use the vue framework to start my front-end journey. Next, I will briefly explain the example of using Golang back end and vue front end for fusion.
Backend API Based on Gin Framework
Write an API based on Gin framework:
# View source files $ cat main.go /** * @File Name: main.go * @Author: xxbandy @http://xxbandy.github.io * @Email: * @Create Date: 2018-12-02 22:12:59 * @Last Modified: 2018-12-02 22:12:52 * @Description: */ package main import ( _ "fmt" "github.com/gin-gonic/gin" "math/rand" "net/http" ) func HelloPage(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message": "welcome to bgops,please visit https://xxbandy.github.io!", }) } func main() { r := gin.Default() v1 := r.Group("/v1") { v1.GET("/hello", HelloPage) v1.GET("/hello/:name", func(c *gin.Context) { name := c.Param("name") c.String(http.StatusOK, "Hello %s", name) }) v1.GET("/line", func(c *gin.Context) { // Note: During front-end and back-end separation, attention should be paid to cross-domain issues, so request headers need to be set up. c.Writer.Header().Set("Access-Control-Allow-Origin", "*") legendData := []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"} xAxisData := []int{120, 240, rand.Intn(500), rand.Intn(500), 150, 230, 180} c.JSON(200, gin.H{ "legend_data": legendData, "xAxis_data": xAxisData, }) }) } //Define default routing r.NoRoute(func(c *gin.Context) { c.JSON(http.StatusNotFound, gin.H{ "status": 404, "error": "404, page not exists!", }) }) r.Run(":8000") } # Operation procedure $ go run main.go [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) [GIN-debug] GET /v1/hello --> main.HelloPage (3 handlers) [GIN-debug] GET /v1/hello/:name --> main.main.func1 (3 handlers) [GIN-debug] GET /v1/line --> main.main.func2 (3 handlers) # Test-related interfaces $ curl -s localhost:8000/v1/hello | python -m json.tool { "message": "welcome to bgops,please visit https://xxbandy.github.io!" } $ curl -s localhost:8000/v1/hello/bgops Hello bgops $ curl -s localhost:8000/v1/line {"legend_data":["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],"xAxis_data":[120,240,81,387,150,230,180]} # You can see that the interface returns data in a json structure $ curl -s localhost:8000/v1/line | python -m json.tool { "legend_data": [ "\u5468\u4e00", "\u5468\u4e8c", "\u5468\u4e09", "\u5468\u56db", "\u5468\u4e94", "\u5468\u516d", "\u5468\u65e5" ], "xAxis_data": [ 120, 240, 347, 59, 150, 230, 180 ] }
Front-end project based on vue framework
Use vue-cli scaffolding to quickly build a Vue project. Note: The premise is that the node environment is required and there are available npm sources
# View version $ npm -v 2.3.0 #Upgrade npm cnpm install npm -g # Upgrade or install cnpm npm install cnpm -g # Latest stable Edition $ cnpm install vue # Global Installation vue-cli $ cnpm install --global vue-cli # Create a new project based on Web pack template ➜ vue-doc vue init webpack vue-test ? Target directory exists. Continue? Yes ? Project name vue-test ? Project description A Vue.js project ? Author xxbandy ? Vue build standalone ? Install vue-router? Yes ? Use ESLint to lint your code? Yes ? Pick an ESLint preset Standard ? Set up unit tests Yes ? Pick a test runner jest ? Setup e2e tests with Nightwatch? Yes //There are two ways [npm and yarn, if NPM is chosen by default, download resources from the outside world, and may not be able to access Google's outside world] ? Should we run `npm install` for you after the project has been created? (recommended) no vue-cli · Generated "vue-test". # Project initialization finished! # ======================== To get started: cd vue-test npm install (or if using yarn: yarn) npm run lint -- --fix (or for yarn: yarn run lint --fix) npm run dev Documentation can be found at https://vuejs-templates.github.io/webpack $ cd vue-test $ cnpm install ✔ Installed 58 packages ✔ Linked 0 latest versions ✔ Run 0 scripts ✔ All packages installed (used 237ms(network 227ms), speed 0B/s, json 0(0B), tarball 0B) # run compiles web pack static resources based on configuration $ cnpm run dev DONE Compiled successfully in 4388ms > Listening at http://localhost:8080
When cnpm run dev is used, a front-end service runs successfully, so you will see a page similar to the following.
vue renders back-end API data
1. First, take a quick look at the code structure of the vue project.
$ tree -L 1 . . ├── README.md ├── build ├── config ├── index.html ├── node_modules ├── package.json ├── src ├── static └── test # For rapid development, you just need to know the vue-related code in the SRC directory, that is, we see that the welcome page of Vue is under src. $ tree -L 2 src src ├── App.vue ├── assets │ └── logo.png ├── components │ └── HelloWorld.vue ├── main.js └── router └── index.js
Note: You can see that the source part of a vue project consists of several parts
- JS main file main.js
- Vue master file App.vue
- Static file directory assets
- Custom component components
- router directory
Let's first look at the App.vue code
# We can see that there is an img tag in div, which is actually the logo of vue on the welcome page we just saw. # In fact, you can see that the < router-view > tag is used, which actually defines the default component, which is HelloWorld imported below. $ cat App.vue <!--Display template--> <template> <!--Here we use id Selector to bind css Styling--> <div id="app"> <img src="./assets/logo.png"> <router-view></router-view> </div> </template> <script> import HelloWorld from './components/HelloWorld' export default { name: 'helloworld', components: { HelloWorld } } </script> <!--Style code--> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
Let's look at the components/HelloWorld.vue file again:
# Actually, there are some hyperlinks below the welcome page we just saw. $ cat components/HelloWorld.vue <template> <div class="HelloWorld"> <h1>{{ msg }}</h1> <h2>Essential Links</h2> <ul> <li> <a href="https://vuejs.org" target="_blank" > Core Docs </a> </li> <li> <a href="https://forum.vuejs.org" target="_blank" > Forum </a> </li> <li> <a href="https://chat.vuejs.org" target="_blank" > Community Chat </a> </li> <li> <a href="https://twitter.com/vuejs" target="_blank" > Twitter </a> </li> .........
In fact, at this point, we basically know how the whole vue project renders the resources. But let's look at the definition of router.
# It's really about defining how we can access this resource. $ cat router/index.js import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld } ] })
2. Think about what we are going to do next.
Now we know how vue renders the relevant data, and we know about the coding rules, but our data is not local, but an external API, at this time we need to find ways to get vue back-end data.
Yes, at this point, we need asynchronous requests for vue to get data, such as ajax, but in the big front-end era, there is a better tool, axios, and then install Axios in our vue environment:
# Install asynchronous request packages $ cnpm install --save axios
3. vue renders back-end data
Simulate and write a component / HelloWorld component
# Write an ApiData.vue component $ cat components/ApiData.vue <template> <!--Use class To bind css Style file--> <div class="hello"> <!--{{}} Output object attributes and function return values--> <h1>{{ msg }}</h1> <h1>site : {{site}}</h1> <h1>url : {{url}}</h1> <h3>{{details()}}</h3> <h1 v-for="data in ydata" :key="data">{{data}}</h1> <h3 v-for="item in xdata" :key="item">{{item}}</h3> </div> </template> <script> import axios from 'axios' export default { name: 'apidata', // Data is used to define the attributes of the returned data data () { return { msg: 'hello,xxbandy!', site: "bgops", url: "https://xxbandy.github.io", xdata: null, ydata: null, } }, // Method for defining js methods: { details: function() { return this.site }, }, mounted () { // response returns a json{"data": "data", "status", "status code", "status text", "headers": {"content-type": "application/json; charset = utf-8"}, "config", "configuration file", "method", "url","request url", "request body"}. axios.get('http://localhost:8000/v1/line').then(response => (this.xdata = response.data.legend_data,this.ydata = response.data.xAxis_data)) } } </script> <!--Use css Of class selector[Effective Priority of Multiple Styles]--> <style> .hello { font-weight: normal; text-align:center; font-size:8pt; } h3 { text-align:center; font-size:20pt; color:red; } </style>
Add our components to the routing
# Add routing cat router/index.js import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld' // Add our custom API Data component import Hello from '@/components/ApiData' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld }, // Refer to our component here { path: '/xxb', name: 'Hello', component: Hello } ] })
Define our Vue script in the App.vue file
# Add the following <script> import Hello from './components/ApiData' export default { name: 'xxb', components: { Hello } } </script>
Operation service
At this point, we can run the service to detect our program.
# Run under the vue project home directory (since our golang api interface runs on port 8000, the vue port needs to be modified) $ cnpm run dev Your application is running here: http://localhost:8082
![](https://upload-images.jianshu.io/upload_images/2577135-613a2c6379cb739e.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)
![](https://upload-images.jianshu.io/upload_images/2577135-884b34affdce931d.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)
At this point, we can see that vue successfully rendered the API data of the back-end Golang. Although it is only a simple rendering, it has basically achieved the integration of back-end API and front-end vue projects. Next, we need to continue the transformation according to the needs. Welcome to my public number