Создайте ленту фотографий с помощью Go и Vue.js
Вам потребуются установленные на вашем компьютере Go и SQLite, а также базовые знания Go и JavaScript.
Многие приложения для социальных сетей позволяют пользователям загружать фотографии, и эти фотографии обычно отображаются на временной шкале для просмотра их подписчиками и другими людьми. Раньше вам приходилось обновлять ленту вручную, чтобы увидеть новые фотографии, загруженные на временную шкалу. Однако современные веб-технологии позволяют просматривать обновления в режиме реального времени без необходимости обновлять страницу вручную.
В этой статье мы рассмотрим, как можно создать ленту фотографий в реальном времени, используя Pusher Channels, GO и немного Vue.js. Каналы толкателя помогает вам «легко создавать масштабируемые уведомления в приложении, чат, графики в реальном времени, геотрекинг и многое другое в ваших веб-приложениях и мобильных приложениях с помощью нашего размещенного API обмена сообщениями pub/sub».
Это предварительный просмотр того, что мы будем строить:
Предпосылки
Прежде чем мы начнем создавать наше приложение, убедитесь, что у вас есть:
- Базовые знания о Идти язык программирования.
- Базовые знания JavaScript (Vue.js).
- Go (версия >= 0.10.x), установленная на вашем компьютере. Проверьте инструкция по установке.
- SQLite (версия >= 3.x), установленный на вашем компьютере. Проверьте инструкция по установке.
Давайте начнем.
Получение приложения Pusher Channels
Первым шагом будет получение приложения Pusher Channels. Нам потребуются учетные данные приложения, чтобы наши функции реального времени работали.
Перейдите на сайт Pusher и создайте учетную запись. После создания учетной записи следует создать новое приложение. Следуйте указаниям мастера создания приложения, после чего вам должны быть предоставлены учетные данные приложения, которые мы будем использовать позже в этой статье.
Теперь, когда у нас есть наше приложение, давайте перейдем к следующему шагу.
Создание нашего приложения Go
Следующее, что мы хотим сделать, это создать приложение Go. В вашем терминале cd
на ваш $GOPATH
и создайте там новый каталог.
$ cd $GOPATH/src
$ mkdir gofoto
$ cd gofoto
💡 Рекомендуется размещать исходный код вашего проекта в
src
подкаталог (например,$GOPATH/src/your_project
или же$GOPATH/src/github.com/your_github_username/your_project
.
Далее мы создадим несколько каталогов, чтобы немного упорядочить наше приложение:
$ mkdir database
$ mkdir public
$ mkdir public/uploads
Это создаст database
а также public
справочник, а также uploads
каталог внутри общедоступного каталога. Мы будем хранить наш файл базы данных внутри database
каталог, мы будем хранить наши общедоступные файлы: HTML и изображения, внутри public
а также uploads
каталог. Создать новый index.html
файл в public
каталог, который был создан.
Теперь давайте создадим наш первый (и единственный) файл Go для этой статьи. Мы постараемся все упростить, поместив весь наш исходный код в один файл. Создать main.go
файл в корне проекта.
В файле вставьте следующее:
<span class="hljs-keyword">package</span> main
<span class="hljs-keyword">import</span> (
<span class="hljs-string">"database/sql"</span>
<span class="hljs-string">"io"</span>
<span class="hljs-string">"net/http"</span>
<span class="hljs-string">"os"</span>
<span class="hljs-string">"github.com/labstack/echo"</span>
<span class="hljs-string">"github.com/labstack/echo/middleware"</span>
_ <span class="hljs-string">"github.com/mattn/go-sqlite3"</span>
pusher <span class="hljs-string">"github.com/pusher/pusher-http-go"</span>
)
Выше мы импортировали некоторые пакеты, которые нам понадобятся для работы с нашим фотопотоком. Нам нужно database/sql
для выполнения SQL-запросов, io
а также os
пакет для нашего процесса загрузки файлов, и net/http
для наших кодов состояния HTTP.
У нас есть некоторые другие внешние пакеты, которые мы импортировали. labstack/echo
пакет это Эхо-фреймворк что мы будем использовать. У нас также есть mattn/go-sqlite3
пакет для SQLite. Наконец, мы импортировали pusher/pusher-http-go
package, который мы будем использовать для запуска событий в Pusher Channels.
Импорт внешних пакетов Go
Прежде чем мы продолжим, давайте загрузим эти пакеты с помощью нашего терминала. Выполните следующие команды ниже, чтобы загрузить пакеты:
$ go get github.com/labstack/echo
$ go get github.com/labstack/echo/middleware
$ go get github.com/mattn/go-sqlite3
$ go get github.com/pusher/pusher-http-go
Обратите внимание, что приведенные выше команды не возвращают никакого подтверждения после завершения установки пакетов. Если вы хотите убедиться, что пакеты действительно были установлены, вы можете просто проверить
$GOPATH/src/github.com
каталог.
Теперь, когда мы загрузили наши пакеты, давайте создадим main
функция. Это функция, которая будет точкой входа нашего приложения. В этой функции мы настроим базу данных приложений, промежуточное ПО и маршруты.
Открой main,go
файл и вставьте следующий код:
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span> {
db := initialiseDatabase(<span class="hljs-string">"database/database.sqlite"</span>)
migrateDatabase(db)
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.File(<span class="hljs-string">"/"</span>, <span class="hljs-string">"public/index.html"</span>)
e.GET(<span class="hljs-string">"/photos"</span>, getPhotos(db))
e.POST(<span class="hljs-string">"/photos"</span>, uploadPhoto(db))
e.Static(<span class="hljs-string">"/uploads"</span>, <span class="hljs-string">"public/uploads"</span>)
e.Logger.Fatal(e.Start(<span class="hljs-string">":9000"</span>))
}
В приведенном выше коде мы создали экземпляр нашей базы данных, используя путь к файлу базы данных. Это создаст файл SQLite, если он еще не существует. Затем мы запускаем migrateDatabase
функция, которая мигрирует базу данных.
Затем мы создаем экземпляр Echo, а затем регистрируем некоторые промежуточные программы. промежуточное ПО регистратора полезен для регистрации информации о HTTP-запросе, когда восстановить промежуточное ПО «восстанавливается после паники в любом месте цепочки, печатает трассировку стека и передает управление централизованному HTTPErrorHandler».
Затем мы настраиваем некоторые маршруты для обработки наших запросов. Первым обработчиком является File
обработчик. Мы используем это для обслуживания index.html
файл. Это будет точка входа в приложение из внешнего интерфейса. У нас также есть /photos
маршрут, который принимает POST
а также GET
запрос. Нам нужно, чтобы эти маршруты действовали как конечные точки API, которые используются для загрузки и отображения фотографий. Конечный обработчик Static
. Мы используем это для возврата статических файлов, которые хранятся в /uploads
каталог.
Мы, наконец, используем e.Start
чтобы запустить наш веб-сервер Go, работающий на порту 9000. Порт не установлен в камне, и вы можете выбрать любой доступный и неиспользуемый порт, который вам нравится.
На данный момент мы еще не создали большинство функций, на которые ссылались в main
функция, поэтому давайте сделаем это сейчас.
Создание наших функций управления базой данных
в main
функция, на которую мы ссылались initialiseDatabase
а также migrateDatabase
функция. Давайте создадим их сейчас. в main.go
файл, вставьте следующие функции над main
функция:
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">initialiseDatabase</span><span class="hljs-params">(filepath <span class="hljs-keyword">string</span>)</span> *<span class="hljs-title">sql</span>.<span class="hljs-title">DB</span></span> {
db, err := sql.Open(<span class="hljs-string">"sqlite3"</span>, filepath)
<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> || db == <span class="hljs-literal">nil</span> {
<span class="hljs-built_in">panic</span>(<span class="hljs-string">"Error connecting to database"</span>)
}
<span class="hljs-keyword">return</span> db
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">migrateDatabase</span><span class="hljs-params">(db *sql.DB)</span></span> {
sql := <span class="hljs-string">`
CREATE TABLE IF NOT EXISTS photos(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
src VARCHAR NOT NULL
);
`</span>
_, err := db.Exec(sql)
<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
<span class="hljs-built_in">panic</span>(err)
}
}
в initialiseDatabase
мы создаем экземпляр базы данных SQLite, используя файл базы данных, и возвращаем этот экземпляр. в migrateDatabase
мы используем экземпляр базы данных, возвращенный в предыдущей функции, для выполнения миграции SQL.
Давайте создадим структуру данных для нашей фотографии и фотоколлекции.
Создание наших структур данных
Следующее, что мы сделаем, это создадим структуру данных для наших типов объектов. Мы создадим Photo
структура и PhotoCollection
структура. Photo
структура будет определять, как будет представлена типичная фотография, в то время как PhotoCollection
будет определять, как будет представлена коллекция фотографий.
Открой main.go
файл и вставьте следующий код над initialiseDatabase
функция:
<span class="hljs-keyword">type</span> Photo <span class="hljs-keyword">struct</span> {
ID <span class="hljs-keyword">int64</span> <span class="hljs-string">`json:"id"`</span>
Src <span class="hljs-keyword">string</span> <span class="hljs-string">`json:"src"`</span>
}
<span class="hljs-keyword">type</span> PhotoCollection <span class="hljs-keyword">struct</span> {
Photos []Photo <span class="hljs-string">`json:"items"`</span>
}
Создание наших функций обработчика маршрута
Далее давайте создадим функции для наших маршрутов. Открой main.go
файл и вставьте в него следующий файл:
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">getPhotos</span><span class="hljs-params">(db *sql.DB)</span> <span class="hljs-title">echo</span>.<span class="hljs-title">HandlerFunc</span></span> {
<span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(c echo.Context)</span> <span class="hljs-title">error</span></span> {
rows, err := db.Query(<span class="hljs-string">"SELECT * FROM photos"</span>)
<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
<span class="hljs-built_in">panic</span>(err)
}
<span class="hljs-keyword">defer</span> rows.Close()
result := PhotoCollection{}
<span class="hljs-keyword">for</span> rows.Next() {
photo := Photo{}
err2 := rows.Scan(&photo.ID, &photo.Src)
<span class="hljs-keyword">if</span> err2 != <span class="hljs-literal">nil</span> {
<span class="hljs-built_in">panic</span>(err2)
}
result.Photos = <span class="hljs-built_in">append</span>(result.Photos, photo)
}
<span class="hljs-keyword">return</span> c.JSON(http.StatusOK, result)
}
}
<span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">uploadPhoto</span><span class="hljs-params">(db *sql.DB)</span> <span class="hljs-title">echo</span>.<span class="hljs-title">HandlerFunc</span></span> {
<span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(c echo.Context)</span> <span class="hljs-title">error</span></span> {
file, err := c.FormFile(<span class="hljs-string">"file"</span>)
<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
<span class="hljs-keyword">return</span> err
}
src, err := file.Open()
<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
<span class="hljs-keyword">return</span> err
}
<span class="hljs-keyword">defer</span> src.Close()
filePath := <span class="hljs-string">"./public/uploads/"</span> + file.Filename
fileSrc := <span class="hljs-string">" + file.Filename
dst, err := os.Create(filePath)
<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
<span class="hljs-built_in">panic</span>(err)
}
<span class="hljs-keyword">defer</span> dst.Close()
<span class="hljs-keyword">if</span> _, err = io.Copy(dst, src); err != <span class="hljs-literal">nil</span> {
<span class="hljs-built_in">panic</span>(err)
}
stmt, err := db.Prepare(<span class="hljs-string">"INSERT INTO photos (src) VALUES(?)"</span>)
<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
<span class="hljs-built_in">panic</span>(err)
}
<span class="hljs-keyword">defer</span> stmt.Close()
result, err := stmt.Exec(fileSrc)
<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
<span class="hljs-built_in">panic</span>(err)
}
insertedId, err := result.LastInsertId()
<span class="hljs-keyword">if</span> err != <span class="hljs-literal">nil</span> {
<span class="hljs-built_in">panic</span>(err)
}
photo := Photo{
Src: fileSrc,
ID: insertedId,
}
<span class="hljs-keyword">return</span> c.JSON(http.StatusOK, photo)
}
}
в getPhotos
мы просто запускаем запрос, чтобы получить все фотографии из базы данных и вернуть их клиенту в виде ответа JSON. в uploadPhoto
методом мы сначала получаем файл для загрузки, затем загружаем его на сервер, а затем запускаем запрос, чтобы вставить новую запись в photos
таблица с только что загруженной фотографией. Мы также возвращаем ответ JSON от этой функции.
Добавление поддержки реального времени в наше приложение Go
Следующее, что мы хотим сделать, это инициировать событие, когда новая фотография загружается на сервер. Для этого мы будем использовать HTTP-библиотека Pusher Go.
в main.go
файл вставьте следующее выше определения типа для Photo
а также PhotoCollection
:
<span class="hljs-keyword">var</span> client = pusher.Client{
AppId: <span class="hljs-string">"PUSHER_APP_ID"</span>,
Key: <span class="hljs-string">"PUSHER_APP_KEY"</span>,
Secret: <span class="hljs-string">"PUSHER_APP_SECRET"</span>,
Cluster: <span class="hljs-string">"PUSHER_APP_CLUSTER"</span>,
Secure: <span class="hljs-literal">true</span>,
}
Это создаст новый экземпляр клиента Pusher. Затем мы можем использовать этот экземпляр для запуска уведомлений на разные каналы, которые нам нужны. Не забудьте заменить PUSHER_APP_*
keys с ключами, предоставленными при создании приложения Pusher ранее.
Далее перейдите в uploadPhoto
функция в main.go
файл и прямо перед return
в нижней части функции вставьте следующий код:
client.Trigger(<span class="hljs-string">"photo-stream"</span>, <span class="hljs-string">"new-photo"</span>, photo)
Это код, который запускает новое событие при загрузке новой фотографии в наше приложение.
Это будет все для нашего приложения Go. На этом этапе вы можете создать свое приложение и скомпилировать его в двоичный файл, используя go build
команда. Однако для этого урока мы просто временно запустим двоичный файл:
$ go run main.go
Создание нашего интерфейса
Следующее, что мы хотим сделать, это построить наш интерфейс. Мы будем использовать Фреймворк Vue.js и Библиотека Аксиос отправлять запросы.
Открой index.html
файл и вставьте туда следующий код:
<span class="hljs-meta"><!doctype html></span>
<span class="hljs-tag"><<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"utf-8"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1, shrink-to-fit=no"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"
<span class="hljs-tag"><<span class="hljs-name">title</span>></span>Photo Feed<span class="hljs-tag"></<span class="hljs-name">title</span>></span>
<span class="hljs-tag"><<span class="hljs-name">style</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/css"</span>></span><span class="css">
<span class="hljs-selector-id">#photoFile</span> { <span class="hljs-attribute">display</span>: none; }
<span class="hljs-selector-id">#app</span> <span class="hljs-selector-tag">img</span> { <span class="hljs-attribute">max-width</span>: <span class="hljs-number">100%</span>; }
<span class="hljs-selector-class">.image-row</span> { <span class="hljs-attribute">margin</span>: <span class="hljs-number">20px</span> <span class="hljs-number">0</span>; }
<span class="hljs-selector-class">.image-row</span> <span class="hljs-selector-class">.thumbnail</span> { <span class="hljs-attribute">padding</span>: <span class="hljs-number">2px</span>; <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#d9d9d9</span>; }
</span><span class="hljs-tag"></<span class="hljs-name">style</span>></span>
<span class="hljs-tag"></<span class="hljs-name">head</span>></span>
<span class="hljs-tag"><<span class="hljs-name">body</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"app"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">nav</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"navbar navbar-expand-lg navbar-light bg-light"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"navbar-brand"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>></span>GoFoto<span class="hljs-tag"></<span class="hljs-name">a</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span>></span>
<span class="hljs-tag"><<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"navbar-nav mr-auto"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-item active"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">a</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"nav-link"</span> <span class="hljs-attr">v-on:click</span>=<span class="hljs-string">"filePicker"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>></span>Upload<span class="hljs-tag"></<span class="hljs-name">a</span>></span>
<span class="hljs-tag"><<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"file"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"photoFile"</span> <span class="hljs-attr">ref</span>=<span class="hljs-string">"myFiles"</span> @<span class="hljs-attr">change</span>=<span class="hljs-string">"upload"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"file"</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">li</span>></span>
<span class="hljs-tag"></<span class="hljs-name">ul</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">nav</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row justify-content-md-center"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"loading"</span> <span class="hljs-attr">v-if</span>=<span class="hljs-string">"loading"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col-xs-12"</span>></span>
Loading photos...
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"row justify-content-md-center image-row"</span> <span class="hljs-attr">v-for</span>=<span class="hljs-string">"photo in photos"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"col col-lg-4 col-md-6 col-xs-12"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">img</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"thumbnail"</span> <span class="hljs-attr">:src</span>=<span class="hljs-string">"photo.src"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">""</span> /></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"></<span class="hljs-name">div</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"//js.pusher.com/4.0/pusher.min.js"</span>></span><span class="undefined"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">" class="undefined"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">" class="undefined"></span><span class="hljs-tag"></<span class="hljs-name">script</span>></span>
<span class="hljs-tag"></<span class="hljs-name">body</span>></span>
<span class="hljs-tag"></<span class="hljs-name">html</span>></span>
В HTML-файле выше мы определили дизайн для нашего фотопотока. Мы используем Bootstrap 4 и включили CSS в HTML выше. Мы также используем библиотеку Axios, библиотеку Pusher и платформу Vue. Мы добавили ссылки на скрипты внизу HTML-документа.
Далее добавим код Vue.js. В файле HTML добавьте следующий код прямо перед закрытием body
ярлык:
<script type=<span class="hljs-string">"text/javascript"</span>>
<span class="hljs-keyword">new</span> Vue({
<span class="hljs-attr">el</span>: <span class="hljs-string">'#app'</span>,
<span class="hljs-attr">data</span>: {
<span class="hljs-attr">photos</span>: [],
<span class="hljs-attr">loading</span>: <span class="hljs-literal">true</span>,
},
mounted() {
<span class="hljs-keyword">const</span> pusher = <span class="hljs-keyword">new</span> Pusher(<span class="hljs-string">'PUSHER_APP_KEY'</span>, {
<span class="hljs-attr">cluster</span>: <span class="hljs-string">'PUSHER_APP_CLUSTER'</span>,
<span class="hljs-attr">encrypted</span>: <span class="hljs-literal">true</span>
});
<span class="hljs-keyword">let</span> channel = pusher.subscribe(<span class="hljs-string">'photo-stream'</span>)
channel.bind(<span class="hljs-string">'new-photo'</span>, data => <span class="hljs-keyword">this</span>.photos.unshift(data));
axios.get(<span class="hljs-string">'/photos'</span>).then(<span class="hljs-function"><span class="hljs-params">res</span> =></span> {
<span class="hljs-keyword">this</span>.loading = <span class="hljs-literal">false</span>
<span class="hljs-keyword">this</span>.photos = res.data.items ? res.data.items : []
})
},
<span class="hljs-attr">methods</span>: {
<span class="hljs-attr">filePicker</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">let</span> elem = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'photoFile'</span>);
<span class="hljs-keyword">if</span> (elem && <span class="hljs-built_in">document</span>.createEvent) {
<span class="hljs-keyword">let</span> evt = <span class="hljs-built_in">document</span>.createEvent(<span class="hljs-string">"MouseEvents"</span>);
evt.initEvent(<span class="hljs-string">"click"</span>, <span class="hljs-literal">true</span>, <span class="hljs-literal">false</span>);
elem.dispatchEvent(evt);
}
},
<span class="hljs-attr">upload</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
<span class="hljs-keyword">let</span> data = <span class="hljs-keyword">new</span> FormData();
data.append(<span class="hljs-string">'file'</span>, <span class="hljs-keyword">this</span>.$refs.myFiles.files[<span class="hljs-number">0</span>]);
axios.post(<span class="hljs-string">'/photos'</span>, data).then(<span class="hljs-function"><span class="hljs-params">res</span> =></span> <span class="hljs-built_in">console</span>.log(res))
}
}
});
<span class="xml"><span class="hljs-tag"></<span class="hljs-name">script</span>></span></span>
Выше мы создали экземпляр Vue и сохранили свойства photos
а также loading
. photos
Свойство хранит список фотографий и loading
просто содержит логическое значение, указывающее, загружаются фотографии или нет.
в mounted
мы создаем экземпляр нашей библиотеки Pusher. Затем мы слушаем на photo-stream
канал для new-photo
мероприятие. Когда событие срабатывает, мы добавляем новую фотографию из события в photos
список. Мы также отправляем запрос GET на /photos
чтобы получить все фотографии из API. Заменить PUSHER_APP_*
ключи с одним из панели управления Pusher.
в methods
свойство, мы добавили несколько методов. filePicker
запускается при нажатии кнопки «Загрузить» в пользовательском интерфейсе. Он запускает средство выбора файлов, которое позволяет пользователю загружать фотографии. upload
Метод принимает загруженный файл и отправляет запрос POST с файлом в API для обработки.
Это все, что касается внешнего интерфейса, вы можете сохранить файл и перейти к своему веб-браузеру. Посещать чтобы увидеть ваше приложение в действии.
Вот как это будет выглядеть снова:
Вывод
В этой статье мы смогли продемонстрировать, как вы можете использовать Pusher Channels в своем приложении Go, чтобы предоставить вашему приложению функции в реальном времени. Как видно из приведенных выше примеров кода, начать работу с Pusher Channels очень просто. Проверить документация чтобы увидеть другие способы использования Pusher Channels для предоставления пользователям функций в реальном времени.
Исходный код этого приложения доступен на Гитхаб.
Этот пост впервые появился на Блог пушера.