Стартовый код Cordova и Vue.js

👁 66 просмотров

Чтобы программировать для Cordova на современном фреймворке Vue.js необходимо учитывать факторы, которые дают знать коду на Vue.js, что все ресурсы устройства загружены и начался черед исполнения кода на Vue.js. Ниже представлен скелет данного кода. По сути дела, это переделанный код из файла по умолчанию index.js в понятный вид:

var app = {
    initialize: function() {
    	//Делаем инициализацию
        this.bindEvents();
        this.setupVue();
    },
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    },
    onDeviceReady: function() {
        app.receivedEvent('deviceready');
    },
    receivedEvent: function(id) {
        console.log('Received Event: ' + id);
    },
    setupVue: function() {
    	//Начинаем кодить на фреймворке Vue.js
    	var app = new Vue({
    		el: '#app',
    		data: {
    		  message: 'Hello Vue!'
    		}
    	})
    }
}

//Запускаем приложение
app.initialize();

В плане организации и подключения файлов скриптов важно подумать об оптимизации.

Загрузка файла на сервер при помощи AJAX и PHP

👁 198 просмотров

 

Примечание. Если нижеприведенный код не работает, то настоятельно рекомендуется проверить права для папок, в которые загружаются файлы на сервер. Они должны иметь права на запись.

Есть возможность реализации этой затеи 2-мя способами:

  1. Чтобы файл загрузился после выбора файла автоматом;
  2. Чтобы файл грузил в последствии нажатии на кнопку загрузки.

Чтобы файл загрузился после выбора файла автоматом

Для этого сначала создадим форму и поле файла:

    <form method="post" enctype="multipart/form-data">
		  <div class="form-group">
		    <label for="file">Загрузка фотографии</label>
		    <input type="file" class="form-control-file" id="file" aria-describedby="fileHelp">
		    <small id="fileHelp" class="form-text text-muted">Загрузите новый баннер или установите из существующего списка.</small>
		  </div>
		  <div class="form-group" id="photo-content">
  
		  </div>
    </form>

Кода AJAX обработки на JS/jQuery:

	$(document).on('change','#file',function(event){
		event.preventDefault();
		
        var property = document.getElementById('file').files[0];
        var image_name = property.name;
        var image_extension = image_name.split('.').pop().toLowerCase();

        if(jQuery.inArray(image_extension,['gif','jpg','jpeg','png']) == -1){
          alert("Неправильный формат");
        }

        var form_data = new FormData();
        form_data.append("file",property);
        console.log(form_data);
        $.ajax({
          url:'upload.php',
          method:'POST',
          data:form_data,
          cache:false,
          processData: false,
          contentType: false,
          beforeSend:function(){
            //$('#msg').html('Loading......');
          },
          success:function(data){
	    	  data = JSON.parse(data);
        	  var photo = `
          	  	<div class="img-item">
  			  		<img src='http://83.220.168.205/upload/upload/reklam/banners/`+data.fileName+`'/>
  		  		</div>
          	  `;
          	  $("#photo-content").append(photo);
          }
        });
      });

Серверная часть на PHP:

<?php

if($_FILES['file']['name'] != ''){
    $test = explode('.', $_FILES['file']['name']);
    $extension = end($test);    
    $name = rand(100,999).'.'.$extension;

    $location = './upload/'.$name;
    move_uploaded_file($_FILES['file']['tmp_name'], $location);

    $data = ["fileName"=>$name];
    echo json_encode($data);
}
?>

Чтобы файл загрузился после выбора и нажатия на кнопку

Клиентская часть на HTML:

    <form method="post" enctype="multipart/form-data">
		  <div class="form-group">
		    <label for="file">Загрузка фото</label>
		    <input type="file" class="form-control-file" id="file" aria-describedby="fileHelp">
		    <br/>
		    <button type="submit" class="btn btn-primary btn-start-upload">Загрузить</button>
		    <small id="fileHelp" class="form-text text-muted">Загрузите новый баннер или установите из существующего списка.</small>
		  </div>
		  <div class="form-group" id="photo-content">
		  
		  </div>
    </form>

Обработка на AJAX:

	$(".btn-start-upload").click(function(e){
		e.preventDefault();
		var formData = new FormData();
		formData.append('file', $('#file').prop("files")[0]);
        console.log(formData);
		$.ajax({
			  url: 'upload.php',
			  type: 'POST',
			  processData: false, // important
			  contentType: false, // important
			  cache:false,
			  dataType : 'text',
			  data: formData,
	          type: 'post',
		      success: function(data){
		    	  data = JSON.parse(data);
	        	  var photo = `
	          	  	<div class="photo-item">
	  			  		<div>
	  			  		<img src='http://mysitename.ru/upload/`+data.fileName+`'/>
	  			  		</div>
	  		  		</div>
	          	  `;
	          	  $("#photo-content").append(photo);
		      }
		});
	});

