NodeJS實戰(zhàn)--使用NodeJS實現(xiàn)前后端的聯(lián)調(diào)

原文鏈接:http://m.itdecent.cn/p/2a9367afe9e7

1510997059(1).jpg

1. 將原項目遷移進(jìn)入KOA2,并順利通過index/index路由進(jìn)行訪問

1.1 新建項目,配置項目結(jié)構(gòu)所需的一系列的文件,使 index/index 可以打開

將原項目 Praisethumb 拖拽到 sublime 編輯器中,新建一個koatest 文件夾

打開小黑窗進(jìn)入koatest 文件夾中

cd Desktop

cd koatest

初始化項目

npm init

找尋 koa2 包教程,www.npmjs.com-> 搜索框輸入koa2

參考鏈接:https://www.npmjs.com/package/koa2

開始配置koa2 -> 在小黑窗中安裝koa2包

npm install koa@next

在koatest文件夾中新建文件 app.js, copy 如下代碼

const Koa = require('koa');

const app = new Koa();

// response

app.use(ctx => {

ctx.body = 'Hello Koa';

});

app.listen(3000);

由于使用的是 ES6 所以將 require 引用 改為 import name from 'name'

import Koa from 'koa';

const app = new Koa();

// response

app.use(ctx => {

ctx.body = 'Hello Koa';

});

app.listen(3000);

此時在小黑窗中輸入 node app.js 會報如下的錯誤,原因是為將ES6 代碼編譯為 可解析的 ES5

4Y4V)NM0S7MLXBOBDM9NH2G.png

開始安裝編譯依賴包 babel ,在此闡述一下 -dev 的問題,安裝包時加 -dev 說明其只在開發(fā)環(huán)境下使用而上線時有命令可以直接將其去掉, babel 便是此類的安裝包

npm install babel-preset-es2015 --save-dev

http://www.ruanyifeng.com/blog/2016/01/babel.html?20170213113809阮一峰先生的 babel 教程

在項目中新建 .babelrc ,babel 的配置文件 輸入如下代碼

{

"presets":[

"es2015",

"stage-0"

],

"plugins":[]

}

安裝babel 編譯所需的其他包,stage-0 是 ES7 的一個階段,是為了使 babel 可以識別后面寫的 async 和 await

cnpm install babel-preset-stage-0 --save-dev

http://m.itdecent.cn/p/c84d52828e45async 和 await 詳解

編譯 app.js 文件,并啟動服務(wù)

babel app.js -o app_o.js

node app_o.js

啟動時報了如下錯誤,猜測是由于哪個包裝的時候未裝完整便退出了,所以將文件夾中的 node_modules 文件刪除? 再重新安裝一遍項目所需的包 cnpm install? 再次啟動 node app_o.js 時便成功了

1511065654(1).jpg

啟動成功后,在瀏覽器中輸入http://localhost:3000/顯示為 Hello Koa證明一切都沒問題了

14.此時需要配置路由 為 /index/index ,使用 koa-simple-router 包

https://www.npmjs.com/package/koa-simple-router包的網(wǎng)址

npm install koa-simple-router --save

在 app.js 文件的代碼改為如下所示的

import Koa from 'koa';

import router from 'koa-simple-router';

const app = new Koa();

