vue+node+mysql搭建我的博客(一)

學習筆記...
在線地址: cl8023.com github
數據庫已改成mongodb

程序員詞彙學習網: www.english4coder.com css

快速搭建 node 後端服務
Github-quick-node-serverhtml

準備工做

安裝node,這是必須的

新版node自帶npm,安裝Node.js時會一塊兒安裝,npm的做用就是對Node.js依賴的包進行管理,也能夠理解爲用來安裝/卸載Node.js須要裝的東西。
驗證是否安裝成功:
驗證是否安裝成功
推薦windows下終端工具:cmdervue

npm安裝vue-cli

使用npm下載依賴包是可能有些慢,因此這裏能夠換上淘寶的鏡像cnpm。
打開終端(能夠在任何位置),輸入
npm install cnpm -g --registry=https://registry.npm.taobao.org
cnpm跟npm用法徹底一致,只是在執行命令時將npm改成cnpm。
如今來安裝vue-cli:輸入
npm install -g vue-cli 或者 cnpm install -g vue-cli
命令中 -g 表示全局安裝,會安裝到node安裝目錄下的node_modules文件夾下,看看裏面是否是多了vue-cli文件夾,若是沒有,看看npm模塊的安裝路徑
npm config ls
能夠查看模塊的安裝路徑 prefix,具體設置請自行百度。
npm模塊安裝路徑node

vue-cli快速構建項目

  • 選定一個你喜歡的文件夾,進入該文件夾下,以後建立的項目目錄就在文件夾下
  • 打開終端,進入目標文件夾,以 D: 爲例,使用webpack模板構建項目,輸入

vue init webpack my-blog
此時會自動從github下載文件目錄到目標文件夾,上不了github的只能想辦法了,從別處把構建好的文件所有拷過來也是能夠的。mysql

運行項目

  • 一、進入my-blog文件夾,首先能夠看到文件夾下有一個package.json文件,這個文件很重要,裏面記錄的項目的一些信息和運行成功運行項目必須的一些依賴包,以後安裝的一些包也要記錄到裏面,方便別人拷貝過來你的項目時安裝依賴,順利運行。
  • 二、新版本的 vue-cli 在執行 vue init webpack my-blog 第9步時會有一個選擇:
    npm i for pro
    若是選擇了Yes,則可跳過步驟3,若是選擇了No,則按照步驟3進入文件夾安裝依賴。
  • 三、終端輸入(要在此文件夾下)輸入:cnpm install install能夠簡寫爲 i 即 cnpm i,cnpm安裝應該挺快的,安裝完成後會看到文件夾下多了個node_modules文件夾,裏面就是運行項目所須要的一些依賴包,能夠看到此文件夾雖然不大,可是裏面文件個數有上千個,因此拷貝起來也是挺麻煩的,因此把依賴包記錄到package.json裏面,別人只要從新下載安裝一下就行了,上傳到github上也方便。
  • 四、啓動項目:輸入 npm run dev,等待瀏覽器自動打開。
    npm run dev 執行的命令便是package.json裏 scripts下的dev:node build/dev-server.jsjquery

    "scripts": {
        "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
        "start": "npm run dev",
        "build": "node build/build.js"
      },

    構建項目

    默認端口爲8080,若此時8080端口被佔用則會出錯webpack

    ...
    > Starting dev server...
    events.js:160
    throw er; // Unhandled 'error' event
          ^
    Error: listen EADDRINUSE :::8080  
    .....

    能夠在D:\my-blog\config\index.js裏修改端口ios

    dev: {
    
        // Paths
        assetsSubDirectory: 'static',
        assetsPublicPath: '/',
        proxyTable: {},
    
        // Various Dev Server settings
        host: 'localhost', // can be overwritten by process.env.HOST
        port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
        autoOpenBrowser: false,
        errorOverlay: true,
        notifyOnErrors: true,
        poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
    
    
    
        // https://webpack.js.org/configuration/devtool/#development
        devtool: 'cheap-module-eval-source-map',
    
        // If you have problems debugging vue-files in devtools,
        // set this to false - it *may* help
        // https://vue-loader.vuejs.org/en/options.html#cachebusting
        cacheBusting: true,
    
        cssSourceMap: true
      },

    啓動成功後:git

    ...
     DONE  Compiled successfully in 2597ms                                                          
     I  Your application is running here: http://localhost:8080

    啓動成功

安裝須要用到的包

首先安裝項目要用到的一些組件,也能夠以後遇到什麼須要的再安裝程序員

  • element-ui:餓了麼前段組件庫,能夠幫助快速創建起前段頁面,少些不少樣式
  • vuex:vue狀態管理
  • axios:基於Promise 用於瀏覽器和 nodejs 的 HTTP 客戶端
  • mysql:鏈接mysql數據庫
  • express:
  • body-parser:
  • node-sass:sass-loader依賴
  • sass-loader:解析sass/scss文件