Серверная часть на PHP:

<?php

if($_FILES['file']['name'] != ''){
    $test = explode('.', $_FILES['file']['name']);
    $extension = end($test);    
    $name = rand(100,999).'.'.$extension;

    $location = './upload/'.$name;
    move_uploaded_file($_FILES['file']['tmp_name'], $location);

    $data = ["fileName"=>$name];
    echo json_encode($data);
}
?>

 

Расширенное поле типа select, tag, search, input в одном флаконе на Vue.js

👁 63 просмотров

Данный проект называется Vue Select и доступен по ссылке.  Много примеров его использования по ссылке на CodePen. Ниже представлен простой пример того, как его использовать в базовом предназначении:

Диалоговое окно на Vue.js

👁 83 просмотров

В данном посте представлено диалоговое окно на Vue.js. Окно использует сетку bootstrap и реализовано в виде компонента, но ничего не мешает видоизменить без bootstrap и оформить в виде модуля.

Все что нужно — это добавить код компонента на страницу:

Vue.component("viewer-dialog", {
  template: `<div id="dialogViewer">
                    <div class="viewerBox" v-show="activeViewer">
                        <div class="container-fluid">
                            <div class="row">
                                <div class="col-3"></div>
                                <div class="col-6"></div>
                                <div class="col-3 dlg-close" @click="closeViewer">×</div>
                            </div>
                        </div>
                        <div v-html="htmlContent"></div>
                    </div>
                </div>`,
  data: function() {
    return {
      activeViewer: false,
      htmlContent: ""
    };
  },
  //props: ['btnText'],
  methods: {
    sendReview: function() {
      console.log("!+");
    },
    openViewer: function() {
      this.activeViewer = true;
    },
    closeViewer: function() {
      this.activeViewer = false;
    }
  },
  watch: {
    src: function() {
      this.openViewer();
    }
  },
  created() {
    this.$root.$on('clicked', (html) => {
      this.activeViewer = true;
      this.htmlContent = html;
    });
  }
});

Подключить стили:

#dialogViewer {}

.viewerBox {
  padding-top: 20pt;
  position: absolute;
  top: 0pt;
  text-align: center;
  left: 0pt;
  width: 100%;
  height: 100%;
  display: block;
  background-color: white;
  z-index: 99999;
  overflow-y: scroll;
}

.viewerBox img {
  width: 90%;
  height: auto;
}

.viewerBox .dlg-close {
  font-size: 30pt;
  cursor: pointer;
}

Добавить теги в разметку страницы:

<div id="myApp">
  <viewer-dialog></viewer-dialog>
  <br/>
  <center>
    <button @click="showDialog">Открыть</button>
  </center>
</div>

Написать код приложения Vue.js:

var myApp = new Vue({
  el: "#myApp",
  data: {

  },
  methods: {
    showDialog: function() {
      var html = "<div>Инфа</div>";
      this.$emit('clicked', html);
    }
  }
});

И любоваться результатом:

Как заполучить превью видео Youtube средствами JavaScript

👁 65 просмотров

Допустим есть задача хранить в массиве ссылку на видео и показать превьюшки этого видео, чтобы не путаться. Для этого у Ютуб есть свой хостинг превьюшек, на который закидывается превью видео, когда их добавляют на видеохостинг. Чтобы заполучить превью по коду видео можно воспользоваться нижеследующим кодом:

var videoURL = prompt('Ссылка на видео в Youtube', "");//Окно запроса ссылки
var imgURL = "";//Ссылка на превью
var imgVidGalSrc = [];//Массив для хранения
var pattern = /^((http|https|ftp):\/\/)/;

if(videoURL!==null&&trim(videoURL)!==""&&pattern.test(videoURL))
{
    if(videoURL.indexOf("?v=") > -1)//Если ссылка из строки запроса браузера
    {
        var videCode = videoURL.split("=")[1];
        imgURL = "https://img.youtube.com/vi/"+videCode+"/0.jpg"
    }else if(videoURL.indexOf("youtu.be/") > -1)//Если ссылка из раздела Поделиться
    {
        var videCode = videoURL.split("be/")[1];
        imgURL = "https://img.youtube.com/vi/"+videCode+"/0.jpg"
    }else//Если произошла ошибка в первом и во втором случаях
    {
        imgURL = "images/icon-video.png";//Какая-то общая иконка
    }
    //Добавляем в общий массив хранения
    imgVidGalSrc.push({url:videoURL,thumb:imgURL});
}else
{
    alert("Вы ввели пустую строку или некорректную ссылку!")
}
//Функция удаления лишних пробелов
function trim( str, charlist ) {
    charlist = !charlist ? ' \s\xA0' : charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '\$1');
    var re = new RegExp('^[' + charlist + ']+|[' + charlist + ']+$', 'g');
    return str.replace(re, '');
}