app.use(router(_ => {

_.get('/', (ctx, next) => {

ctx.body = 'hello'

})

_.post('/name/:id', (ctx, next) => {

// ...

})

})

app.listen(3000);

為了使項目變得更加的分化明了

新建一個 midddleware 文件夾放項目的容錯文件

新建一個 config 文件夾放項目的配置文件

新建一個 controller 文件夾放項目的路由配置文件

新建一個向后端請求數(shù)據(jù)的文件夾 models

新建一個放 html 頁面的文件夾 views

再加一個放靜態(tài)文件 .css .js 的文件夾 public

文件創(chuàng)建解構(gòu)如下

public -> css -> index.css

public -> scripts -> index.js

controller -> initController.js

controller -> indexController.js

編輯 initController.js 文件,將 app.js 文件中的路由配置方法代碼拿到 該文件中略加修改,最后講方法導(dǎo)出

import index from './indexController';//引入 indexController 文件導(dǎo)出的方法

const controllerInit = {

//配置初始化函數(shù)

init(app, router) {

app.use(router(_ => {

_.get('/index/index', index.index())

}))

}

}

//導(dǎo)出初始化方法,使其全局可用

export default controllerInit;

編輯 indexController.js 文件,并導(dǎo)出該方法給 initController.js 文件使用

const indexController ={

index(){

return async(ctx,next)=>{

ctx.body = await ctx.render('index.html',function(){

title:'大拇指點贊'

})

}

}

}

// 導(dǎo)出該方法給 initController.js 文件使用

export default indexController;

在 app.js 文件中引用 initController 并執(zhí)行

import initController from './controller/initController';

initController.init(app,router);

由于在controller js 文件中都使用了 koa-swig 框架中的 rander 函數(shù),而且需要這個框架在靜態(tài)文件中引用文件,所以要引用 koa-swig

https://www.npmjs.com/package/koa-swig包的網(wǎng)址

npm install koa-swig --save

https://www.cnblogs.com/elementstorm/p/3142644.htmlswig 使用指南

在 swig 使用指南中找到 模板繼承模塊,在項目中的 views 文件夾中新建 layout.html 和 index.html 將如下代碼 copy 進(jìn)去

layout.html

{% block title %}My Site{% endblock %}

{% block head %}

{% endblock %}

{% block content %}{% endblock %}

index.html

{% extends 'layout.html' %}

{% block title %}My Page{% endblock %}

{% block head %}

{% parent %}

{% endblock %}

{% block content %}

This is just an awesome page.

{% endblock %}

以為用的是 koa2 所以用 swig 時還要引用 co 模塊,該模塊無需安裝,在 app.js 文件中輸入如下代碼

import co from 'co';

app.context.render = co.wrap(render({

root: __dirname + 'views',

autoescape: true,

cache: 'memory', // disable, set to false

ext: 'html',

writeBody: false

}));

html 文件中相互引用路徑時需要安裝 koa-static 來配置

npm install koa-static --save

在 app.js 文件中輸入如下代碼

import serve from 'koa-static';

app.use(serve(__dirname + '/test/fixtures'));

在 config 文件夾中新建? config.js 文件

http://es6.ruanyifeng.com/?search=map&x=0&y=0#docs/set-mapES

6-Map 方法詳述

安裝 path

npm? install path --save-dev

編輯 config.js 文件,將方法導(dǎo)出 app.js 會使用

import path from 'path';

const CONFIG = new Map();

CONFIG.set('port',3000);

CONFIG.set('staticDir',path.join(__dirname,'..','public'));

CONFIG.set('viewDir',path.join(__dirname,'..','views'));

export default CONFIG;

在 app.js 文件中引入 CONFIG 并修改配置路徑

import CONFIG from './config/config';

initController.init(app,router);

app.context.render = co.wrap(render({

root: CONFIG.get('viewDir'),

autoescape: true,

cache: 'memory', // disable, set to false

ext: 'html',

writeBody: false

}));

app.use(serve(CONFIG.get('staticDir')));

app.listen(CONFIG.get('port'));

編譯文件

babel app.js -o app_o.js? //期間莫名其妙報了錯,然后檢查了下需要引用的包,看看 package.json 文件中是否存在沒有的安裝一遍,之后還是報錯,便將 node_modules 文件夾刪掉 在將所有的包重裝了一遍 npm install 可以了

進(jìn)入 config 和 controller 文件夾中,將里面的 .js 文件后綴名改為 .es,再在命令行中進(jìn)行編譯

cd config

babel config.es -o config.js

cd ..

cd controller

babel initController.es -o initController.js

babel indexController.es -o indexController.js

啟動服務(wù)

cd..

node app_o.js

此時報了如下的錯誤,

1511073380(1).jpg

原因是在 indexController 中用到了 async 和 await 但是并沒有編譯的很好,因為 babel 默認(rèn)是不會編譯較高級的函數(shù)的,所以需要裝兩個包使其支持

cnpm install babel-register --save-dev

cnpm install babel-polyfill --save-dev

裝好之后在 app.js 文件中引入

import babel_co from 'babel-core/register';

import babel_po from 'babel-pocyfill';

再編譯一遍文件

babel app.js -o app_o.js

cd controller

babel indexcontroller

babel indexController.es -o indexController.js

運行服務(wù) 報錯為如下圖

image.png

在 app.js 文件中引入 CONFIG

import CONFIG from './config/config';

編譯修改過的文件

babel app.js -o app_o.js

cd config

babel config.es -o config.js

切記每次修改了 .es 都需要在重新編譯一遍

運行服務(wù)

node app_o.js

在瀏覽器打開頁面http://localhost:3000/index/index展示如下圖所示? 便表示成功了接下來就是第二步將原項目遷移過來

1511076432(1).jpg

1.2 將之前所做的 項目 Praisethumb 中的文件配置到新項目中

1.將之前的 css 樣式 放到 koatest 項目中的 index.css 文件中

{

margin: 0;

padding: 0;

}

body {

background-color: #b1c8ac;

padding: 50px;

position: relative;

height: 600px;

}

.a {

position: absolute;

left: 0;

right: 0;

top: 0;

bottom: 0;

margin: auto;

background-color: #ffcaaa;

width: 226px;

height: 360px;

border-radius: 38px 0 0 38px;

border: 1px solid #95755e;

border-width: 1px 0 1px 1px;

}

.a:before {

content: " ";

display: block;

position: absolute;

width: 246px;

height: 240px;

border-top: 1px solid #95755e;

bottom: 0;

top: 0;

right: 0;

left: 0;

margin: auto auto auto -224px;

background-color: #ffcaaa;

}

.a:after {

content: " ";

display: block;

position: absolute;

width: 150px;

height: 90px;

border: 1px solid #95755e;

border-width: 1px 1px 0 0;

border-radius: 0 45px 45px 0;

bottom: 0;

top: 0;

right: 0;

left: 0;

margin: 0 auto auto 30px;

background-color: #ffcaaa;

transform: rotate(-65deg);

transform-origin: left top;

box-shadow: -4px -4px 22px 2px #ffcaaa inset, -4px 4px 30px 2px #ffcaaa inset, -25px 2px 10px 3px #fce0d4 inset, -80px 2px 10px 1px #ffcaaa inset, -100px 2px 20px 0px #efb38f inset;

transition: all .3s;

}

.b {

width: 180px;

height: 90px;

border: 1px solid #95755e;

position: absolute;

border-radius: 45px;

box-shadow: -4px -4px 22px 2px #ffcaaa inset, -4px 4px 30px 2px #ffcaaa inset, -25px 2px 10px 3px #fce0d4 inset;

background-color: #ffcaaa;

z-index: -1;

left: 0;

right: 0;

top: 0;

bottom: 0;

margin: auto -90px -1px auto;

-webkit-box-reflect: above 178px;

box-reflect: above 178px;

}

.b:before {

content: " ";

display: block;

position: absolute;

width: 180px;

height: 90px;

border: 1px solid #95755e;

right: 0;

top: -91px;

border-radius: 45px;

border-width: 1px 1px 1px 0;

box-shadow: -4px -4px 22px 2px #ffcaaa inset, -4px 4px 30px 2px #ffcaaa inset, -25px 2px 10px 3px #fce0d4 inset;

background-color: #ffcaaa;

}

.c {

width: 180px;

height: 90px;

border: 1px solid #95755e;

position: absolute;

border-radius: 45px;

box-shadow: -4px -4px 22px 2px #ffcaaa inset, -4px 4px 30px 2px #ffcaaa inset, -25px 2px 10px 3px #fce0d4 inset;

background-color: #ffcaaa;

z-index: -1;

left: 0;

right: 0;

top: 0;

bottom: 0;

margin: 90px -90px -1px auto;

/-webkit-box-reflect: above 178px;

box-reflect: above 178px;

/

}

.c:before {

content: " ";

display: block;

position: absolute;

width: 180px;

height: 90px;

border: 1px solid #95755e;

right: 0;

top: -91px;

border-radius: 45px;

border-width: 1px 1px 1px 0;

box-shadow: -4px -4px 22px 2px #ffcaaa inset, -4px 4px 30px 2px #ffcaaa inset, -25px 2px 10px 3px #fce0d4 inset;

background-color: #ffcaaa;

}

/.b:after{content: " ";display: block;position: absolute;width: 180px;height:90px;border: 1px solid #95755e;right: 0;top:182px;border-radius: 45px;border-width: 1px 1px 1px 0;box-shadow:-4px -4px 22px 2px #ffcaaa inset, -4px 4px 30px 2px #ffcaaa inset, -25px 2px 10px 3px #fce0d4 inset;background-color: #ffcaaa;}/

.hide {

opacity: 0;

color: red;

font-size: 60px;

position: absolute;

right: 60px;

top: 150px;

}

.num {

animation: myani .6s ease;

-moz-animation: myani .6s ease;

-webkit-animation: myani .6s ease;

-o-animation: myani .6s ease;

}

@keyframes myani() {

form {

opacity: 0;

top: 150px;

}

to {

opacity: 1;

top: 50px;

}

}

@-moz-keyframes myani {

form {

opacity: 0;

top: 150px;

}

to {

opacity: 1;

top: 50px;

}

}

@-webkit-keyframes myani {

form {

opacity: 0;

top: 150px;

}

to {

opacity: 1;

top: 50px;

}

}

@-o-keyframes myani {

form {

opacity: 0;

top: 150px;

}

to {

opacity: 1;

top: 50px;

}

}

:root {

--green: #b1c8ac;

}

body {

background-color: var(--green);

}

將 html 內(nèi)容也拿過來

index.html

{% extends 'layout.html' %}

{% block title %}My Page{% endblock %}

{% block head %}

{% parent %}

{% endblock %}

{% block content %}

+1

SystemJS.config({

//使用的 js 文件的文件夾路徑

baseURL: '/scripts'

});

//使用的 js 文件名稱

SystemJS.import('index-es.js').then(function(m) {

$.extend({

//將自己寫的函數(shù)掛載到 jq 上稱為一個插件

thumb:m.default.Thumb

})

//回調(diào)函數(shù)

callBack();

});

//定義回調(diào)函數(shù)

function callBack() {

//為頁面元素添加方法

var f = new $.thumb(0,$('#thumb'));

f.clickAction();

}

{% endblock %}

拿 js

window.add = function (num) {

return num + 1;

}

將編譯過的 點擊小手子類繼承父類的 js文件(index.es.js)復(fù)制到 項目的 scripts 文件夾下

index-es.js

'use strict';

Object.defineProperty(exports, "__esModule", {

value: true

});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.proto= superClass; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var PraiseButton = function () {

function PraiseButton(num, element) {

_classCallCheck(this, PraiseButton);

this.num = num;

this.element = element;

_createClass(PraiseButton, [{

key: 'clickAction',

value: function clickAction() {

var _this = this;

this.element.click(function () {

if (_this.num < 10) {

_this.element.css('-webkit-filter', 'grayscale(0)');

$('#animation').addClass('num');

_this.num = add(_this.num);

setTimeout(function () {

$('#animation').removeClass('num');

}, 1000);

} else {

_this.element.css('-webkit-filter', 'grayscale(1)');

_this.num = 0;

}

console.log(_this.num);

});

}

}]);

return PraiseButton;

}();

var Thumb = function (_PraiseButton) {

_inherits(Thumb, _PraiseButton);

function Thumb(num, element) {

_classCallCheck(this, Thumb);

return _possibleConstructorReturn(this, (Thumb.proto|| Object.getPrototypeOf(Thumb)).call(this, num, element));

}

return Thumb;

}(PraiseButton);

exports.default = { Thumb: Thumb

// let? f = new Thumb(0,$('#thumb'));

// f.clickAction();

};

重啟服務(wù)

node app_o.js

刷新http://localhost:3000/index/index頁面,發(fā)現(xiàn)項目已經(jīng)移植成功

2. 使用 PHP + MySQL 完成點贊借口,實現(xiàn)用戶點擊一次更新數(shù)據(jù)庫點贊次數(shù)

在項目中新建一個 praise.php 文件

編輯文件


//用php的面向?qū)ο髞韺?/p>

/**

* 新建一個類

*/

class Conmysql

{

//定義所需的變量

//public關(guān)鍵字表示屬性或方法是公開可見的

public $servername;

public $username;

public $password;

public $dbname;

}

?>

用 XAMPP 啟動 Apache 和 MySQL

1511081397(1).jpg

在瀏覽器中打開http://localhost/phpmyadmin/頁面

在左側(cè)操作欄中點擊【新建】

輸入新數(shù)據(jù)庫的名字 praise 點擊【創(chuàng)建】

新建數(shù)據(jù)表 text 2

字段分別為? id 和 num

id 需要設(shè)置為主鍵

點擊保存

具體設(shè)計如下圖所示

image.png

在 text 數(shù)據(jù)表中手動添加一條數(shù)據(jù)

點擊數(shù)據(jù)表【text】

點擊 【SQL】

點擊【INSERT】

將輸入域的值修改為如下所示,點擊【執(zhí)行】

INSERT INTO `text`(`id`, `num`) VALUES (1,0)

在 php 文件中編輯


//用php的面向?qū)ο髞韺?/p>

/**

* 新建一個類

*/

class Conmysql

{

//定義所需的變量

//public關(guān)鍵字表示屬性或方法是公開可見的

public $servername;

public $username;

public $password;

public $dbname;

public $con = null;

//添加構(gòu)造方法

public function __construct($servername,$username,$password,$dbname){

$this->servername = $servername;

$this->username = $username;

$this->password = $password;

$this->dbname = $dbname;

}

//創(chuàng)建數(shù)據(jù)庫鏈接方法

//參考網(wǎng)址:http://www.runoob.com/php/php-mysql-connect.html -> 實例 (PDO)

public function getConnection(){

//這里用的是 PDO 方法

try {

$dsn = "mysql:host=$this->servername;dbname=$this->dbname";

$this->con = new PDO($dsn, $this->username, $this->password);

//echo "連接成功";

}

catch(PDOException $e)

{

echo $e->getMessage();

}

}

//更新數(shù)據(jù)的方法

public function updateDate($sql){

//如果未連接的話就鏈接到數(shù)據(jù)庫

if($this->con == null){

$this->getConnection();

}

//執(zhí)行sql

//參考鏈接:http://www.runoob.com/php/php-mysql-insert.html -> 實例 (PDO)

$res=$this->con->exec($sql);

//關(guān)閉鏈接

$this->closeCon();

}

//關(guān)閉鏈接的方法

public function closeCon(){

$this->con = null;

}

}

/**

* 創(chuàng)建子類

*/

class realConn extends Conmysql

{

//繼承父類的構(gòu)造方法

public function __construct($servername,$username,$password,$dbname){

parent::__construct($servername,$username,$password,$dbname);

}

//真正執(zhí)行 sql 的方法

public function updateRealDate(){

$sql = "UPDATE text SET num=num+1 WHERE id=1";

$this->updateDate($sql);

}

}

//將子類實例化執(zhí)行方法

$praiseCon = new realConn('localhost','root','','praise');

$praiseCon->updateRealDate();

?>

將 praise.php 文件復(fù)制到 C:\xampp\htdocs 文件夾下,在瀏覽器中打開http://localhost/praise.php,再查看 text 數(shù)據(jù)表中會發(fā)現(xiàn) num 的值為 1 ,刷 php 頁面一次值便會加 1,至此點贊接口便完成了

3. 使用KOA2+ES6封裝PHP點贊接口,并建立路由

1.在 koatest 項目文件夾的 models 文件夾中新建一個 indexmodel.js 文件

編輯 indexmodel.js 文件

import rpA from 'request-promise';

class indexModel {

constructor(ctx) {

this.ctx = ctx;

}

//為了實現(xiàn)數(shù)據(jù)庫更新建立方法 傳數(shù)據(jù)的接口

updateNum() {

//在這里 return 一個 promise 模塊傳入 initController.js 再在indexController.js 中調(diào)用需要用到一個模塊 request-promise? 參考網(wǎng)址:https://www.npmjs.com/package/request-promise

// 獲取文件

const options = {

uri: 'http://localhost/praise.php',

method:'GET'

};

return new Promise((resolve,reject)=>{

rpA(options).then(function(result){

const info = JSON.parse(result);

if(info){

resolve({data:info.result});

}else{

reject({});

}

})

})

}

}

//將該方法導(dǎo)出,? indexController.js 文件要用到

export default indexModel;

由于 updateNum 方法中需要用到 request-promise 模塊 所以需要安裝兩個包

參考鏈接:https://www.npmjs.com/package/request-promise

npm install --save request

npm install --save request-promise

編輯 indexController.js 文件

indexController 對象中增加一個 提交數(shù)據(jù)的方法

//引入所需方法的文件

import indexModel from '../models/indexModel';

update(){

return async(ctx,next)=>{

const indexM = new indexModel(ctx);

ctx.body = await indexM.updateNum();

}

}

編輯 initController.js 文件

將 indexController 提交數(shù)據(jù)的方法注冊到 一個新的路由上

_.get('/index/update', index.update());

babel 編譯文件

將 indexmodel.js 重命名為 indexmodel.es

cd models

babel indexmodel.es -o indexmodel.js

cd ..

cd controller

babel? indexController.es -o indexController.js

babel initController.es -o initController.js

此時運行服務(wù)會發(fā)現(xiàn)小手點擊并沒有與服務(wù)器關(guān)聯(lián)起來,此時需要用 axios 模塊來使其連接到 koa2 點贊接口上

4. 將用戶點擊事件通過 axios 鏈接到 KOA2 點贊接口

在 koatest 項目中的 scripts 文件夾中新建 index.es 文件,并將 praisethumb 項目中的 scripts -> index.js 文件代碼復(fù)制過來

class PraiseButton{

constructor(num,element){

this.num = num;

this.element = element;

}

clickAction(){

this.element.click(()=>{

if(this.num < 10){

this.element.css('-webkit-filter','grayscale(0)');

$('#animation').addClass('num');

this.num = add(this.num);

setTimeout(function () {

$('#animation').removeClass('num');

},1000);

}else{

this.element.css('-webkit-filter','grayscale(1)');

this.num = 0;

}

console.log(this.num);

})

}

}

class Thumb extends PraiseButton{

constructor(num,element){

super(num,element)

}

}

export default{Thumb}

// let? f = new Thumb(0,$('#thumb'));

// f.clickAction();

編輯 index.es 文件,這里是要用 axios 模塊來使其連接到 koa2 點贊接口上

參考鏈接:https://www.npmjs.com/package/axios

這里有三種引用的方法:npm 裝包,瀏覽器裝包,cdn,這里我們用的是 cdn 方法,將如下代碼 copy 至 index.html 文件中

將如下代碼 copy 至 index.es -> this.element.click 點擊事件中

axios.get('/index/update')

.then(function (response) {

console.log(response);

})

.catch(function (error) {

console.log(error);

});

編修改過的文件 index.es

cd public\scripts\

babel index.es -o index-es.js

運行服務(wù)

cd ../..

node app_o.js

點擊時頁面http://localhost:3000/index/index報如下圖所示的錯誤

image.png

編輯 praise.php 文件中的 updateDate 方法

//更新數(shù)據(jù)的方法

public function updateDate($sql){

//如果未連接的話就鏈接到數(shù)據(jù)庫

if($this->con == null){

$this->getConnection();

}

//向前臺輸出 json 格式的數(shù)據(jù)

header('content-type:application/json;charset=utf8');

//執(zhí)行sql

//參考鏈接:http://www.runoob.com/php/php-mysql-insert.html -> 實例 (PDO)

$res=$this->con->exec($sql);

//執(zhí)行之后 輸出返回的數(shù)據(jù)

$arr = array('result'=>$res);

echo json_encode($arr);

//關(guān)閉鏈接

$this->closeCon();

}

運行服務(wù),發(fā)現(xiàn)又報了 404 ,排查之后發(fā)現(xiàn)是 index.es 文件中的 uodate 寫成了 uodete ,誒,修改后 編譯 ,再運行點擊一下小手,數(shù)據(jù)庫里面的 num 的值 +1 證明成功了

需要注意的是 php返回的數(shù)據(jù)必須嚴(yán)格是 json 格式的 不然前臺 .js 文件 (未編譯:indexmodel.es 已編譯 indexmodel.js)中用到的 JSON.parse(result); 會一直報錯導(dǎo)致頁面崩潰

cd public\scripts\

babel index.es -o index-es.js

cd../..

node app_o.js

5. 對用戶連續(xù)點擊事件進(jìn)行稀釋

稀釋所用的方法就是 setTimeout

編輯 index.es 文件

let f = '';

class PraiseButton{

constructor(num,element){

this.num = num;

this.element = element;

}

clickAction(){

this.element.click(()=>{

//判斷事件是否已經(jīng)存在,如果存在便會將其清除掉,所以點擊只會執(zhí)行最后一次點擊的那次事件

if(f){

clearTimeout(f);

}

f = setTimeout(()=>{

if(this.num < 10){

this.element.css('-webkit-filter','grayscale(0)');

$('#animation').addClass('num');

this.num = add(this.num);

setTimeout(function () {

$('#animation').removeClass('num');

},1000);

axios.get('/index/update')

.then(function (response) {

console.log(response);

})

.catch(function (error) {

console.log(error);

});

}else{

this.element.css('-webkit-filter','grayscale(1)');

this.num = 0;

}

console.log(this.num);

},800)

})

}

}

class Thumb extends PraiseButton{

constructor(num,element){

super(num,element)

}

}

export default{Thumb}

// let? f = new Thumb(0,$('#thumb'));

// f.clickAction();

編譯文件

cd public\scripts\

babel index.es -o index-es.js

運行服務(wù),稀釋成功

node app_o.js

6. 完成點贊接口的自動化測試、點贊+1功能的自動化測試、真實頁面點擊自動化測試

1. 點贊+1功能的自動化測試

安裝 karma

cnpm install karma --save-dev

安裝斷言庫、核心、chrome 啟動器

cnpm install karma-jasmine jasmine-core karma-chrome-launcher --save-dev

安裝無界面瀏覽器、無界面瀏覽器啟動器

cnpm install phantomjs --save-dev

cnpm install karma-phantomjs-launcher --save-dev

karma 初始化生成配置文件 karma.conf.js

karma init

jasmine

no

PhantomJS

yes

5.在項目中新建一個 test 文件夾,在該文件夾下做三大測試

將 praisethumb 項目文件夾的中 index.spce.js 文件復(fù)制到 test 文件夾下

編輯 karma.conf.js 文件

files: [

'test/index.spec.js',

'public/scripts/index.js'

],

singleRun: true,

啟動測試,運行成功

karma start

2. 點贊接口的自動化測試

1.先安裝 mocha

cnpm install mocha --save-dev

安裝 supertest

cnpm install supertest --save-dev

在 test 文件夾下新建一個 server.js 文件

編輯 sever.js 文件,這里我們需要用到 supertest 模塊

參考鏈接:https://www.npmjs.com/package/supertest

import requestsuper from 'supertest';

//這里引用的是 app_o.js 文件拿到 app,所以需要在 app.js 文件中將其導(dǎo)出,然后再將 app.js 文件編譯為 app_o.js 文件

import app from '../app_o.js';

//先定義一個拿到端口的方法

function request(){

return requestsuper(app.listen());

}

describe('測試路由', function() {

it('點贊', function(done) {

request()

.get('/index/update')

.expect(200)

.end(function(err,res){

if(res.data==1)return done(err);

done();

})

});

});

修改 app.js 文件

export default app;

編譯文件

babel app.js -o app_o.js

cd test\

babel server.js -o server-es.js

執(zhí)行 server-es.js 文件

cd ..

mocha test\server-es.js

此時報如下圖所示的錯誤

image.png

將 mocha 安裝至全局

cnpm install mocha -g

執(zhí)行測試

mocha test\server-es.js

執(zhí)行成功

image.png

3. 真實頁面點擊自動化測試

1.安裝 selenium-webdriver

參考鏈接:https://www.npmjs.com/package/selenium-webdriver

cnpm install selenium-webdriver

2.下面火狐瀏覽器所需的相應(yīng)組件

參考鏈接:https://github.com/mozilla/geckodriver/releases/找到與當(dāng)前設(shè)備匹配的一款點擊下載 我的是 win64

將下載好的壓縮包解壓至 koatest 項目文件夾中,刪除壓縮包

再安裝兩個包

cnpm install selenium-standalone --save

cnpm install protractor --save

test 文件夾下新建 e2e.js 文件

編輯 e2e.js 文件

參考鏈接:https://www.npmjs.com/package/selenium-webdriver->? Usage

const {Builder, By, Key, until} = require('selenium-webdriver');

let driver = new Builder()

.forBrowser('firefox')

.build();

//設(shè)置地址

driver.get('http://localhost:3000/index/index');

driver.findElement(By.id('thumb')).click();

const _animation = driver.findElement(By.id('animation'))

driver.wait(_animation.isDisplayed(), 1000);

// driver.quit(); //為了看到效果將關(guān)閉瀏覽器的行為暫時注釋掉

執(zhí)行測試腳本 e2e.js 文件

node test\e2e.js

此時會發(fā)現(xiàn)瀏覽器打開頁面后,頁面并不能加載出來原因是這個 koatest 項目此時并沒有處于運行狀態(tài),所以需要新建一個命令行窗口中執(zhí)行項目運行操作

image.png

在新窗口中輸入命令

cd Desktop

cd koatest

node app_o.js

此時再在之前的命令行窗口中執(zhí)行測試腳本 e2e.js 文件

node test\e2e.js

整個實戰(zhàn)到此結(jié)束。

作者:sunxiaochuan

鏈接:http://m.itdecent.cn/p/2a9367afe9e7

來源:簡書

著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容