能夠依次安裝( npm 安裝很慢的可使用 cnpm ):

npm install element-ui --save  (回車)
npm install vuex --save  (回車)
npm install axios --save  (回車)
npm install mysql --save  (回車)
npm install express --save  (回車)
npm install body-parser --save  (回車)
npm install node-sass --save-dev  (回車)
npm install sass-loader --save-dev  (回車)

也能夠一塊兒安裝:

npm install element-ui vuex axios mysql express body-parser --save  (回車)
npm install node-sass sass-loader --save-dev  (回車)

--save 意思就是將依賴記錄在 package.json 裏的 dependencies 下,以後生產環境也是須要這些包的,--sava-dev 是將依賴記錄在 package.json 裏的 devDependencies 下,只是開發環境須要這些包,方便開發調試,而生產環境不須要。(-S 是 --save 的縮寫,-D 是 --save-dev 的縮寫)

"dependencies": {
    "axios": "^0.18.0",
    "body-parser": "^1.18.3",
    "element-ui": "^2.3.9",
    "express": "^4.16.3",
    "mysql": "^2.15.0",
    "vue": "^2.5.2",  // 項目構建完就有了
    "vue-router": "^3.0.1",  // 項目構建完就有了 當時"Install vue-router"選了Yes
    "vuex": "^3.0.1"
  },
  "devDependencies": {
    ...
    "node-sass": "^4.9.0",
    "sass-loader": "^7.0.1",
    ...
  },
使用scss/sass前必須先安裝node-sass、sass-loader,不然運行npm run dev時會報錯
<style lang="scss" scoped>
  $bgColor: #F90;
  .blog-home {
    background: $bgColor
  }
</style>

調用後臺接口 ajax 請求數據

一、打開入口js文件main.js,引入element-ui組件來搭建頁面 element-ui 查看官網文檔

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.config.productionTip = false
Vue.use(ElementUI);
Vue.prototype.$http = axios;

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

其中 axios 用來完成 ajax 請求,

import axios from 'axios'
axios.get('/', function() {});
axios.post('/', function() {});

// 將 axios 添加的 Vue 原型上後就不須要再在每一個須要使用它的頁面引入了
Vue.prototype.$http = axios;
$http.get('/', function() {});
$http.post('/', function() {});

二、每一個頁面都至關於一個組件,文件以.vue結尾,第一次啓動成功時看到的頁面就是組件Hello.vue,路徑src/components/Hello.vue。路由地址在 src/router/index.js 中配置,打開修改咱們待會本身要用的:

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Home from '@/components/pages/Home'
import Blog from '@/components/pages/Blog'

Vue.use(Router)

export default new Router({
  routes: [
    // {
    //   path: '/',
    //   name: 'HelloWorld',
    //   component: HelloWorld
    // },
    {
      path: '/', // http://localhost:8080/#/
      name: 'Home',
      component: Home
    },
    {
      path: '/blog', // http://localhost:8080/#/blog
      name: 'Blog',
      component: Blog
    }
  ]
})

上面引入了三個組件HelloWorld.vue(默認),Home.vue,Blog.vue。
path是頁面地址,name能夠隨便寫,component 是 import 的組件名。

三、在 scr/components 下新建文件夾 pages,在 pages 下新建文件 Home.vue,Blog.vue,裏面按規則要求寫好內容,運行工程打開頁面 http://localhost:8080/#/、http://localhost:8080/#/blog 便可看到相應的內容。
在 Blog.vue 中輸入下面內容用來後面測試調用接口

<template>
  <div class="">
    <el-button type="primary" @click="getArticle">調用後臺接口</el-button>
    <el-input v-model="inpContent"></el-input>
  </div>
</template>

<script>
export default {
  name: 'blog',
  data() {
    return {
      inpContent: 'Blog'
    }
  },
  methods: {
    getArticle() {
      this.$http.get('/api/getArticle')
        .then( (res) => {
          console.log('res', res);
          this.inpContent = res.data.data;
        })
    }
  }
}
</script>

四、後端使用Express作服務端提供數據接口,不瞭解的能夠先去官網文檔大體瞭解一下 Express官網,在根目錄my-blog下建立文件夾server用來存放後端數據庫配置數據和相關方法api。
server文件夾下建立文件:index.js

const path = require('path');
const express = require('express');
const app = express();

app.get('/api/getArticle', (req, res, next) => {
  res.json({
      data: '後臺返回結果 getArticle'
    })
})

// 監聽端口
app.listen(3000);
console.log('success listen at port:3000......');