Связь между компонентами в Vue.js

👁 364 просмотров

Допустим, есть задача связать корневой компонент или приложение Vue.js с дочерними компонентами и наоборот.

Есть несколько методов, здесь приведен классический пример обмена данными между компонентами Vue.js. Причем, во Vue.js нет горизонтального обмена данными между дочерними компонентами, все компоненты должны обращаться к главному , а главный может обращаться к любому дочернему и может выступать между ними промежуточным мостом.

Стоит отметить, что данный подход предполагает использование событий по нисходящей и свойств элемента по восходящей

Т.е., это означает, что дочерние компоненты могут обращаться к корневому компоненту посредством событий эммитеров, а от корневого компонента к дочерним данные передаются по заранее определенным в дочернем компоненте свойствам элемента. Ниже приведены оба пример обмена.

От корневого к дочернему:

От дочернего к корневому:

Тут еще один пример двунаправленной передачи:

Компонент добавления тегов в Vue.js

👁 66 просмотров

Представим, что у нас есть задача сделать компонент в виде формы ввода тегов. Не буду вдаваться в подробности, но скажу, что компонент может быть записан в отдельные файлы component.js и component.css  и подключить обычным образом к странице. В Cordova, к примеру, пока это единственный способ использовать внешние компоненты, загружаемые в виде отдельных модулей, потому что нет поддержки import

Чтобы иметь обратную связь из модуля в главное приложение Vue.js нам необходимо установить событие обновления  тегов, потому что нам необходимо заполучить эти введенные, чтобы потом хранить их в БД. Решением этого является добавление в методе watch модуля наблюдение для параметра tags:

tags() {
    this.$root.$emit('updateTags',this.elementId, this.tags, this.tagBadges, this.existingTags);
}

Т.е., модуль будет вызывать метод в главном приложении, чтобы ему передавать обновленные данные состояния поля ввода тегов. В главном приложении в методе create создаем слушатель события для метода:

this.$root.$on('updateTags', (fieldName, tags, badges, existingTags) => {
    //...
});

К примеру, если у нас несколько полей ввода на одной странице, то нам будет полезно их разграничить, ведь, чтобы получить данные того поля, который был изменен, для этого можно воспользоваться следующим кодом:

<tags-input element-id="fieldGenreTags"
            :existing-tags="genreTags"
            :typeahead="true">
</tags-input>
<tags-input element-id="fieldSkillTags"
            :existing-tags="skillTags"
            :typeahead="true">
</tags-input>
<tags-input element-id="fieldImageTags"
            :existing-tags="imageTags"
            :typeahead="true">
</tags-input>
this.$root.$on('updateTags', (fieldName, tags, badges, existingTags) => {
   //
   var tagObj = {};
   tags.forEach(function(item, index, tags){
        tagObj[item] = badges[index];
   });
   //
   if("fieldGenreTags"==fieldName+"") this.curGenreTags = tagObj;
   if("fieldSkillTags"==fieldName+"") this.curImageTags = tagObj;
   if("fieldImageTags"==fieldName+"") this.curSkillTags = tagObj;
   //
   console.log("fieldGenreTags");
   console.log(this.curGenreTags);
   console.log("fieldSkillTags");
   console.log(this.curImageTags);
   console.log("fieldImageTags");
   console.log(this.curSkillTags);
})

Т.е., на странице для поля мы определяем для него ID, а в методе мы по этому ID разграничиваем получаемые данные.

Загрузка файла на удаленный сервер в Cordova

👁 116 просмотров

Рассмотрим пример загрузки файла с мобильного устройства на удаленный сервер. Условимся, что у нас могут быть разные варианты приема отправленного файла на стороне сервера:

  • прием файла посредством PHP;
  • прием файла посредством Node.js

 

Плагины и доступы

Для начала нам нужно установить необходимые плагины для работы с загружаемыми файлами:

cordova plugin add cordova-plugin-file
cordova plugin add cordova-plugin-file-transfer
cordova plugin add cordova-plugin-white-list
cordova plugin add cordova-plugin-camera
cordova plugin add cordova-plugin-device

