.Net Core+Vue.js+ElementUI 實現前后端分離


.Net Core+Vue.js+ElementUI 實現前后端分離

Tags: Vue


架構

前端采用:Vue.js、Element-UI、axios
后端采用:.Net Core Mvc
本項目是基於Vue.js的多頁應用,由於是后端開發對不擅長Node.js開發並且希望使用傳統的方式進行權限管控及生產發布,所以.Net Core Mvc 承擔了所有的頁面路由管控及頁面級權限控制,Vue.js只是作為視圖渲染及頁面交互使用。

准備工作

Node安裝及配置

node -v
  • 配置淘寶npm鏡像
 # 臨時使用
 npm --registry https://registry.npm.taobao.org install express
 
 # 永久使用
 npm config set registry https://registry.npm.taobao.org
 
 # 配置后可通過下面方式來驗證是否成功 
 npm config get registry

客戶端實現


搭建vue腳手架

  • 使用npm全局安裝vue-cli腳手架構建工具
    vue-cli 提供一個官方命令行工具,可用於快速搭建大型單頁應用。該工具提供開箱即用的構建工具配置,帶來現代化的前端開發流程。只需幾分鍾即可創建並啟動一個帶熱重載、保存時靜態檢查以及可用於生產環境的構建配置的項目:
npm install -g vue-cli
  • 創建一個基於 webpack 模板的新項目
# vue-multiple為自定義名稱,注意項目名稱不能大寫
vue init webpack vue-multiple

# 初始化配置中 Install vue-router? 選擇 no, 不使用vue-router,其他配置項默認即可

執行初始化命令后需要輸入以下內容:

 1. Project name (my-project) # 項目名稱(我的項目) 
 2. Project description (A Vue.js project) # 項目描述一個Vue.js 項目 
 3. Author 作者(你的名字) 
 4. Install vue-router? (Y/n)# 是否安裝Vue路由,也就是以后是spa(但頁面應用需要的模塊) 
 5. Use ESLint to lint your code? (Y/n) # 使用 ESLint 到你的代碼? (Y [ yes ] / N [ no ]) 
 6. Pick an ESLint preset (Use arrow keys) # 選擇一個預置ESLint(使用箭頭鍵) Setup unit tests with
 7. Karma + Mocha? (Y/n) # 設置單元測Karma + Mocha? (Y/ N) Setup e2e tests
 8. with Nightwatch? (Y/n) # 設置端到端測試,Nightwatch? (Y/ N)
  • 安裝項目所需要的依賴
cd vue-multiple

# 本地安裝npm依賴包,保存至 ./node_modules目錄

npm install

chromedriver@2.38.3 install: node install.js 報錯解決辦法:

 1.全局安裝 chromedriver
npm install chromedriver -g

 2.指定淘寶鏡像安裝
npm install chromedriver --chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver
  • 運行項目
#運行dev命令 啟動server服務器,並監聽8080端口,開發環境測試使用

npm run dev 

#看到  I  Your application is running here: http://localhost:8080 並且能夠成功訪問  http://localhost:8080   表示項目創建成功 


修改項目模板目錄

build/                       #webpack打包配置
    build.js                 #構建生產代碼
    check-versions.js        #檢測node及npm版本
    vue-loader.conf.js       #處理Vue文件中的樣式 vue開發環境的wepack相關配置文件,主要用來處理各種文件的配置
    utils.js                 #額外的通用方法
    webpack.base.conf.js     #默認的webpack配置
    webpack.dev.conf.js      #本地開發的webpack配置
    webpack.prod.conf.js     #構建生產的webpack配置
config/   配置文件
    dev.env.js
    index.js                 #定義開發環境和生產環境中所需要的參數
    pord.env.js
    test.env.js
src/
    assets/                  #放資源
    components/              #公共組件
    views/                   #頁面模塊
        home/                #子頁面
            index.html       #模版頁面
            index.js         #js入口
        // 注意,這里的html和js的文件名要一致,如上面就是index    
dist/                        #最后打包生成的資源

修改webpack打包配置以支持多頁應用開發 webpack中文

  • 修改build/utils.js文件,添加以下代碼:
const glob = require('glob')
// 頁面模板
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 取得相應的頁面路徑,因為之前的配置,所以是src文件夾下的views文件夾
const PAGE_PATH = path.resolve(__dirname, '../src/views')
// 用於做相應的merge處理
const merge = require('webpack-merge')

// 多頁面入口配置,通過glob模塊讀取views文件夾下所有對應文件夾下的js后綴文件,作為入口文件處理
exports.entries = function () {
  var entryFiles = glob.sync(PAGE_PATH + '/*/*.js')
  var entries = {},
    basename,
    tmp,
    pathname;
  entryFiles.forEach((entry) => {
    basename = path.basename(entry, path.extname(entry));
    tmp = entry.split("/").splice(-3);
    pathname = tmp.splice(1, 1) + "/" + basename; // 正確輸出js和html的路徑
    entries[pathname] = entry;
  })
  return entries
}
// 多頁面輸出配置,與上面的多頁面入口配置相同,讀取views文件夾下的對應的html后綴文件,然后放入數組中
exports.htmlPlugin = function () {
  let entryHtml = glob.sync(PAGE_PATH + '/*/*.html')
  let htmlentries = []
  let basename,
    tmp;
  entryHtml.forEach((filePath) => {
    basename = path.basename(filePath, path.extname(filePath));
    tmp = filePath.split("/").splice(-3);
    let filename = tmp.splice(1, 1) + "/" + basename; // 正確輸出js和html的路徑
    let conf = {
      // 模板來源
      template: filePath,
      // 文件名稱
      filename:  filename + '.html',
      // 頁面模板需要加對應的js腳本,如果不加這行則每個頁面都會引入所有的js腳本
      chunks: ['manifest', 'vendor', filename],
      inject: true
    }
    if (process.env.NODE_ENV === 'product') {
      conf = merge(conf, {
        minify: {
          removeComments: true,
          collapseWhitespace: true,
          removeAttributeQuotes: true
        },
        chunksSortMode: 'dependency'
      })
    }
    htmlentries.push(new HtmlWebpackPlugin(conf))
  })
  return htmlentries
}

  • 修改webpack.base.conf.js:配置多個頁面的js入口
module.exports = {
  entry: utils.entries(), //設置多個頁面的js入口
  ...
}
  • 修改webpack.dev.conf.js:本地開發的多頁面配置
plugins: [
    ...
    // 注釋HtmlWebpackPlugin相關配置
    // new HtmlWebpackPlugin({
    //   filename: 'index.html',
    //   template: 'index.html',
    //   inject: true
    // }),
    ...
  ].concat(utils.htmlPlugin()) //添加Html模板集合
  • 修改webpack.prod.conf.js:構建生產的多頁面配置
 plugins: [
    ...
    // 注釋HtmlWebpackPlugin相關配置
    // new HtmlWebpackPlugin({
    //   filename: process.env.NODE_ENV === 'testing' ?
    //     'index.html' :
    //     config.build.index,
    //   template: 'index.html',
    //   inject: true,
    //   minify: {
    //     removeComments: true,
    //     collapseWhitespace: true,
    //     removeAttributeQuotes: true
    //     // more options:
    //     // https://github.com/kangax/html-minifier#options-quick-reference
    //   },
    //   // necessary to consistently work with multiple chunks via CommonsChunkPlugin
    //   chunksSortMode: 'dependency'
    // }),
    ...
  ].concat(utils.htmlPlugin())  //添加Html模板集合

如何去除js、css文件名hash值

    // 刪除filename中的contenthash配置去除css文件名hash
    new ExtractTextPlugin({
      filename: utils.assetsPath('css/[name].css'),
      allChunks: true,
    })
    
    // 刪除filename和chunkFilename中的chunkhash配置去除js文件名hash
    output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
    }
    
    
  
  • 執行npm run build 指令測試打包是否成功
打包成功生成以下目錄及文件
dist\
    home\
        index.html
    static
        css
            home
                index.css
        js
            home index.js
        manifest.js
        vender.js

github地址:https://github.com/chubin518/vue-multiple.git