另開一個 CMD 窗口,進入目錄 D:my-blogserver

D:\my-blog\server
$ node index.js
success listen at port:3000......

五、打開 http://localhost:8080/#/blog 點擊按鈕"調用後臺接口",會發現控制檯報錯
調後臺接口報錯_跨域
這是由於咱們工程運行的端口是8080,然後端程序運行的端口是3000,因此是跨域請求,要想請求成功,就要先在配置裏設置一下代理

六、打開文件 /config/index.js,將 proxyTable 項設置以下

proxyTable: {
  '/api': {
    target: 'http://localhost:3000/api',
    changeOrigin: true,
    pathRewrite: {
      '^/api': ''
    }
  }
}
  • '/api': 表示全部以 /api 爲開頭的請求,如咱們的請求 this.$http.get('/api/getArticle')
  • target: 將全部以 /api 爲開頭請求轉發到 http://localhost:3000/api
  • changeOrigin: true/false, Default: false,本地會虛擬一個服務端接收你的請求並代你發送該請求(不太明白,false 試了也能夠)
  • pathRewrite: 重寫地址。 '^/api': '' 表示將以 /api 開頭的請求的地址中的 '/api' 替換爲 '',
    即 path = path.replace(/^/api/, '')
    eg: this.&dollar;http.get('/api/getArticle')
    path = '/api/getArticle'
    path = path.replace(/^/api/, '') = '/getArticle'
    這樣目標請求就變成了 http://localhost:3000/api/getArticle ,
    若是不寫 pathRewrite, 請求則爲 http://localhost:3000/api/api/getArticle 因此也能夠這樣

    proxyTable: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
      }
    }

    最後請求一樣轉發爲 http://localhost:3000/api/getArticle , 總之要和後臺的接口路徑對應上,不過仍是建議加上 pathRewrite,方便同類方法調用

    // server/index.js
    const path = require('path');
    const express = require('express');
    const router = express.Router();
    const app = express();
    
    app.use('/add', router);
    app.use('/del', router);
    
    router.get('/getArticle1', (req, res, next) => {
      api.getArticle(req, res, next);
    })
    router.get('/getArticle2', (req, res, next) => {
      api.getArticle(req, res, next);
    })
    
    router.get('/delArticle1', (req, res, next) => {
      api.getArticle(req, res, next);
    })
    router.get('/delArticle2', (req, res, next) => {
      api.getArticle(req, res, next);
    })
    
    // 監聽端口
    app.listen(3000);
    console.log('success listen at port:3000......');
    
    ----------------------------------------------
    
    // congif/index.js
    proxyTable: {
      '/add': {
        target: 'http://localhost:3000/add',
        changeOrigin: true,
        pathRewrite: {
            '^/add': ''
          }
      },
      '/del': {
        target: 'http://localhost:3000/del',
        changeOrigin: true,
        pathRewrite: {
            '^/del': ''
          }
      },
    },

七、正確返回數據

數據庫存取數據(Mysql)

Mysql可視化工具我用的是Navicat For Mysql,新建鏈接,數據庫,數據表,查詢等均可在其中完成,固然熟悉命令的均可以在cmd中命令完成

Mysql 新建鏈接

新建數據庫

鏈接數據庫

在 src/server 下新建文件 db.js,寫入下面代碼

const mysql = require('mysql');

const mysqlConfig = {
  host: 'localhost',  // 新建數據庫鏈接時的 主機名或ID地址 內容
  user: 'root', 
  password: '8023', // root 密碼
  database: 'myBlog', // 數據庫名
  port: '3306'
}
const pool = mysql.createPool({
  host: mysqlConfig.host,
  user: mysqlConfig.user,
  password: mysqlConfig.password,
  database: mysqlConfig.database,
  port: mysqlConfig.port,
  multipleStatements: true    // 多語句查詢
});

var setValue = function() {
  pool.getConnection((err, connection) => {
    var sql = 'INSERT INTO test(id, name) VALUES (1, "blog")'
    connection.query(sql, (err, result) => {
        console.log(result);
        connection.release();
    })
  })
}

setValue();

引入包 mysql,建立鏈接池 mysql.createPool,sql語法和在命令中使用的形同,拼成字符串便可,在 server 目錄下運行 db.js 文件,刷新數據庫
添加數據

同理可增刪查改數據

// 查詢數據,? 的值填入 connection.jquery 的第二個參數(數組)中
// WHERE id = ? AND name = ? ---> connetion.query(sql, [1, "blog"], () => )
var getValue = function() {
  pool.getConnection((err, connection) => {
    var sql = 'SELECT * FROM test WHERE id = ?'
    connection.query(sql, [1], (err, result) => {
        console.log(result);
        connection.release();
    })
  })
}
getValue();