Далее даем доступы на права работы с файлами и с сетями платформе. К примеру. для Android они задаются в файле в папке по пути MyApp\platforms\android\app\src\main\AndroidManifest.xml:

<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="10000" android:versionName="1.0.0" package="io.cordova.hellocordova" xmlns:android="http://schemas.android.com/apk/res/android">
    <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
    ...

 

Клиентский код

Кнопка открытия. Обращаем внимание на meta — тег с разрешениями на удаленную передачу:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'">
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
        <link rel="stylesheet" type="text/css" href="css/index.css">
    </head>
    <body>
        <button id="getImage">Выбрать картинку</button>
        <script src="cordova.js" ><script>
        <script src="index.js" ><script>
    </body>
</html>

Скрипт:

var app = {
    initialize: function() {
        this.bindEvents();
        this.setupApp();
    },
    bindEvents: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    },
    onDeviceReady: function() {
        app.receivedEvent('deviceready');
    },
    receivedEvent: function(id) {
        console.log('Received Event: ' + id);
    },
    setupApp: function(){
                function getImage() {
                    navigator.camera.getPicture(
                        this.uploadPhoto,
                        function (message) { alert('get picture failed'); },
                        {
                            quality: 50,
                            destinationType: navigator.camera.DestinationType.FILE_URI,
                            sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY
                        }
                    );
                }
                function uploadPhoto(imageURI) {
                    alert(imageURI);
                    var options = new FileUploadOptions();
                    options.fileKey = "file";
                    options.fileName = imageURI.substr(imageURI.lastIndexOf('/') + 1);
                    options.mimeType = "image/jpeg";
    
                    var params = {};
                    params.value1 = "test";
                    params.value2 = "param";
    
                    options.params = params;
    
                    var ft = new FileTransfer(); 
                    ft.upload(
                        imageURI, 
                        encodeURI("http://83.220.168.205/upload/upload.php"), 
                        this.win, 
                        this.fail, 
                        options);
                }
                function win(r) {
                    console.log("Code = " + r.responseCode);
                    console.log("Response = " + r.response);
                    console.log("Sent = " + r.bytesSent);
                }
                function fail(error) {
                    alert("An error has occurred: Code = " + error.code);
                    console.log("upload error source " + error.source);
                    console.log("upload error target " + error.target);
                    alert("upload error source " + error.source);
                    alert("upload error target " + error.target);
                }
        document.getElementById("getImage").onclick = function() {
            getImage();
        };
        
    }
    
}

app.initialize();

Серверный код на PHP

Сначала в корне сервера надо создать папку upload и в  ней файл upload.php и подпапку upload, куда будут файлы грузиться и храниться:

<?php
//Задаем заголовки на стороний доступ
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, PATCH, DELETE');
header('Access-Control-Allow-Headers: X-Requested-With,content-type');
header('Access-Control-Allow-Credentials: true');
//
$new_image_name = urldecode($_FILES["file"]["name"]).".jpg";
//Переносим файл в нужную папку
move_uploaded_file($_FILES["file"]["tmp_name"], "upload/".$new_image_name);
?>

Обращаем внимание на заголовки, которые разрешают доступ со стороны клиента.

Серверный код на JavaScript для Node.js

Если требуется загрузить и заполучить файл со стороны Node.js, то легче все это сделать при помощи стороннего модуля express-formidable, если приложение express. Сначала устанавливаем сам модуль:

npm install express-formidable

Далее дописываем наш app.js на прием. К пример, у нас есть url — адрес http://myhostname:3000/upload, то код для приема и сохранения загруженного с клиента файла будет следующим:

var formidable = require('formidable');

...

app.post('/upload', function(req, res) {
    res.set({
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, PUT, PATCH, DELETE',
        'Access-Control-Allow-Headers': 'X-Requested-With,content-type',
        'Access-Control-Allow-Credentials': 'true'
    });
    //var data = req.body;
    //console.log(data);
    //console.log(req.files);
    var form = new formidable.IncomingForm();

    form.parse(req);

    form.on('fileBegin', function (name, file){
        file.path = __dirname + '/upload/' + file.name + '.jpg';
    });

    form.on('file', function (name, file){
        console.log('Uploaded ' + file.name);
    });
});

 

Некоторые полезные сниппеты на Vue.js

👁 43 просмотров

Как создать список select с предустановленным значением option?

К примеру, есть задача загнать в select список данных с значением и его названием и чтобы какая-то опция была выбрана по умолчанию. Ниже представлен этот код:

Базовые вещи в Vue.js

👁 119 просмотров

Предисловие

