2017.4.11 - 4.13
前言:
上周大致瀏覽了Vue文檔,簡單使用了Vue.js文件嘗試基本Vue特性晚伙。在這一周颖低,學(xué)習(xí)Vue入門教程,完成了一個登錄界面的Vue組件陌宿,并且通過與nodeJs的連接實現(xiàn)了登錄驗證锡足。
在下一周中,學(xué)習(xí)Vue組件的套用壳坪,使用less完善css舶得,使用Vuex管理項目狀態(tài)。
筆記導(dǎo)航
- Vue框架搭建
- Vue前端組件搭建
- Vue服務(wù)器端通信
項目要求
使用VUE實現(xiàn)求職系統(tǒng)爽蝴,系統(tǒng)主要功能包括 注冊沐批,登錄,職位查詢蝎亚,職位保存九孩,求職跟蹤,報表系統(tǒng)发框,具體要求如下:
新用戶可以注冊賬號躺彬,注冊需要通過email,系統(tǒng)將驗證碼發(fā)送到郵箱梅惯,用戶需要填寫驗證碼完成注冊宪拥;
用戶可以根據(jù)用戶名和密碼登錄系統(tǒng);
在職位查詢中铣减,用戶可以根據(jù)公司名稱她君,薪水,職位類型查詢求職信息葫哗;
用戶可以將查詢中的某些記錄加入到自己的關(guān)注信息缔刹;
用戶可以將某些公司加入到求職跟蹤,系統(tǒng)從招聘網(wǎng)站(比如智聯(lián)招聘)抓取數(shù)據(jù)劣针,并自動統(tǒng)計該公司每周的求職信息桨螺,發(fā)送給用戶;
報表系統(tǒng)提供多種信息分析圖表酿秸,比如各職位的數(shù)量餅狀圖灭翔,某職位的薪資變化圖等等;
項目周期:3年級學(xué)生6周
知識要點:
1 . 掌握模板語法 v-html v-bind v-on v-show v-if v-for
2 . 理解vue-router路由模板以及路由事件的處理
3 . 掌握使用vue-resource訪問網(wǎng)絡(luò)服務(wù)
4 . 理解vuex狀態(tài)管理模式
5 . 掌握使用webpack來模塊化管理和打包
具體筆記
1. Vue項目的搭建
官方介紹文檔
根據(jù)官方示例搭建環(huán)境,并且使用webpack依賴創(chuàng)建一個Vue項目
# 全局安裝 vue-cli
$ npm install --global vue-cli
# 創(chuàng)建一個基于 webpack 模板的新項目
$ vue init webpack my-project
# 出現(xiàn)多行參數(shù)配置提示肝箱,一路回車就好
# 安裝依賴哄褒,走你
$ cd my-project
$ npm install
# npm install因命令安裝內(nèi)容較多,需要時間比較久
$ npm run dev
# 執(zhí)行run命令煌张,即可運行程序自動打開瀏覽器并顯示vue界面
# 此處使用的服務(wù)器端口號是8080呐赡,注意自己的電腦上是否有其他應(yīng)用占用此端口,有則改之
項目創(chuàng)建完成之后骏融,目錄結(jié)構(gòu)及其目錄內(nèi)文件功能說明如下圖:
.
├── build/ # webpack config files
│ └── ...
├── config/
│ ├── index.js # main project config
│ └── ...
├── src/
│ ├── main.js # app entry file
│ ├── App.vue # main app component
│ ├── components/ # ui components
│ │ └── ...
│ └── assets/ # module assets (processed by webpack)
│ └── ...
├── static/ # pure static assets (directly copied)
├── test/
│ └── unit/ # unit tests
│ │ ├── specs/ # test spec files
│ │ ├── index.js # test build entry file
│ │ └── karma.conf.js # test runner config file
│ └── e2e/ # e2e tests
│ │ ├── specs/ # test spec files
│ │ ├── custom-assertions/ # custom assertions for e2e tests
│ │ ├── runner.js # test runner script
│ │ └── nightwatch.conf.js # test runner config file
├── .babelrc # babel config
├── .postcssrc.js # postcss config
├── .eslintrc.js # eslint config
├── .editorconfig # editor config
├── index.html # index.html template
└── package.json # build scripts and dependencies
./src/components/Hello.vue
就是服務(wù)器啟動后在瀏覽器中打開的vue組件链嘀,在編輯器中打開這個文件進行修改后保存,即可在瀏覽器中看到代碼的同步更新档玻。
如果出現(xiàn)語法錯誤或格式錯誤怀泊,瀏覽器也會直接提示error信息,十分簡單粗暴便利误趴。
2. Vue組件界面搭建
簡明的入門視頻教程Vue.js 2.0入門
Vue-resource 一個類似于ajax的工具
登錄組件搭建:
<template>
<div class="login">
<form @submit.prevent='submit'>
<label>username: </label>
<input type="text" v-model='user.username'>
<br>
<label>password: </label>
<input type="password" v-model='user.password'>
<br>
<input type="submit" value="submit">
</form>
</div>
</template>
<script>
export default {
name: 'login',
data () {
return {
user: {
username: '',
password: ''
}
}
},
methods: {
submit: function () {
// 向后臺發(fā)送ajax請求
}
}
}
</script>
<style scoped>
.login {
text-align: center;
}
</style>
3.后臺處理登錄請求
使用命令行創(chuàng)建express框架的新項目
express --view=hbs [project_name]
npm install
實現(xiàn)Vue項目與node后臺的連接
(跨域訪問后臺的教程)[http://www.imooc.com/article/8093]
關(guān)鍵在于設(shè)置訪問來源地址
//在app.js中完成如下設(shè)置霹琼,即可實現(xiàn)兩個端口進程之間的通信
app.all("*", function (req, res, next) {
// 修改Access-Control-Allow-Origin的參數(shù)值,設(shè)成'*'會有收到不明攻擊的危險凉当,因此最好改成指定地址
res.header('Access-Control-Allow-Origin', 'http://localhost:[node端口號]');
res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
if (req.method == 'OPTIONS') {
res.send(200);
} else {
next();
}
});
前端Vue界面
<template>
<div class="login">
// 此處觸發(fā)submit函數(shù)枣申,通過.prevent禁止頁面的刷新跳轉(zhuǎn)
<form @submit.prevent='submit'>
<label>username: </label>
<input type="text" v-model='user.username'>
<br>
<label>password: </label>
<input type="password" v-model='user.password'>
<br>
<input type="submit" value="login">
<p v-if='user.validated'>{{user.errmsg}}</p>
</form>
</div>
</template>
<script>
export default {
name: 'login',
data () {
return {
user: {
username: '',
password: '',
validated: false,
errmsg: ''
}
}
},
methods: {
submit: function () {
this.$http.post('http://localhost:8888/login', {
username: this.user.username,
password: this.user.password
}).then(function (res) {
// res即為服務(wù)器端發(fā)送過來的信息,通過res.body獲取json數(shù)據(jù)
console.log(res)
this.user.errmsg = ''
this.user.errmsg = res.body.errmsg
this.user.validated = res.body.validated
if (!res.body.validated) {
alert('Welcome back, ' + this.user.username + ' !')
}
})
}
}
}
</script>
<style scoped>
.login {
text-align: center;
}
</style>
后臺服務(wù)器數(shù)據(jù)請求與處理
//app.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var morgan = require('morgan');
var MongoClient = require('mongodb').MongoClient;
var mongoUrl = 'mongodb://localhost:27017/zhaopin';
var _db;
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(express.static('dist'));
app.all("*", function (req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:8080');
res.header("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
if (req.method == 'OPTIONS') {
res.send(200);
} else {
next();
}
});
// 連接mongodb數(shù)據(jù)庫
MongoClient.connect(mongoUrl, function (err, db) {
if(err) {
console.error(err);
return;
}
console.log('connected to mongo');
_db = db;
app.listen(8888, function () {
console.log('server is running...');
});
});
// ************ nodejs中的路由部分 ************
app.post('/login', function(req, res, next){
var user = req.body;
console.log(user)
var collection = _db.collection('user');
if(!user.username || !user.password){
res.send({validated: true, errmsg:"Please enter the entire info"});
return;
}
collection.find({username: user.username}, function(err, ret){
ret.toArray(function(err, doc){
if (err) {
console.log(err);
}else if(doc.length == 1){
if (doc[0].password == user.password) {
res.send({validated: false, errmsg:''});
} else {
res.send({validated: true, errmsg:'Please enter the correct pwd...'})
return;
}
}else{
res.send({validated: true, errmsg: 'This account doesn\'t exist...'})
return;
}
})
})
})
app.post('/register', function(req, res, next){
var user = req.body;
var collection = _db.collection('user');
if(!user.username || !user.password){
res.send({validated: true, errmsg:"Please enter the entire info"});
return;
}
collection.find({username: user.username}, function(err, ret){
ret.toArray(function(err, doc){
if (err) {
console.log(err);
}else if(doc.length == 1){
res.send({validated: true, errmsg:"Sorry, this username has been registered!"});
return;
}else{
collection.insert({username: user.username, password: user.password}, function(err, ret){
if(err){
console.error(err);
}else {
res.send({validated: false, errmsg: ''});
}
})
}
})
});
})
// ************ nodejs中的路由部分 ************