使用vue3创建vue项目_如何使用Go和Vue建立真实的项目

使用vue3创建vue项目

When I first started with Go programming I found it pretty hard to get my head around it. It was way more low-level than anything else I had ever coded in.

当我刚开始使用Go编程时,我发现很难理解。 它比我以前编写的任何其他代码都更底层。

Fast forward a few months and now I'm a total fan and use it for a lot of projects.

快进几个月,现在我是一个狂热的粉丝,并将其用于许多项目。

In this article, I'll show you how I set up a full-stack web application with Go and Vue.

在本文中,我将向您展示如何使用Go和Vue设置完整的Web应用程序。

Let's dive in!

让我们潜入吧!

我们将要创造的 (What we're going to create)

I thought it would be cool to create a website thumbnail generator. The idea is that you enter a website URL and the application will generate a thumbnail of that website for you.

我认为创建网站缩略图生成器会很酷。 想法是您输入一个网站URL,应用程序将为您生成该网站的缩略图。

设置Go模块 (Setting up a Go module)

First, I create a new directory. Then I set up a Go module by running the following command.

首先,我创建一个新目录。 然后,我通过运行以下命令来设置Go模块。

go mod init github.com/Dirk94/website-thumbnail-generator

This will create a go.mod file that keeps track of all the module dependencies. This is similar to the package.json file in a node project.

这将创建一个go.mod文件,该文件跟踪所有模块依赖性。 这类似于节点项目中的package.json文件。

Next, I create a new directory main in which I add a server.go file. This will be the main entry point of the application.

接下来,我创建一个新的目录main在其中添加server.go文件。 这将是应用程序的主要入口点。

For now, let's just print a "hello world" message.

现在,让我们只打印“ hello world”消息。

package main

import "fmt"

func main() {
	fmt.Println("Hello world")
}

To run the program I run the following command from the project directory.

要运行该程序,请从项目目录运行以下命令。

go run main/server.go
Hello world

Great, so far everything works! 🙌

太好了,到目前为止一切正常! 🙌

设置网络服务器 (Setting up a web server)

We should create a web server that will listen for incoming requests.

我们应该创建一个Web服务器来侦听传入的请求。

Let's update the main function.

让我们更新主要功能。

func main() {
	http.HandleFunc("/", homePageHandler)

	fmt.Println("Server listening on port 3000")
	log.Panic(
		http.ListenAndServe(":3000", nil),
	)
}

This will start up a web server and listen on port 3000.

这将启动Web服务器并监听端口3000。

Any request coming in will be handled by the homePageHandler function. This does not yet exist so let's create it.

任何homePageHandler请求都将由homePageHandler函数处理。 目前尚不存在,因此让我们创建它。

func homePageHandler(w http.ResponseWriter, r *http.Request) {
	_, err := fmt.Fprintf(w, "hello world")
	checkError(err)
}

func checkError(err error) {
	if err != nil {
		log.Panic(err)
	}
}

All this function does is write "hello world" to the http.ResponseWriter

此功能所做的全部工作就是将“ hello world”写入http.ResponseWriter

The checkError function is simply a handy function that will stop the program and print a stack trace if the error is not nil.

checkError函数只是一个方便的函数,如果error不是nil,它将停止程序并打印堆栈跟踪。

When running the program the web server prints the "hello world" message correctly!

运行该程序时,Web服务器将正确打印“ hello world”消息!

创建Vue项目 (Creating the Vue project)

To create a new Vue project I run the following command from the project directory.

要创建一个新的Vue项目,请从项目目录运行以下命令。

vue create frontend

This creates a lot of files but don't be overwhelmed. Let's begin by running the Vue development server.

这会创建很多文件,但不会被淹没。 让我们从运行Vue开发服务器开始。

yarn serve

When navigating to localhost:8081 you can see that the Vue app works!

导航到localhost:8081时,您可以看到Vue应用程序正常运行!

Alright, let's clean up the frontend directory a bit.

好吧,让我们稍微整理一下前端目录。

For starters, I delete the assets and components directory as I won't use them.

首先,我将删除assetscomponents目录,因为我不会使用它们。

Then I update the App.vue file.

然后,我更新App.vue文件。

<template>
  <div id="app" class="container">
    <div class="row">
      <div class="col-md-6 offset-md-3 py-5">
        <h1>Generate a thumbnail of a website</h1>

        <form v-on:submit.prevent="makeWebsiteThumbnail">
          <div class="form-group">
            <input v-model="websiteUrl" type="text" id="website-input" placeholder="Enter a website" class="form-control">
          </div>
          <div class="form-group">
            <button class="btn btn-primary">Generate!</button>
          </div>
        </form>
      </div>
    </div>
  </div>
</template>

I use the v-model tag and I call a makeWebsiteThumbnail function when the form submits. Right now these don't exist. Let's add them.

我使用v-model标记,并在表单提交时调用makeWebsiteThumbnail函数。 现在这些都不存在。 让我们添加它们。

<script>
export default {
  name: 'App',

  data() { return {
    websiteUrl: '',
  } },

  methods: {
    makeWebsiteThumbnail() {
      console.log(`I should create a website thumbnail of ${this.websiteUrl}`);
    }
  }
}
</script>

I'm also using some Bootstrap 4 classes, so for that to work I must add the bootstrap CSS to the public/index.html file.

我还使用了一些Bootstrap 4类,因此要使其正常工作,我必须将bootstrap CSS添加到public/index.html文件中。

<!DOCTYPE html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
      
      <!--- The other stuff in the head tag here... -->
  </head>

Alright, let's fire up the web server and check if we see the log message.

好了,让我们启动Web服务器并检查是否看到日志消息。

Nice, it works! 🔥

很好,可以用! 🔥

创建网站缩略图 (Creating a website thumbnail)

To create the website thumbnail I'm going to use screenshotapi.net. That way I only have to call an API to do the heavy lifting for me.

要创建网站缩略图,我将使用screenshotapi.net 。 这样,我只需要调用API即可为我完成繁重的工作。

First I install axios.

首先,我安装axios。

yarn add axios

Then I import it in the App.vue file.

然后,将其导入App.vue文件中。

<script>
  import axios from 'axios';
  
  export default {
    name: 'App', 
    
    // The rest here...

Next, I update the makeWebsiteThumbnail function to actually call the screenshot API.

接下来,我更新makeWebsiteThumbnail函数以实际调用屏幕快照API。

makeWebsiteThumbnail() {
  axios.post("https://screenshotapi.net/api/v1/screenshot", {
    token: "SCREENSHOTAPI_TOKEN",
    url: this.websiteUrl,
    width: 1920,
    height: 1080,
    output: 'json',
    thumbnail_width: 300
  })
  .then((response) => {
    this.thumbnailUrl = response.data.screenshot;
  })
  .catch((error) => {
    window.alert(`The API returned an error: ${error}`);
  })
}

Make sure to replace the SCREENSHOTAPI_TOKEN with your token.

确保用您的令牌替换SCREENSHOTAPI_TOKEN

I set the variable thumbnailUrl to the screenshot URL that is created by the API. To make this work I have to add 2 things.

我将变量thumbnailUrl设置为由API创建的屏幕快照URL。 为了使这项工作,我必须添加两件事。

First, I add the thumbnailUrl variable to the Vue data object.

首先,我将thumbnailUrl变量添加到Vue data对象。

data: {
  websiteUrl: '',
  thumbnailUrl: '',
},

Second, I create an img tag that will display thumbnailUrl image.

其次,我创建一个img标签,将显示thumbnailUrl图像。

<img :src="thumbnailUrl"/>

Let's spin up the web server and see the result:

让我们启动Web服务器并查看结果:

It shows a thumbnail of freeCodeCamp, nice!

它显示了freeCodeCamp的缩略图,太好了!

将Go和Vue粘合在一起 (Gluing Go and Vue together)

Right now we've used the Vue development server to spin up the front end. It works, but the development server should only be used for local development.

现在,我们已经使用Vue开发服务器加速了前端。 它可以工作,但是开发服务器应仅用于本地开发。

When we host this application in a production environment you will want to use a "real" web server to handle the incoming requests.

当我们在生产环境中托管此应用程序时,您将需要使用“真实的” Web服务器来处理传入的请求。

Luckily we have just such a thing: our Go server.

幸运的是,我们有这样的事情:我们的Go服务器。

The first thing we have to do is compile our frontend.

我们要做的第一件事是编译前端。

yarn run build

This creates a dist directory with the compiled assets.

这将使用已编译资产创建一个dist目录。

We should update the Go server to serve the files from this directory.

我们应该更新Go服务器以提供该目录中的文件。

To do this I update the main function in the main.go file.

为此,我更新了main.go文件中的main函数。

func main() {
	// Serve static files from the frontend/dist directory.
	fs := http.FileServer(http.Dir("./frontend/dist"))
	http.Handle("/", fs)

	// Start the server.
	fmt.Println("Server listening on port 3000")
	log.Panic(
		http.ListenAndServe(":3000", nil),
	)
}

As you can see we simply pass the frontend/dist directory to the fileserver.

如您所见,我们只是将frontend/dist目录传递到文件服务器。

When running the go program and navigating to localhost:3000 you can indeed see the application!

当运行go程序并导航到localhost:3000您确实可以看到该应用程序!

使应用程序更安全 (Making the app more secure)

Right now we have a major security flaw. The screenshot API token is visible in our frontend code.

目前,我们存在一个重大的安全漏洞。 屏幕快照API令牌在我们的前端代码中可见。

This means that anybody that inspects the webpage can steal the token.

这意味着检查网页的任何人都可以窃取令牌。

Let's fix that by using our server to call the screenshot API. That way only the server needs to know the token.

让我们通过使用服务器调用屏幕快照API来解决此问题。 这样,只有服务器需要知道令牌。

In the server.go I create a new function that will listen for any request to the /api/thumbnail endpoint.

server.go我创建了一个新函数,该函数将侦听对/api/thumbnail端点的任何请求。

type thumbnailRequest struct {
	Url string `json:"url"`
}

func thumbnailHandler(w http.ResponseWriter, r *http.Request) {
	var decoded thumbnailRequest

	// Try to decode the request into the thumbnailRequest struct.
	err := json.NewDecoder(r.Body).Decode(&decoded)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	fmt.Printf("Got the following url: %s\n", decoded.Url)
}

For now we just extract and print the URL parameter from the request.

现在,我们仅从请求中提取并打印URL参数。

To make this work I update the main function to use our thumbnailHandler function.

为了完成这项工作,我更新了main函数以使用我们的thumbnailHandler函数。

func main() {
	// Use the thumbnailHandler function 
	http.HandleFunc("/api/thumbnail", thumbnailHandler)

	fs := http.FileServer(http.Dir("./frontend/dist"))
	http.Handle("/", fs)

	fmt.Println("Server listening on port 3000")
	log.Panic(
		http.ListenAndServe(":3000", nil),
	)
}

And finally, I should update the App.vue file to call the Go server instead of the screenshot API.

最后,我应该更新App.vue文件以调用Go服务器,而不是截图API。

makeWebsiteThumbnail() {
  // Call the Go API, in this case we only need the URL parameter.
  axios.post("http://localhost:3000/api/thumbnail", {
    url: this.websiteUrl,
  })
  .then((response) => {
    this.thumbnailUrl = response.data.screenshot;
  })
  .catch((error) => {
    window.alert(`The API returned an error: ${error}`);
  })
}

When testing the new setup I indeed see a log message in the go server.

在测试新设置时,我确实在go服务器中看到一条日志消息。

go run main/server.go
Got the following url: freecodecamp.org

从Go调用屏幕截图API (Calling the screenshot API from Go)

Let's actually call the Screenshot API from our Go server.

让我们实际从Go服务器调用Screenshot API。

To begin I create a struct that holds all the parameters needed to call the Screenshot API.

首先,我创建一个struct ,该struct包含调用Screenshot API所需的所有参数。

type screenshotAPIRequest struct {
	Token          string `json:"token"`
	Url            string `json:"url"`
	Output         string `json:"output"`
	Width          int    `json:"width"`
	Height         int    `json:"height"`
	ThumbnailWidth int    `json:"thumbnail_width"`
}

Then, I update the thumbnailHandler function to create a http POST request and call the API.

然后,我更新thumbnailHandler函数以创建http POST请求并调用API。

func thumbnailHandler(w http.ResponseWriter, r *http.Request) {
	var decoded thumbnailRequest

	// Try to decode the request into the thumbnailRequest struct.
	err := json.NewDecoder(r.Body).Decode(&decoded)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	// Create a struct with the parameters needed to call the ScreenshotAPI.
	apiRequest := screenshotAPIRequest{
		Token:          "SCREENSHOTAPI_TOKEN",
		Url:            decoded.Url,
		Output:         "json",
		Width:          1920,
		Height:         1080,
		ThumbnailWidth: 300,
	}

	// Convert the struct to a JSON string.
	jsonString, err := json.Marshal(apiRequest)
	checkError(err)

	// Create a HTTP request.
	req, err := http.NewRequest("POST", "https://screenshotapi.net/api/v1/screenshot", bytes.NewBuffer(jsonString))
	req.Header.Set("Content-Type", "application/json")

	// Execute the HTTP request.
	client := &http.Client{}
	response, err := client.Do(req)
	checkError(err)

	// Tell Go to close the response at the end of the function.
	defer response.Body.Close();

	// Read the raw response into a Go struct.
	type screenshotAPIResponse struct {
		Screenshot string `json"screenshot"`
	}
	var apiResponse screenshotAPIResponse
	err = json.NewDecoder(response.Body).Decode(&apiResponse)
	checkError(err)

	// Pass back the screenshot URL to the frontend.
	_, err = fmt.Fprintf(w, `{ "screenshot": "%s" }`, apiResponse.Screenshot)
	checkError(err)
}

And when restarting the Go server you can see that the thumbnail generator still works! And as a bonus, nobody can steal our API token now.

重新启动Go服务器时,您会看到缩略图生成器仍然有效! 另外,现在没有人可以窃取我们的API令牌。

结论 (Conclusion)

We've set up a full-stack website thumbnail generator using Go and Vue. The frontend is separated from the backend and we've added an external API in the mix that we call from the Go server.

我们已经使用Go和Vue设置了完整的网站缩略图生成器。 前端与后端是分开的,并且我们在从Go服务器调用的混合中添加了一个外部API。

You can view the live version here and the Github source code here.

您可以在此处查看实时版本,并在此处查看Github源代码

Happy coding!

编码愉快!

翻译自: https://www.freecodecamp.org/news/how-i-set-up-a-real-world-project-with-go-and-vue/

使用vue3创建vue项目

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值