Всегда, для начального использования какого-то фреймворка необходимо понимать в нем работу базовых вещей, чтобы зная их  было от чего отталкиваться дальше. То же самое и во Vue.js, нам нужно знать как его готовить, имея примитивный набор знаний о базовых его вещах, начиная от старта простого примера и кончая использование в нем обработчиков событий. Именно эту суть преследует данные пост.

Установка Vue.js

Установить Vue.js — это просто. Все, что нам нужно — это знать, какими методами установить. Есть несколько способов, в зависимости от того, где мы хотим использовать Vue.js.

Если хотим использовать на стороне клиента, то можем ссылать на cdn — ссылку проекта, добавив в страницу ссылку на cdn:

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.js"></script>

Можем также добавить через менеджер пакетов bower:

bower install vue

Если хотим использовать в масштабируемых Node.js — серверных приложениях, то выполняем код:

npm install vue

Все дополнительные моменты установки можно найти в разделе установки Vue по ссылке.

 

Базовое приложение Vue.js

Ниже представлено базовое приложение на Vue.js или базовый скелетон приложения на Vue.js

Описание основных параметров приложения Vue.js

Выше мы создали первое и базовое приложение на Vue.js. Давайте рассмотрим список основных его параметров.

Параметры приложения:

  • new Vue{…} — это главный объект приложения. Можно было это написать так var app = new Vue{…}; после чего через объект app можно было получить все значения данного приложения для взаимодействия с другими приложениями;
  • data — это поле, в котором хранятся все данные и переменные текущего приложения. Это могут быть обычные объекты или же массивы в JSON — формате;
  • computed — это поле, которое нужно для вычисляемых методов. Параметрами данного поля являются методы, которые вычиляют обновляющиеся данные. Вычисление происходит после каждого случая взаимодействия с приложением, поэтому это поле обновляется всегда;
  • methods — поле для определения методов текущего приложения. Это могут быть обработчики событий или другая логика выполнения кода;
  • watch — поле для задания слушателей для определенного параметра. Данный слушатель будет выполняться всегда, когда будет обновляться значение данного параметра;

Условные конструкции приложения:

  • v-if=’isTrue’ — условный оператор выполнения текущего блока, если какое-то значение истинно;
  • v-else — условный оператор ветвления, если не выполнится блок v-if. Является необязательной продолжительной частью v-if;
  • v-else-if — условный оператор ветвления, если не выполнится блок v-if и требуется продолжения ветвления. Является необязательной продолжительной частью v-if;
  • v-show — выполняет ту же операцию, что и v-if, но в отличии от v-if данная конструкция просто скрывает элемент посредством css — поля display;

Конструкции организации циклов:

  • v-for=‘item in items’ — самый простой вид итерации из массива, в данном случае, будет читать все объекты в виде item из массива items;
  • v-for=‘(index, item) in items’ — то же самое, но еще можно заполучить индекс текущего элемента массива;
  • v-for=‘value in object’ — итерация полей из объекта;
  • v-for=‘(key, val) in object’ — итерация полей из объекта с ключами;
  • v-for=‘n in 10’ — ранжирование, т.е. инкремент на 1 значения n от 0 до определенного значения, в  данном случае — до 10;

Организации событий:

  • v-on:eventname=’eventHandler — организиует для элемента событие с типом eventname и обработчиком eventHandler. В роли типа события может выступать любой определенный в JS событие на элементе, а в роли обработчика может выступать функция, определенная в параметре приложения methods;
  • @eventname=’eventHandler — короткая запись организации события без v-on;
  • v-on:eventname=’eventHandler(param)‘ — то же самое, но передаем еще и параметр в обработчик;
  • v-on:eventname=’eventHandler(param, $event) — то же самое, но передаем еще параметр и специальный объект события в обработчик. В последствии мы можем на объекте глобального события event вызвать, к примеру метод preventDefault() или же можем заполучить координаты нажатого объекта;

Работа с атрибутами:

  • v-bind:attrname=’pаram’ — позволяет задать значение для атрибута, где param — переменная приложения Vue;
  • :attrname=’param’ — то же самое, нов коротком виде;

Сквозная связь между данным поля HTML и параметром:

  • v-model:=’param’ — позволяет двунаправленно создавать связи между меняющимся значением какой-то формы HTML и каким-нибудь параметром или переменной Vue.js. Это позволяет создавать интерактивному смену значения одной переменной по всему приложению;

 

На этом материал для данного поста все. Это основные моменты, но не все. Vue.js гораздо гибок и богат функционалом. Для углубленного изучения, лучше, конечно, почитать документацию.