您好,登錄后才能下訂單哦!
小編這次要給大家分享的是webpack+vue.js怎么構(gòu)建前端工程化,文章內(nèi)容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。
node.js基本入門
node.js介紹
node.js可以讓javascript程序在后端運(yùn)行起來。我們之前所熟知的javascript都是運(yùn)行在前端瀏覽器,我們編寫好了javascript代碼后,由瀏覽器解釋執(zhí)行。而node.js,可以讓我們編寫javascript,然后在后端運(yùn)行起來?,F(xiàn)在的javascript和java、python一樣,可以操作I/O、操作數(shù)據(jù)庫、或者其他各類操作系統(tǒng)資源。
上面這張圖,和下面的這張圖很像。可以認(rèn)為,node.js是javascript的一種跨平臺(tái)運(yùn)行在主機(jī)的實(shí)現(xiàn)。
環(huán)境搭建
下載node.js (運(yùn)行環(huán)境)
https://nodejs.org/en/
下載Visual Studio Code(開發(fā)環(huán)境)
https://code.visualstudio.com/
npm介紹
寫過Java的同學(xué)應(yīng)該都知道,我們要編寫程序往往都需要導(dǎo)入很多其他額外的JAR包(官方的JavaSE包默認(rèn)提供了)。早期在Maven出現(xiàn)之前,我們都是需要手動(dòng)去下載各種框架的JAR包。自從有了Maven之后,我們不再需要手動(dòng)下載了,直接在一個(gè)POM.XML文件中引入需要的依賴即可。在node中,運(yùn)行一個(gè)node程序也會(huì)依賴于其他的一些模塊。當(dāng)然node也會(huì)自帶一些基本模塊。那當(dāng)我們需要使用這些模塊的時(shí)候,我們需要從網(wǎng)絡(luò)上下載。這個(gè)去網(wǎng)上下載非常麻煩。node官方提供了一個(gè)管理工具npm,這個(gè)工具可以根據(jù)需要自動(dòng)從服務(wù)器下載各種包。這就省去了,我們自己去網(wǎng)上下載包的過程。
npm淘寶鏡像
官方的npm在國內(nèi)速度是比較慢的,可以使用淘寶的鏡像
npm install -g cnpm --registry=https://registry.npm.taobao.org
安裝完成后,就可以使用cnpm從淘寶鏡像來下載、安裝node包
使用cnpm安裝包
cnpm install <包的名稱>
包的名稱可以去https://npm.taobao.org/上搜索
node.js模塊化程序結(jié)構(gòu)
每一個(gè)js文件就是一個(gè)模塊(json等其實(shí)也可以作為一個(gè)模塊),對應(yīng)的就是一個(gè)module對象。下面這一段程序,表示從外部引入一個(gè)模塊,然后執(zhí)行模塊中的函數(shù)。
var fs = require("fs"); // 引入fs模塊 var data = fs.readFileSync('input.txt'); // 調(diào)用fs模塊中的readFileSync方法 console.log(data.toString());
第一行的, required表示引入一個(gè)包,返回的就是module對象。這個(gè)fs包,是node自帶的包,引入一個(gè)包后就可以調(diào)用這個(gè)包下的方法。但是包中的方法不是都可以被調(diào)用的,只有類似:
exports.world = function() { console.log('Hello World'); }
這樣的代碼,才能被調(diào)用。更簡單來說,在包中定義的函數(shù)都是對外不可見的,要想被外部調(diào)用,需要使用exports來定義函數(shù)。
這個(gè)require函數(shù)有點(diǎn)類似于C語言中的#include。它首先會(huì)從文件cache緩存中查找傳入的模塊名,如果沒有找到再查找原生模塊,最后查找文件中加載。
node.js重要模塊(API)介紹
node.js全局對象
node.js原生模塊
實(shí)現(xiàn)一個(gè)用戶管理模塊
創(chuàng)建項(xiàng)目
建立一個(gè)空的文件夾用于保存該項(xiàng)目
進(jìn)入命令提示符,使用npm init初始化項(xiàng)目,結(jié)束后會(huì)自動(dòng)生成一個(gè)package.json文件,這個(gè)文件中包含了項(xiàng)目的所有依賴包,可以把這個(gè)package.json文件理解為項(xiàng)目文件
創(chuàng)建客戶Service模塊
/** * 客戶Service */ exports.CustomerService = function() { this.customers = []; // 添加客戶 this.add = function(cstm) { this.customers.push(cstm); } // 根據(jù)客戶名字移除 this.remove = function(name) { for(var i = 0; i < this.customers.length; ++i) { if(this.customers[i].name === name) { this.customers.splice(i, 1); break; } } } // 獲取所有客戶 this.findAll = function() { return this.customers; } }
創(chuàng)建入口模塊index.js
var customerService = require('./customerService'); var cm = new customerService.CustomerService(); cm.add({name: '小喬', age: 20, sex: '女'}); cm.add({name: '二喬', age: 21, sex: '女'}); cm.add({name: '大喬', age: 22, sex: '女'}); // 查詢所有客戶 var cstms = cm.findAll(); console.log("---"); console.log(cstms); // 刪除客戶 cm.remove("小喬"); console.log("---"); console.log(cm.findAll())
執(zhí)行node index.js
PS H:\code\nodejs\02> node .\index.js --- [ { name: '小喬', age: 20, sex: '女' }, { name: '二喬', age: 21, sex: '女' }, { name: '大喬', age: 22, sex: '女' } ] --- [ { name: '二喬', age: 21, sex: '女' }, { name: '大喬', age: 22, sex: '女' } ]
vue.js基本入門
介紹
Vue是一套前端框架。它實(shí)現(xiàn)了前端頁面視圖(HTML/CSS)和模型數(shù)據(jù)的分離,而且它提供了快速簡單構(gòu)建組件的方式。讓我們以一種全新的方式來開發(fā)前端。
基本編程模型(模板 + 模型)
使用Vue指令定義模板
<div id="app"> <span> {{name}} </span> </div>
使用Vue定義數(shù)據(jù)模型
var app2 = new Vue({ el: '#app', data: { // 定義模型數(shù)據(jù) name: 'Hello, Tom!' }, method: { // 定義綁定數(shù)據(jù)方法 sayHello: function() { alert('hello!'); } } })
常用指令介紹
組件化開發(fā)
在前端開發(fā)中引入組件化是一個(gè)大的進(jìn)步。其實(shí),如果我們用過一些UI框架就會(huì)知道,大多數(shù)的UI框架都定義了很多的組件,例如:button按鈕、datagrid表格組件、tree樹形組件、dialog對話框組件等等。但是,之前我們都是使用別人給我們開發(fā)好的框架。我們今天要學(xué)習(xí)如何使用Vue來開發(fā)一個(gè)自己的組件。將來,我們可以自己開發(fā)一套自己的組件庫,然后使用這些組件庫來構(gòu)建我們的前端應(yīng)用程序。
組件結(jié)構(gòu)
可以把組件理解為就是一個(gè)小的頁面視圖。使用Vue開發(fā)的組件也分為兩個(gè)部分:
視圖模板
屬性(模型數(shù)據(jù))
視圖模板依舊是使用HTML/CSS+Vue指令,但是模型數(shù)據(jù)現(xiàn)在跟之前不太一樣,模型數(shù)據(jù)應(yīng)該是使用組件的時(shí)候,動(dòng)態(tài)傳入進(jìn)來的。所以,模型數(shù)據(jù)需要先定義出來。
實(shí)現(xiàn)一個(gè)購物車程序
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>購物車</title> <link rel="stylesheet" href="./bootstrap/css/bootstrap.css" rel="external nofollow" > </head> <body> <div id="app" class="container"> <h2>購物車</h2> <hr> <btn-grp :buttons="buttons"></btn-grp> <btn-grp :buttons="buttons_test"></btn-grp> <btn-grp :buttons="buttons"></btn-grp> <btn-grp :buttons="buttons_test"></btn-grp> <br> <br> <table class="table table-bordered table-striped table-hover"> <tr> <th>ID</th> <th>商品名稱</th> <th>商品價(jià)格</th> <th>商品數(shù)量</th> <th>商品總價(jià)</th> </tr> <tr v-for="(prod, index) in products"> <td>{{index+1}}</td> <td>{{prod.name}}</td> <td>{{prod.price}}</td> <td> <button @click="changeCount(prod, -1)">-</button> <input type="text" v-model="prod.count"> <button @click="changeCount(prod, 1)">+</button> </td> <td>{{prod.price * prod.count}}</td> </tr> <tr> <td colspan="4" class="text-right">總價(jià):</td> <td class="text-primary">{{getTotalMoney()}}</td> </tr> </table> </div> <script src="./vue.js"></script> <script> // 自定義組件,這里實(shí)現(xiàn)了一個(gè)按鈕組組件 Vue.component('btn-grp', { props: ['buttons'], template: '<div class="btn-group" role="group">' + '<button type="button" @click="btn.handler" v-for="btn in buttons" :class="\'btn \' + (btn.class == null || btn.class == \'\' ? \'btn-default\':btn.class)">' + '{{btn.title}}' + '</button>' + '</div>' }); var app = new Vue({ el: '#app', data: { // 按鈕組件測試 buttons_test: [ {title: '測試1', class: 'btn-danger'},{title: '測試2'},{title: '測試3'},{title: '測試4'}, ], buttons: [{ title: '添加', class: 'btn-primary', handler: function() { alert('點(diǎn)擊添加按鈕'); } }, { title: '修改', class: 'btn-default', handler: function() { alert('點(diǎn)擊修改按鈕'); } }, { title: '刪除', class: 'btn-default', handler: function() { alert('點(diǎn)擊刪除按鈕'); } }, ], products: [ { name: '小米6S', price: 3999, count: 1, }, { name: '錘子2', price: 4999, count: 1, }, { name: '華為P20', price: 3599, count: 1, }, { name: 'OPPO R15', price: 2999, count: 1, }, { name: 'OPPO R11', price: 1999, count: 1, }, ], }, methods: { // 用戶點(diǎn)擊加減數(shù)量時(shí)調(diào)用 changeCount: function(prod, num) { if(num < 0) { if(prod.count > 0) { prod.count += num; } } else { prod.count += num; } }, // 獲取總金額 getTotalMoney: function() { var totalMoney = 0.0; for(var i = 0; i < this.products.length; ++i) { totalMoney += parseFloat(this.products[i].price * this.products[i].count); } return totalMoney; } } }); </script> </body> </html>
效果圖
使用webpack構(gòu)建前端工程化
webpack介紹
webpack是一個(gè)前端項(xiàng)目構(gòu)建工具。使用webpack可以把前端當(dāng)成一個(gè)工程來開發(fā)。而且能夠很好地把前端的各類資源統(tǒng)一管理、編譯、打包。
它是一個(gè)“編譯器”,可以通過各種插件將基于node.js、sass、less編寫代碼編譯成能夠運(yùn)行在前端瀏覽器的javascript、和css
它是一個(gè)打包工具,可以將所有前端的資源打包到一個(gè)bundle.js中
有了webpack,我們可以像開發(fā)后端應(yīng)用一樣開發(fā)前端。
總體結(jié)構(gòu)圖
webpack是基于node.js開發(fā)的一款應(yīng)用,其實(shí)webpack就是一個(gè)node.js的模塊。
安裝webpack
創(chuàng)建一個(gè)空的文件夾
使用npm init創(chuàng)建package.json
安裝cnpm淘寶鏡像
使用cnpm install vue-cli -g全局安裝vue-cli模塊
使用vue init webpack cart創(chuàng)建基于webpack購物車項(xiàng)目
使用cnpm install bootstrap --save安裝bootstrap模塊
具體步驟請參考:https://www.webpackjs.com/guides/installation/
使用webpack重構(gòu)購物車程序
使用vue-cli生成項(xiàng)目腳手架如下圖:
將原來編寫的btn-grp組件單獨(dú)編寫到BtnGrp.vue文件中
可以看到現(xiàn)在代碼清晰了很多,template標(biāo)簽部分編寫模板,script標(biāo)簽部分編寫組件的交互代碼,編寫方式和原先寫在HTML的代碼一致
現(xiàn)在整個(gè)前端應(yīng)用都是基于組件化的,代碼變得更加清晰了
<template> <div class="btn-group" role="group"> <button :key="btn.title" type="button" @click="btn.handler" v-for="btn in buttons" :class="'btn ' + (btn.class == null || btn.class == '' ? 'btn-outline-secondary':btn.class)"> {{btn.title}} </button> </div> </template> <script> export default { props: ['buttons'] } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
將原來寫在HTML中的代碼重構(gòu)到App.vue中
此處因?yàn)樾枰玫紹tnGrp組件,所以需要先import 組件,然后在components中引用該組件
<template> <div id="app" class="container"> <h2>WEBPACK + VUE 實(shí)現(xiàn)購物車</h2> <BtnGrp :buttons="buttons"></BtnGrp> <br/> <br/> <table class="table table-bordered table-striped table-hover"> <tr> <th>ID</th> <th>商品名稱</th> <th>商品價(jià)格</th> <th>商品數(shù)量</th> <th>商品總價(jià)</th> </tr> <tr :key="index+1" v-for="(prod, index) in products"> <td>{{index+1}}</td> <td>{{prod.name}}</td> <td>{{prod.price}}</td> <td> <button class="btn btn-outline-info btn-sm" @click="changeCount(prod, -1)">-</button> <input type="text" v-model="prod.count"> button class="btn btn-outline-info btn-sm" @click="changeCount(prod, 1)">+</button> </td> <td>{{prod.price * prod.count}}</td> </tr> <tr> <td colspan="4" class="text-right">總價(jià):</td> <td class="text-primary">{{getTotalMoney()}}</td> </tr> </table> </div> </template> <script> /* eslint-disable no-new */ import 'bootstrap/dist/css/bootstrap.min.css' import BtnGrp from './components/BtnGrp' export default { name: 'App', components: {BtnGrp}, data () { return { products: [ { name: '小米6S', price: 3999, count: 1, }, { name: '錘子2', price: 4999, count: 1, }, { name: '華為P20', price: 3599, count: 1, }, { name: 'OPPO R15', price: 2999, count: 1, }, { name: 'OPPO R11', price: 1999, count: 1, }, ], buttons: [{ title: '添加', class: 'btn-outline-primary', handler: function() { alert('點(diǎn)擊添加按鈕'); } }, { title: '修改', class: 'btn-outline-primary', handler: function() { alert('點(diǎn)擊修改按鈕'); } }, { title: '刪除', class: 'btn-outline-danger', handler: function() { alert('點(diǎn)擊刪除按鈕'); } }, ], changeCount: function(prod, num) { if(num < 0) { if(prod.count > 0) { prod.count += num; } } else { prod.count += num; } }, getTotalMoney: function() { var totalMoney = 0.0; for(var i = 0; i < this.products.length; ++i) { totalMoney += parseFloat(this.products[i].price * this.products[i].count); } ? return totalMoney; } } } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
因?yàn)閚pm安裝的bootstrap是bootstrap4,所以稍微對原先的樣式調(diào)整了下。最終的效果圖如下:
看完這篇關(guān)于webpack+vue.js怎么構(gòu)建前端工程化的文章,如果覺得文章內(nèi)容寫得不錯(cuò)的話,可以把它分享出去給更多人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。