服務端實現

  • 打開VS創建Web應用,項目創建成功后刪除不必要的js、css引用等。
  • 將生成的dist目錄拷貝紙wwwroot文件加下
  • _layout.cshtml 模板頁添加 vender.js 、 manifest.js 引用
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - NetCoreVueMultiple</title>
    <link href="~/dist/static/css/main/index.css" rel="stylesheet" />
    @RenderSection("Styles", required: false)
</head>
<body>
    @RenderBody()
    <script src="~/dist/static/js/manifest.js"></script>
    <script src="~/dist/static/js/vendor.js"></script>
    <script src="~/dist/static/js/main/index.js"></script>
    @RenderSection("Scripts", required: false)
</body>
</html>

element-ui的引入方式參考官網
本實例使用webpack一起打包進了vendor.js中

  • 修改Index.cshtml 如下:
@{
    ViewData["Title"] = "Home Page";
}
@section Styles{
    <link href="~/dist/static/css/home/Index.css" rel="stylesheet" />
}
<div id="app">
</div>
@section Scripts{
    <script src="~/dist/static/js/home/Index.js"></script>
}
  • 編譯項目運行

github地址:https://github.com/chubin518/NetCoreVueMultiple.git

  • 也可將前后端項目合並,將vue項目相關文件復制到MVC項目根目錄,修改config/index.js
  build: {
    // 輸出打包后的文件至wwwroot下的dist文件夾,執行npm run build 會自動生成js至wwwroot/dist下
    assetsRoot: path.resolve(__dirname, '../wwwroot/dist'),
    }
  • 如果項目中已經已經以script的方式引入vue.js /element-ui 等框架時,再次引用manifest.js,vendor.js文件可能會引起js框架版本沖突等問題

此時可通過配置設置不打包公共組件,具體操作如下:

  • 修改webpack.base.conf.js,不打包的文件
let exten = {};
if (process.env.NODE_ENV === 'testing') {
// key 為應用的第三方庫的名稱,value為在項目中起的別名
  exten = { //不打包的文件
    jquery: 'jQuery',
    'element-ui': 'ElementUI',
    vue: "Vue",
    vuex: 'Vuex',
    axios: 'axios',
    moment: 'moment'
  }
}
module.exports = {
  entry: utils.entries(), //設置多個頁面的js入口
  externals: exten,
  ...
  }
  • 復制 webpack.prod.conf.js 並重命名為 webpack.test.conf.js,修改webpack.test.conf.js配置
    // 注釋 CommonsChunkPlugin 不生成manifest.js,vendor.js文件
    
    // new webpack.optimize.CommonsChunkPlugin({
    //   name: 'vendor',
    //   minChunks(module) {
    //     // any required modules inside node_modules are extracted to vendor
    //     return (
    //       module.resource &&
    //       /\.js$/.test(module.resource) &&
    //       module.resource.indexOf(
    //         path.join(__dirname, '../node_modules')
    //       ) === 0
    //     )
    //   }
    // }),
    
    // new webpack.optimize.CommonsChunkPlugin({
    //   name: 'manifest',
    //   minChunks: Infinity
    // }),
    
    // new webpack.optimize.CommonsChunkPlugin({
    //   name: 'app',
    //   async: 'vendor-async',
    //   children: true,
    //   minChunks: 3
    // }),
    
  • 復制 build.js 並重命名為 build.test.js,修改build.test.js配置
// 設置環境變量為testing
process.env.NODE_ENV = 'testing'
// 加載webpack.test.conf.js配置
const webpackConfig = require('./webpack.test.conf.js')
// 設置靜態輸出目錄為test
config.build.assetsSubDirectory = "test"

  • 修改 build/utils.js 修改靜態文件輸出目錄為test
exports.assetsPath = function (_path) {
  const assetsSubDirectory = process.env.NODE_ENV === 'production' ?
    config.build.assetsSubDirectory :
    process.env.NODE_ENV === 'testing' ? 
    "test" : config.dev.assetsSubDirectory

  return path.posix.join(assetsSubDirectory, _path)
}
  • 修改package.json 添加test環境編譯指令
  "scripts": {
    ....
    "build": "node build/build.js",
    "build:test": "node build/build.test.js"
  },
  • 編譯打包測試配置修改是否OK


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM