Несколько недель назад я решил составить список интересных проектов на Vue.js, и по этой причине я начал рыться в Интернете в поисках ценных ресурсов. В конце дня я собрал значительный объем знаний о некоторых полезных API. Среди прочего, мне очень понравился Яндекс Переводчик API; он может взять почти любой текст и вернуть его эквивалент на более чем 90 языках.
Немного поигравшись с API (используя Postman), я решил взять свои знания о Vue.js и заключить их в великолепие этого API. Результат? Я собрал веб-приложение-переводчик Vue.js.
Во время проекта я интегрировал аудио функционально, сославшись на ResponsiveVoiceJS CDN и запустив простую функцию.
Вот визуальное отображение завершенного проекта:
Посмотрим, как я это построил.
Требования
Поскольку мы собираемся создавать это приложение с помощью Progressive Javascript Framework Vue.js, перед тем, как продолжить, мы должны убедиться, что у вас установлено несколько вещей:
Также нам понадобятся:
- API-ключ для использования Яндекс Переводчика API
Чтобы создать учетную запись на Яндексе, перейдите сюда:
Чтобы создать бесплатный ключ API, перейдите сюда:
После того, как зависимости установлены и у вас есть ключ, мы готовы приступить к работе!
Создание проекта
Мы будем создавать этот проект с помощью инструмента Vue-CLI, альтернативой может быть ссылка на Vue.js из CDN, и вы можете сделать это, если захотите.
Мы будем использовать шаблон webpack-simple
, поскольку его не составит труда разработать.
Возможно, вам потребуется сменить владельца для каталога проекта и запустить некоторые из этих команд от имени пользователя root (используя
sudo
)
vue init webpack-simple translator
С помощью этой команды вам нужно будет ответить на несколько строк запроса командной строки:
Давайте перейдем в каталог проекта и установим зависимости:
cd translator
npm install
Создание компонента перевода
Мы создадим ровно один компонент для этого проекта, так как мы не хотим загромождать среду разработки ненужными компонентами. Этот компонент будет содержать два textareas
, расположенных рядом; одна будет содержать текст для перевода, а другая - отображать переведенный текст, обе стороны также будут иметь audio
функциональность.
Давайте создадим каталог components
и файл translate
в каталоге src
нашего только что установленного проекта.
mkdir -p src/components
cd src/components
touch translate.vue
Этот файл будет содержать весь код для компонента translate
.
Написание кода для компонента Translate
Прежде чем мы вообще напишем какой-либо код, давайте подумаем о взаимосвязи между корневым компонентом (App.vue) и дочерним компонентом (translate.vue). Предположим, что основная работа будет выполняться корневым компонентом, поэтому дочерний компонент будет получать реквизиты, регистрировать несколько переменных и emit
событий вплоть до корневого компонента при взаимодействии с пользователем.
Теперь, когда мы понимаем, как это будет работать, давайте напишем код в теге script
для получения свойств и инициализации переменных.
export default {
name: 'translate',
props: {
AvailableLanguages : {
type : Object
},
ResponseText : {
type : String
},
CurrentLanguage : {
type : String
},
TranslateLanguage : {
type : String
}
},
data () {
return {
Text: '',
FromLanguage : "English",
ToLanguage : "French"
}
}
}
Давайте проанализируем приведенный выше код сверху вниз, чтобы понять, что происходит:
- Во-первых, мы экспортируем default, что позволило бы нам импортировать этот компонент в корневой компонент.
- Мы инициализируем переменную
name
, затем получаем и проверяем некоторые реквизиты, очевидно, эти реквизиты будут исходить от корневого компонента. Вот что они собой представляют и чем занимаются:
AvailableLanguages
будет содержать объект доступных для перевода языков, возвращенный API Яндекса.ResponseText
будет содержать переведенный текст для указанного языка, возвращенный API Яндекса.CurrentLanguage
будет кодом для текущего языка, который мы набираем.TranslateLanguage
- это код языка, на котором будет выполнен перевод.
- Наконец, мы инициализируем переменную
Text
(это для вводимого текста) пустой строкой. Затем мы инициализируем две другие переменные,FromLanguage
иToLanguage
, на «английский» и «французский» соответственно. Это переменные, которые будут содержать полное имя (не код) выбранного языка.
Потрясающий.
Написание MarkUp
Получив props
и проинициализировав некоторые переменные в приведенном выше коде, мы должны теперь написать HTML
. В основном мы будем связывать textareas
с соответствующими переменными данных и запускать события при взаимодействии с пользователем. HTML
будет записан в тегах template
, чтобы Vue.js знал, что это MarkUp
, и отображал его во время выполнения.
<div id="parent_translate">
<div id="input">
<div id="imageholder">
<select v-model="FromLanguage" @change="changeFromLanguage">
<option v-for="(lang, code) in AvailableLanguages" :value="code"> {{ lang }} </option>
</select>
<img @click="translateSpeak" src="../assets/speaker.png">
</div>
<textarea placeholder="Type in something here" v-model="Text"></textarea>
<button @click="submit" id="submit">SUBMIT</button>
</div>
<div id="output">
<div id="imageholder">
<select v-model="ToLanguage" @change="changeToLanguage">
<option v-for="(lang, code) in AvailableLanguages" :value="code"> {{ lang }} </option>
</select>
<img @click="responseSpeak" src="../assets/speaker.png">
</div>
<textarea placeholder="Your output goes here" disabled v-model="ResponseText"> </textarea>
</div>
</div>
Давайте внимательно посмотрим на функциональность, связанную с этим MarkUp:
Первый тег select
привязан к переменной данных FromLanguage
с помощью директивы v-model
и запускает обработчик событий changeFromLanguage при изменении его значения.
Тег option
, вложенный в первый тег select
, принимает объект доступных языков (который поступает как свойство из корневого компонента) и просматривает его с помощью директивы v-for
. Директива :value
привязана к переменной code
, поэтому каждый тег опции, созданный во время цикла, имеет свой уникальный code
.
Давайте посмотрим еще на MarkUp:
<select v-model="FromLanguage" @change="changeFromLanguage">
<option v-for="(lang, code) in AvailableLanguages" :value="code"> {{ lang }} </option>
</select>
Тег img
чуть ниже ранее обсужденного тега select
содержит представление изображения для звуковых функций и направляет события щелчка в обработчик событий translateSpeak.
<img @click="translateSpeak" src="../assets/speaker.png">
Первый textarea
довольно прост в том, что он делает, он связывает переменную Text
с собой, так что он отображает заполнитель только тогда, когда в нем нет написанного текста.
<textarea placeholder="Type in something here" v-model="Text"></textarea>
<button @click="submit" id="submit">SUBMIT</button>
Тег button
выполняет единственную функцию; он запускает submit
метод всякий раз, когда по нему щелкают.
После этой точки в MarkUp
оставшийся код представляет собой просто повторение того, что уже было отображено, без новой логики или функций.
Давайте напишем обработчики событий в объекте methods
.
Написание обработчиков событий
Давайте начнем этот раздел с написания обработчиков для полей выбора, они срабатывают всякий раз, когда выбран параметр changed
.
changeFromLanguage:function( ev ) {
let LanguageCode = ev.target.value;
this.$emit('updateFromLanguage', LanguageCode)
},
changeToLanguage:function( ev ) {
let LanguageCode = ev.target.value;
this.$emit('updateToLanguage', LanguageCode)
}
Функция этих двух обработчиков совершенно очевидна. Сначала новая переменная содержит язык code
для выбранной опции, а затем это обновление emitted
для корневого компонента. Также указаны обработчики в корневом компоненте для обработки этих генерируемых событий.
submit:function( ev ){
let Word = this.Text
if ( Word ) {
this.$emit('translate', Word)
}
}
Вышеупомянутый метод отправки вызывается всякий раз, когда нажимается Submit
кнопка, и его простая задача - emit
событие при передаче набранного текста родительскому компоненту.
Прежде чем мы рассмотрим обработчики событий для звуковых функций, мы должны извлечь библиотеку ResponsiveVoiceJS
, потому что мы зависим от нее для звуковых функций, мы можем сделать это, вставив тег script
непосредственно перед закрывающим тегом </body>
файла index.html
. .
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Indie+Flower" rel="stylesheet">
<title>A simple translator application using the Yandex API</title>
<style>
body{
overflow-x: hidden;
overflow-y: hidden;
background: linear-gradient( to right, DodgerBlue, lightblue);
}
</style>
</head>
<body>
<div id="app"></div>
<script src="/dist/build.js"></script>
<script src='https://code.responsivevoice.org/responsivevoice.js'></script>
</body>
</html>
Чтобы приложение говорило, нам нужна одна функция из библиотеки ResponsiveVoiceJS
:
responsiveVoice.speak()
Мы можем встроить эту функцию в наши обработчики звука и получить что-то вроде этого:
translateSpeak:function(){
responsiveVoice.speak(this.Text);
},
responseSpeak:function(){
responsiveVoice.speak(this.ResponseText);
}
Функция speak()
принимает текст в одной из двух переменных данных и воспроизводит его.
Включая стили
Наконец, давайте добавим некоторые Styles
ограниченные области действия, чтобы все оставалось красивым:
<style scoped>
#parent_translate {
width: 100%;
height: 100%;
display: flex;
flex-wrap: nowrap;
flex-direction: row;
}
select {
padding: 0.2em 0em;
margin: 0;
font-family: 'Indie Flower', cursive;
}
#submit {
background: #4ed34c;
padding: 0.7em;
border: none;
border-radius: 1px;
cursor: pointer;
color: black;
}
#input, #output {
background-color: #f1f1f1;
width: inherit;
height: inherit;
text-align: center;
font-size: 30px;
border-radius: 60px;
}
#input {
margin: 0px 2px 0px 0px;
}
#output {
margin: 0px 0px 0px 2px;
}
textarea {
width: inherit;
height: 60%;
margin: 0px;
padding: 45px 20px;
box-sizing: border-box;
outline: none;
border: none;
text-align: center;
font-size: 25px;
font-family: 'Indie Flower', cursive;
font-weight: bold;
}
#input > div, #output > div {
width: inherit;
height: 20%;
margin: 0px;
padding: 0px;
}
#input > div > img, #output > div > img {
padding: 10px 0px 0px 0px;
width: 12%;
height: 60%;
cursor: pointer;
}
</style>
Это действительно все для translate
компонента, скоро все станет более функциональным и более интересным.
Создание корневого компонента
Прежде чем мы начнем писать код для этого компонента, я хочу, чтобы мы быстро изучили Яндекс Переводчик API и получили бесплатный ключ, если вы еще этого не сделали, потому что это необходимо для дальнейших частей этого проекта.
После создания учетной записи на Яндексе:
Вы сможете создать бесплатный ключ:
Написание MarkUp
Корневому компоненту не нужно так много MarkUp
, поэтому мы напишем только несколько строк, в которые добавим компонент translate в качестве настраиваемого тега:
<div id="app">
<h2>VUE AUDIO TRANSLATOR </h2>
<div id="translate">
<translate v-bind:AvailableLanguages="AvailableLanguages" v-bind:TranslateText="TranslateText" v-bind:ResponseText="ResponseText" @updateFromLanguage="updateFromLanguage($event)" @updateToLanguage="updateToLanguage($event)" @translate="handleTranslation($event)">
</translate>
</div>
</div>
С пользовательским тегом <translate>
происходит два примечательных действия, давайте посмотрим на них:
AvailableLanguages
,TranslateText
иResponseText
передаются как реквизиты.@updateFromLanguage
,@updateToLanguage
и@translate
принимаются как отправленные события корневым компонентом из компонента перевода.
Включая стили
Давайте добавим несколько стилей, чтобы пользовательский интерфейс выглядел хорошо:
<style scoped>
#translate {
height: 45vh;
max-width: 90%;
margin: 2.5vh auto;
}
h2 {
text-align: center;
font-size: 1.6rem;
color: black;
font-weight: bold;
font-family: 'Indie Flower', cursive;
}
</style>
На этом этапе мы можем запустить приложение с помощью этой команды:
npm run dev
Выходные данные показывают, что пользовательский интерфейс обоих компонентов был создан, но при щелчке раскрывающегося списка он не заполняется языками. Это потому, что мы не написали сценарии для реализации этой функции.
Давай сделаем это сейчас.
Написание Javascript
Давайте сделаем три вещи в этом компоненте:
- Импортируйте компонент перевода.
- Зарегистрируйте компонент
- Инициализировать переменные
import translate from './components/translate.vue'
export default {
name: 'app',
components: {
translate : translate
},
data () {
return {
TranslateText : '',
ResponseText : '',
CurrentLanguage : 'en',
TranslateLanguage : 'fr',
AvailableLanguages : {}
}
}
}
Подключение к методу жизненного цикла Created ()
Vue.js позволяет нам подключаться к различным методам жизненного цикла компонентов и делать разные вещи для повышения гибкости приложения. Для этого приложения мы хотим отправить GET
запрос в API Яндекс Переводчика при создании приложения. Поскольку API Яндекс Переводчика позволяет нам создавать HTTP request
для полезной нагрузки JSON поддерживаемых языков вместе с их кодами, мы будем отправлять запрос при каждом создании приложения.
Нам нужен HTTP client
для отправки этого запроса, поэтому давайте его получим, хотя есть ряд подходящих альтернатив (vue-resource, Fetch API и т. Д.), Мы будем использовать HTTP client
axios на основе Promise.
Давайте добавим axios
и небольшую оболочку для интеграции axios
в Vue.js
:
npm install --save axios vue-axios
Чтобы на самом деле использовать axios
и vue-axios
, нам нужно импортировать и использовать их в файл src/main.js
:
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
new Vue({
el: '#app',
render: h => h(App)
})
Теперь, когда мы настроили axios
, мы можем запрашивать объект поддерживаемых языков и их коды при каждом создании приложения:
created(){
var self = this;
this.axios.get('https://translate.yandex.net/api/v1.5/tr.json/getLangs?ui=en&key=YOUR_KEY_GOES_HERE')
.then(function (response) {
self.AvailableLanguages = response.data.langs;
})
.catch(function (error) {
console.log(error);
})
}
После запроса API Яндекс Переводчика response
асинхронно передается обратно как Promise, мы немного копаемся в response
и обновляем значение объекта AvailableLanguages
.
Написание методов Translate и ValidateResponse
Это центральная тема всей статьи, потому что именно здесь происходит фактический перевод текстов и проверка запросов. Здесь мы будем делать три простые вещи:
- Запрос к API Яндекс Переводчика с нашим уникальным ключом и текстом для перевода.
- Проверка ответа, чтобы убедиться, что текст был переведен правильно или была возвращена ошибка.
- Обновление значения переменной данных
ResponseText
, если код ответа200
, или запись строки ошибки в консоль, если это не так.
translate:function(){
var self = this;
this.axios.get('https://translate.yandex.net/api/v1.5/tr.json/translate?key=YOUR_KEY_GOES_HERE&text='+self.TranslateText+'&lang='+self.CurrentLanguage+'-'+self.TranslateLanguage+'&format=plain')
.then(function (response) {
self.validateResponse(response);
})
.catch(function (error) {
console.log(error);
})
},
validateResponse:function(response){
if (response.status === 422) {
console.log('Could Not Translate Text Please Try Again Later');
} else if (response.status === 413) {
console.log('Please Enter A Shorter Text to translate');
} else if (response.status === 200) {
this.ResponseText = response.data.text[0]
} else {
console.log('Cannot translate at this moment please try again later');
}
}
Это почти вся функция этих методов, давайте посмотрим, как корневой компонент обрабатывает события, генерируемые компонентом translate
.
Написание обработчиков событий
Из предыдущего раздела мы знаем, что корневой компонент должен обрабатывать три события, генерируемые компонентом translate:
@updateFromLanguage
,@updateToLanguage
и@translate
Давайте напишем методы для их обработки соответственно:
updateFromLanguage:function( value ){
this.CurrentLanguage = value;
this.translate();
Этот обработчик получает значение от компонента translate и обновляет с его помощью значение переменной CurrentLanguage
. Затем он вызывает метод translate()
для завершения своей работы.
Это метод, который запускается в корневом компоненте всякий раз, когда выбирается новый язык (язык для перевода).
Причина, по которой он вызывает метод translate, заключается в том, что пользователь может мгновенно получать обновления переводов при переключении между языками без необходимости каждый раз нажимать кнопку отправки.
updateToLanguage:function( value ){
this.TranslateLanguage = value;
this.translate();
}
Этот метод делает почти то же самое, что и метод выше, с той лишь разницей, что он работает с выбором языка, на который переводится, а не языка, с которого переводится.
Наконец, обратите внимание на метод обработки событий щелчка для кнопки отправки компонента перевода:
handleTranslation:function( value ){
this.TranslateText = value;
this.translate();
}
Этот обработчик просто обновляет переменную TranslateText
значением параметра, полученного от компонента перевода, а затем переводит текст, вызывая метод translate()
.
Запуск приложения
Мы можем запустить приложение с помощью этой команды:
npm run dev
Это должно открыть новое окно в браузере по адресу разработки localhost:8080
:
Вот и все! Мы только что создали функциональное приложение для перевода аудио, и оно готово к тестированию.
Создайте приложение
При желании мы можем выполнить сборку для производства с помощью этой команды:
npm run build
Вывод
В этом руководстве мы увидели, как создать простое приложение для перевода аудио на Vue.js. Мы также использовали мощный HTTP-клиент axios
для запроса данных в API Яндекс Переводчика.
Мы можем сделать вывод, что Vue.js - очень захватывающий прогрессивный фреймворк для создания множества потрясающих проектов.
Код этого проекта доступен на Github.
Первоначально опубликовано на dev.to.