/*
$ node db.js
[ RowDataPacket { id: '1', name: 'blog' } ]
*/

// 更新數據
var updValue = function() {
  pool.getConnection((err, connection) => {
    var sql = 'UPDATE test SET name = ? WHERE id = ?'
    connection.query(sql, [22, 1], (err, result) => {
        console.log(result);
        connection.release();
    })
  })
}
updValue();

// 刪除數據
var delValue = function() {
  pool.getConnection((err, connection) => {
    var sql = 'DELETE FROM test WHERE id = ?'
    connection.query(sql, [1], (err, result) => {
        console.log(result);
        connection.release();
    })
  })
}
delValue();

結合前面的 ajax 請求數據,咱們即可以輕鬆的對數據庫中的數據進行操做了,下面來模塊化這些操做。

模塊化後端代碼

在 /server 下建立文件

  • db.js 數據庫鏈接配置
  • api.js 鏈接數據庫,各類方法實現
  • sqlMap.js sql語句
  • router.js 後端 express 路由配置
  • index.js 後端入口文件,啓動後端服務

一、db.js

// 數據庫鏈接配置
module.exports = {
  mysql: {
    host: 'localhost',  // 新建數據庫鏈接時的 主機名或ID地址 內容
    user: 'root', 
    password: '8023', // root 密碼
    database: 'myBlog', // 數據庫名
    port: '3306'
  }
}

二、api.js

const mysql = require('mysql');
const dbConfig = require('./db');
const sqlMap = require('./sqlMap');

const pool = mysql.createPool({
  host: dbConfig.mysql.host,
  user: dbConfig.mysql.user,
  password: dbConfig.mysql.password,
  database: dbConfig.mysql.database,
  port: dbConfig.mysql.port,
  multipleStatements: true    // 多語句查詢
});

module.exports = {
  getValue(req, res, next) {
    var id = req.query.id;
    pool.getConnection((err, connection) => {
      var sql = sqlMap.getValue;
      connection.query(sql, [id], (err, result) => {
          res.json(result);
          connection.release();
      })
    })
  },
  setValue(req, res, next) {
    console.log(req.body);
    var id = req.body.id, name = req.body.name;
    pool.getConnection((err, connection) => {
      var sql = sqlMap.setValue;
      connection.query(sql, [name, id], (err, result) => {
          res.json(result);
          connection.release();
      })
    })
  }
}

三、sqlMap.js

var sqlMap = {
  getValue: 'SELECT * FROM test WHERE id = ?',
  setValue: 'UPDATE test SET name = ? WHERE id = ?'
}

module.exports = sqlMap;

四、router.js

const express = require('express');
const router = express.Router();
const api = require('./api');

router.get('/getValue', (req, res, next) => {
  api.getValue(req, res, next);
});

router.post('/setValue', (req, res, next) => {
  api.setValue(req, res, next);
});

module.exports = router;

五、index.js

const routerApi = require('./router');
const bodyParser = require('body-parser'); // post 數據是須要
const express = require('express');
const app = express();

app.use(bodyParser.json());

// 後端api路由
app.use('/api', routerApi);

// 監聽端口
app.listen(3000);
console.log('success listen at port:3000......');

在 /scr/components/pages/Blog.vue 文件中寫入下面代碼測試

<template>
  <div class="">
    <el-input v-model="inpContent"></el-input>
    <el-button type="primary" @click="getValue">獲取數據</el-button>
    <el-button type="primary" @click="setValue">添加數據</el-button>
  </div>
</template>

<script>
export default {
  name: 'blog',
  data() {
    return {
      inpContent: ''
    }
  },
  methods: {
    getValue() {
      // axios.get('/', {params: ''})
      this.$http.get('/api/getValue', {
        params: {id: 1}
      }).then( (res) => {
        console.log('res', res);
        this.inpContent = res.data[0].name;
      })
    },
    setValue() {
      // axios.post('/', {})
      this.$http.post('/api/setValue', {
        id: 1, name: this.inpContent
      }).then( (res) => {
        console.log('res', res);
      })
    }
  }
}
</script>
  • get:第二個參數(可選)是一個對象,以 params 爲屬性,將條件數據傳到後臺,後臺經過 req.query 能夠得到 params 對應的值
  • post:第二個參數(可選)也是一個對象,屬性任意,將提交數據傳到後臺,後臺經過 req.body 能夠得到這個對象,req.body 數據的解析須要用到包 body-parser,在 index.js 中引入 use 便可。

打開兩個命令窗口分別運行工程,運行後端服務,便可進行測試:

D:\my-blog
$ npm run dev
D:\my-blog\server
$ node index.js
相關文章
相關標籤/搜索