前端工程化:
一.ES6
變量與模版字符串
let 和var的差別:
<script>
//1. let只有在當前代碼塊有效代碼塊. 代碼塊、函數(shù)、全局
{
let a = 1
var b = 2
}
console.log(a); // a is not defined 花括號外面無法訪問
console.log(b); // 可以正常輸出
//2. 不能重復聲明
let name = '天真'
let name = '無邪'
//3. 不存在變量提升(先聲明,在使用)
console.log(test) //可以 但是值為undefined
var test = 'test'
console.log(test1) //不可以 let命令改變了語法行為,它所聲明的變量一定要在聲明后使用,否則報錯。
let test1 = 'test1'
//4、不會成為window的屬性
var a = 100
console.log(window.a) //100
let b = 200
console.log(window.b) //undefined
</script>
-
const和var的差異
1、新增const和let類似,只是const定義的變量不能修改
2、并不是變量的值不得改動,而是變量指向的那個內(nèi)存地址所保存的數(shù)據(jù)不得改動。
模板字符串(template string)是增強版的字符串,用反引號(`)標識
1、字符串中可以出現(xiàn)換行符
2、可以使用 ${xxx} 形式輸出變量和拼接變量
解構(gòu)表達式:解構(gòu)賦值的語法使用花括號 {}
表示對象,方括號 []
表示數(shù)組
let [a, b, c] = [1, 2, 3]; //新增變量名任意合法即可,本質(zhì)是按照順序進行初始化變量的值
let {a, b} = {a: 1, b: 2};
//新增變量名必須和屬性名相同,本質(zhì)是初始化變量的值為對象中同名屬性的值
//等價于 let a = 對象.a let b = 對象.b
//使用 : 操作符指定新的變量名
let {a: x, b: y} = {a: 1, b: 2};
//函數(shù)參數(shù)解構(gòu)賦值
function add([x, y]) {
return x + y;
}
add([1, 2]); // 3
箭頭函數(shù)(類似Java中的Lambda表達式 )
//ES6 允許使用“箭頭”(=>)定義函數(shù)。
//1. 函數(shù)聲明
let fn1 = function(){}
let fn2 = ()=>{} //箭頭函數(shù),此處不需要書寫function關鍵字
let fn3 = x =>{} //單參數(shù)可以省略(),多參數(shù)無參數(shù)不可以!
let fn4 = x => console.log(x) //只有一行方法體可以省略{};
let fun5 = x => x + 1 //當函數(shù)體只有一句返回值時,可以省略花括號和 return 語句
//2. 使用特點 箭頭函數(shù)this關鍵字
// 在 JavaScript 中,this 關鍵字通常用來引用函數(shù)所在的對象,
// 或者在函數(shù)本身作為構(gòu)造函數(shù)時,來引用新對象的實例。
// 但是在箭頭函數(shù)中,this 的含義與常規(guī)函數(shù)定義中的含義不同,
// 并且是由箭頭函數(shù)定義時的上下文來決定的,而不是由函數(shù)調(diào)用時的上下文來決定的。
// 箭頭函數(shù)沒有自己的this,this指向的是外層上下文環(huán)境的this
let person ={
name:"張三",
showName:function (){
console.log(this) // 這里的this是person
},
viewName: () =>{
console.log(this) // 這里的this是window
}
}
rest參數(shù),在形參上使用 和JAVA中的可變參數(shù)幾乎一樣 :let fun?= function (...args){...}}
spread參數(shù),在實參上使用rest:fun1(...arr)
應用:
//應用場景1 合并數(shù)組
let arr=[1,2,3]
let arr2=[4,5,6]
let arr3=[...arr,...arr2]
//應用場景2 合并對象屬性
let p1={name:"張三"}
let p2={age:10}
let p3={gender:"boy"}
let person ={...p1,...p2,...p3}
對象的創(chuàng)建與拷貝(支持了class extends constructor等關鍵字?)
淺拷貝:let person2 = person;--指向統(tǒng)一內(nèi)存
深拷貝:let person2 = JSON.parse(JSON.stringify(person));--通過JSON和字符串的轉(zhuǎn)換形成一個新的對象
模塊化處理:分別導出,統(tǒng)一導出,默認導出
分別導出-模塊想對外導出,添加export關鍵字即可(導入-import * as m1 from './module.js';*代表module.js中的所有成員,m1代表所有成員所屬的對象)
?導入JS文件 添加type='module' 屬性,否則不支持ES6的模塊化
<script src="./app.js" type="module" />?
統(tǒng)一導出
// 統(tǒng)一對外導出(暴露)
export {
PI,
sum,
Person
}
導入:
/*
{}中導入要使用的來自于module.js中的成員
{}中導入的名稱要和module.js中導出的一致,也可以在此處起別名
{}中如果定義了別名,那么在當前模塊中就只能使用別名
{}中導入成員的順序可以不是暴露的順序
一個模塊中可以同時有多個import
多個import可以導入多個不同的模塊,也可以是同一個模塊
*/
import {PI ,Person ,sum,PI as pi,Person as People,sum as add} from './module.js'
默認導出:export default sum
導入:import {default as add} from './module.js'
npm常用命令:
1.項目初始化
-
npm init
-
生成一個package.json 文件
-
-
npm init -y
-
所有信息使用當前文件夾的默認值!
-
2.安裝依賴 npm | Home
-
npm install 包名 或者 npm install 包名@版本號
-
安裝包或者指定版本的依賴包(安裝到當前項目中)
-
-
npm install -g 包名
-
安裝全局依賴包
-
-
npm install
-
安裝package.json中的所有記錄的依賴
-
3.升級依賴
-
npm update 包名
-
將依賴升級到最新版
-
4.卸載依賴
-
npm uninstall 包名
5.查看依賴
-
npm ls
-
查看項目依賴
-
-
npm list -g
-
查看全局依賴
-
6.運行命令
-
npm run 命令是在執(zhí)行 npm 腳本時使用的命令。npm 腳本是一組在 package.json 文件中定義的可執(zhí)行命令。npm 腳本可用于啟動應用程序,運行測試,生成文檔等,還可以自定義命令以及配置需要運行的腳本。
-
在 package.json 文件中,scripts 字段是一個對象,其中包含一組鍵值對,鍵是要運行的腳本的名稱,值是要執(zhí)行的命令。
? ?"scripts": { ? ? ? ?"start": "node index.js", ? ? ? ?"test": "jest", ? ? ? ?"build": "webpack" ? },
-
scripts 對象包含 start、test 和 build 三個腳本。當您運行 npm run start 時,將運行 node index.js,并啟動應用程序。同樣,運行 npm run test 時,將運行 Jest 測試套件,而 npm run build 將運行 webpack 命令以生成最終的構(gòu)v建輸出。
二.VUE3:
-
聲明式渲染:Vue 基于標準 HTML 拓展了一套模板語法,使得我們可以聲明式地描述最終輸出的 HTML 和 JavaScript 狀態(tài)之間的關系。
-
響應性:Vue 會自動跟蹤 JavaScript 狀態(tài)并在其發(fā)生變化時響應式地更新 DOM
Vite創(chuàng)建Vue3工程化項目(vscode)
- 創(chuàng)建工程:npm create vite@latest; 選擇vue+JavaScript選項
- 安裝依賴:npm i(安裝package.json 中的依賴)
- 啟動項目-研發(fā)模式:npm run dev
- 停止項目:ctrl+c
Vite+Vue3項目的目錄結(jié)構(gòu):
Vite 項目的入口為 src/main.js 文件,這是 Vue.js 應用程序的啟動文件,也是整個前端應用程序的入口文件。在該文件中,通常會引入 Vue.js 及其相關插件和組件,同時會創(chuàng)建 Vue 實例,掛載到 HTML 頁面上指定的 DOM 元素中。
SFC:.vue文件對js/css/html統(tǒng)一封裝, 該文件由三個部分組成 <script> <template> <style>
-
template標簽 代表組件的html部分代碼 代替?zhèn)鹘y(tǒng)的.html文件
-
script標簽 代表組件的js代碼 代替?zhèn)鹘y(tǒng)的.js文件
-
style標簽 代表組件的css樣式代碼 代替?zhèn)鹘y(tǒng)的.css文件(存儲的是css代碼! <style scoped> 是 Vue.js 單文件組件中用于設置組件樣式的一種方式,它的含義是將樣式局限在當前組件中,不對全局樣式造成影響。)
工程組織:
-
index.html是項目的入口,其中
<div id ='app'></div>
是用于掛載所有組建的元素 -
index.html中的script標簽引入了一個main.js文件,具體的掛載過程在main.js中執(zhí)行
-
main.js是vue工程中非常重要的文件,他決定這項目使用哪些依賴,導入的第一個組件
-
App.vue是vue中的核心組件,所有的其他組件都要通過該組件進行導入,該組件通過路由可以控制頁面的切換
Vite+Vue3響應式和setup函數(shù):
響應數(shù)據(jù):
<script type="module">
//存儲vue頁面邏輯js代碼
import {ref} from 'vue'
export default{
setup(){
//非響應式數(shù)據(jù): 修改后VUE不會更新DOM
//響應式數(shù)據(jù): 修改后VUE會更新DOM
//VUE2中數(shù)據(jù)默認是響應式的
//VUE3中數(shù)據(jù)要經(jīng)過ref或者reactive處理后才是響應式的
//ref是VUE3框架提供的一個函數(shù),需要導入
//let counter = 1
//ref處理的響應式數(shù)據(jù)在js編碼修改的時候需要通過.value操作
//ref響應式數(shù)據(jù)在綁定到html上時不需要.value
let counter = ref(1)
function increase(){
// 通過.value修改響應式數(shù)據(jù)
counter.value++
}
function decrease(){
counter.value--
}
return {
counter,
increase,
decrease
}
}
}
</script>
<template>
<div>
<button @click="decrease()">-</button>
{{ counter }}
<button @click="increase()">+</button>
</div>
</template>
通過setup函數(shù)來省略語句:
<script type="module" setup>
/* <script type="module" setup> 通過setup關鍵字
可以省略 export default {setup(){ return{}}}這些冗余的語法結(jié)構(gòu) */
import {ref} from 'vue'
// 定義響應式數(shù)據(jù)
let counter = ref(1)
// 定義函數(shù)
function increase(){
counter.value++
}
function decrease(){
counter.value--
}
</script>
樣式導入方式:?
-
全局引入main.js
import './style/reset.css'
-
vue文件script代碼引入
import './style/reset.css'
-
Vue文件style代碼引入
@import './style/reset.css'
Vue3視圖渲染技術(shù):
插值表達式:雙大括號{{}}和文本表達式:v-xxxx
-
插值表達式是將數(shù)據(jù)渲染到元素的指定位置的手段之一
-
插值表達式不絕對依賴標簽,其位置相對自由
-
插值表達式中支持javascript的運算表達式
-
插值表達式中也支持函數(shù)的調(diào)用
-
v-*** 這種寫法的方式使用的是vue的命令
-
v-***的命令必須依賴元素,并且要寫在元素的開始標簽中
-
v-***指令支持ES6中的字符串模板:``
-
插值表達式中支持javascript的運算表達式
-
插值表達式中也支持函數(shù)的調(diào)用
-
v-text可以將數(shù)據(jù)渲染成雙標簽中間的文本,但是不識別html元素結(jié)構(gòu)的文本
-
v-html可以將數(shù)據(jù)渲染成雙標簽中間的文本,識別html元素結(jié)構(gòu)的文本
屬性渲染:渲染元素的屬性使用v-bind;語法為 v-bind:屬性名='數(shù)據(jù)名'
事件綁定:v-on
來監(jiān)聽 DOM 事件,并在事件觸發(fā)時執(zhí)行對應的 Vue的JavaScript代碼
-
用法:
v-on:click="handler"
或簡寫為@click="handler"
-
vue中的事件名=原生事件名去掉
on
前綴 如:onClick --> click
-
handler的值可以是方法事件處理器,也可以是內(nèi)聯(lián)事件處理器(直接對數(shù)據(jù)進行修改)
-
<!-- 方法事件處理器 --> <button v-on:click="addCount()">addCount</button> <br> <!-- 內(nèi)聯(lián)事件處理器 --> <button @click="count++">incrCount</button> <br>
-
綁定事件時,可以通過一些綁定的修飾符,常見的事件修飾符如下
-
.once:只觸發(fā)一次事件。[重點]
-
.prevent:阻止默認事件。[重點]
-
響應式數(shù)據(jù):
ref
可以將一個基本類型的數(shù)據(jù)(如字符串,數(shù)字等)轉(zhuǎn)換為一個響應式對象。 ref
只能包裹單一元素; reactive() 函數(shù)創(chuàng)建一個響應式對象或數(shù)組(toRef基于reactive響應式對象上的一個屬性,創(chuàng)建一個對應的 ref響應式數(shù)據(jù)。這樣創(chuàng)建的 ref 與其源屬性保持同步:改變源屬性的值將更新 ref 的值,反之亦然。toRefs將一個響應式對象多個屬性轉(zhuǎn)換為一個多個ref數(shù)據(jù),這個普通對象的每個屬性都是指向源對象相應屬性的 ref。 )
條件渲染與列表渲染
-
v-if='表達式'
只會在指令的表達式返回真值時才被渲染 -
也可以使用
v-else
為v-if
添加一個“else 區(qū)塊”。 -
一個
v-else
元素必須跟在一個v-if
元素后面,否則它將不會被識別。 -
v-show
會在 DOM 渲染中保留該元素;v-show
僅切換了該元素上名為display
的 CSS 屬性。 -
使用
v-for
指令基于一個數(shù)組來渲染一個列表 -
使用
item in items
形式的特殊語法,其中items
是源數(shù)據(jù)的數(shù)組,而item
是迭代項的別名 -
可選的第二個參數(shù)表示當前項的位置索引??v-for="(item, index) in items"?
計算屬性computed
// 一個計算屬性 ref
const publishedBooksMessage = computed(() => {
return author.books.length > 0 ? 'Yes' : 'No'
})
數(shù)據(jù)監(jiān)聽器watch(watcheffect)
-
當數(shù)據(jù)發(fā)生變化時需要執(zhí)行相應的操作
-
監(jiān)聽數(shù)據(jù)變化,當滿足一定條件時觸發(fā)相應操作
-
在異步操作前或操作后需要執(zhí)行相應的操作
<script type="module" setup>
//引入模塊
import { ref,reactive,watch} from 'vue'
let firstname=ref('')
let lastname=reactive({name:''})
let fullname=ref('')
//監(jiān)聽一個ref響應式數(shù)據(jù)
watch(firstname,(newValue,oldValue)=>{
console.log(`${oldValue}變?yōu)?{newValue}`)
fullname.value=firstname.value+lastname.name
})
//監(jiān)聽reactive響應式數(shù)據(jù)的指定屬性
watch(()=>lastname.name,(newValue,oldValue)=>{
console.log(`${oldValue}變?yōu)?{newValue}`)
fullname.value=firstname.value+lastname.name
})
//監(jiān)聽reactive響應式數(shù)據(jù)的所有屬性(深度監(jiān)視,一般不推薦)
//deep:true 深度監(jiān)視
//immediate:true 深度監(jiān)視在進入頁面時立即執(zhí)行一次
watch(()=>lastname,(newValue,oldValue)=>{
// 此時的newValue和oldValue一樣,都是lastname
console.log(newValue)
console.log(oldValue)
fullname.value=firstname.value+lastname.name
},{deep:true,immediate:false})
//監(jiān)聽所有響應式數(shù)據(jù)
watchEffect(()=>{
//直接在內(nèi)部使用監(jiān)聽屬性即可!不用外部聲明
//也不需要,即時回調(diào)設置!默認初始化就加載!
console.log(firstname.value)
console.log(lastname.name)
fullname.value=`${firstname.value}${lastname.name}`
})
</script>
vue生命周期-Vue 組件實例在創(chuàng)建時都需要經(jīng)歷一系列的初始化步驟,比如設置好數(shù)據(jù)偵聽,編譯模板,掛載實例到 DOM,以及在數(shù)據(jù)改變時更新 DOM。在此過程中,它也會運行生命周期鉤子的函數(shù)
-
onMounted() 注冊一個回調(diào)函數(shù),在組件掛載完成后執(zhí)行。
-
onUpdated() 注冊一個回調(diào)函數(shù),在組件因為響應式狀態(tài)變更而更新其 DOM 樹之后調(diào)用。
-
onUnmounted() 注冊一個回調(diào)函數(shù),在組件實例被卸載之后調(diào)用。
-
onBeforeMount() 注冊一個鉤子,在組件被掛載之前被調(diào)用。
-
onBeforeUpdate() 注冊一個鉤子,在組件即將因為響應式狀態(tài)變更而更新其 DOM 樹之前調(diào)用。
-
onBeforeUnmount() 注冊一個鉤子,在組件實例被卸載之前調(diào)用。
組件之間傳遞數(shù)據(jù):
父傳子:
//父
<!-- 使用子組件,并且傳遞數(shù)據(jù)!通過設置屬性傳遞數(shù)據(jù) -->
<Son :message="message" :title="title"></Son>
//子
import {defineProps} from 'vue'
//聲明父組件傳遞屬性值,屬性值要一致
defineProps({
message: String ,
title: Number
})
子傳父:
//子
import {defineEmits} from 'vue'
//1.定義要發(fā)送給父組件的方法,可以1或者多個
let emites = defineEmits(['add','sub']);
let data = ref(1);
function sendMsgToParent(){
//2.發(fā)父組件對應的方法,調(diào)用defineEmites對應的屬性
emites('add','add data!'+data.value)
emites('sub','sub data!'+data. Value)
}
<button @click="sendMsgToParent">發(fā)送消息給父組件</button>
//父
//自定義接收,子組件傳遞數(shù)據(jù)方法! 參數(shù)為數(shù)據(jù)!
const psub = (data) => {
pdata.value = data;
}
<!-- 聲明@事件名應該等于子模塊對應事件名!調(diào)用方法可以是當前自定義!-->
<Son @add="padd" @sub="psub"></Son>
兄弟間傳參:子傳父-父傳子
Vue3路由機制router-資源
promise-異步編程技術(shù)
(1)Promise對象代表一個異步操作,有三種狀態(tài):`Pending`(進行中)、`Resolved`(已完成,又稱 Fulfilled)和`Rejected`(已失?。V挥挟惒讲僮鞯慕Y(jié)果,可以決定當前是哪一種狀態(tài),任何其他操作都無法改變這個狀態(tài)。
(2)一旦狀態(tài)改變,就不會再變,任何時候都可以得到這個結(jié)果。Promise對象的狀態(tài)改變,只有兩種可能:從`Pending`變?yōu)閌Resolved`和從`Pending`變?yōu)閌Rejected`。
1.實例化promise對象,并且執(zhí)行(類似Java創(chuàng)建線程對象,并且start)
參數(shù): resolve,reject隨意命名,但是一般這么叫!
參數(shù): resolve,reject分別處理成功和失敗的兩個函數(shù)! 成功resolve(結(jié)果) 失敗reject(結(jié)果)
參數(shù): 在function中調(diào)用這里兩個方法,那么promise會處于兩個不同的狀態(tài)
狀態(tài): promise有三個狀態(tài)
pending 正在運行
resolved 內(nèi)部調(diào)用了resolve方法
rejected 內(nèi)部調(diào)用了reject方法
參數(shù): 在第二步回調(diào)函數(shù)中就可以獲取對應的結(jié)果
*/
let promise =new Promise(function(resolve,reject){
//resolve("promise success")
//reject("promise fail")
// throw new Error("error message")
})
//2.獲取回調(diào)函數(shù)結(jié)果 then在這里會等待promise中的運行結(jié)果,但是不會阻塞代碼繼續(xù)運行
promise.then(
function(value){console.log(`promise中執(zhí)行了resolve:${value}`)},
).catch(
function(error){console.log(error)}
)
async 標識異步函數(shù)
-
async標識函數(shù)后,async函數(shù)的返回值會變成一個promise對象
-
如果函數(shù)內(nèi)部返回的數(shù)據(jù)是一個非promise對象,async函數(shù)的結(jié)果會返回一個成功狀態(tài) promise對象
-
如果函數(shù)內(nèi)部返回的是一個promise對象,則async函數(shù)返回的狀態(tài)與結(jié)果由該對象決定
-
如果函數(shù)內(nèi)部拋出的是一個異常,則async函數(shù)返回的是一個失敗的promise對象
async function fun1(){
...
}
let promise =fun1()
promise.then(
function(value){
console.log("success:"+value)
}
).catch(
function(value){
console.log("fail:"+value)
}
)
await-
-
await右側(cè)的表達式一般為一個promise對象,但是也可以是一個其他值
-
如果表達式是promise對象,await返回的是promise成功的值
-
await會等右邊的promise對象執(zhí)行結(jié)束,然后再獲取結(jié)果,后續(xù)代碼也會等待await的執(zhí)行
-
如果表達式是其他值,則直接返回該值
-
await必須在async函數(shù)中
-
如果await右邊的promise失敗了,就會拋出異常,需要通過 try ... catch捕獲處理文章來源:http://www.zghlxwxcb.cn/news/detail-828551.html
axios-資源
三.后端過濾器中設置跨域處理
@WebFilter("/*")
public class CrosFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
System.out.println(request.getMethod());
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT,OPTIONS, DELETE, HEAD");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "access-control-allow-origin, authority, content-type, version-info, X-Requested-With");
// 如果是跨域預檢請求,則直接在此響應200業(yè)務碼
if(request.getMethod().equalsIgnoreCase("OPTIONS")){
WebUtil.writeJson(response, Result.ok(null));
}else{
// 非預檢請求,放行即可
filterChain.doFilter(servletRequest, servletResponse);
}
}
}
通過pinia狀態(tài)管理定義共享數(shù)據(jù):文章來源地址http://www.zghlxwxcb.cn/news/detail-828551.html
import {defineStore } from 'pinia'
//定義數(shù)據(jù)并且對外暴露
// store就是定義共享狀態(tài)的包裝對象
// 內(nèi)部包含四個屬性: id 唯一標識 state 完整類型推理,推薦使用箭頭函數(shù) 存放的數(shù)據(jù) getters 類似屬性計算,存儲放對數(shù)據(jù)
// 操作的方法 actions 存儲數(shù)據(jù)的復雜業(yè)務邏輯方法
// 理解: store類似Java中的實體類, id就是類名, state 就是裝數(shù)據(jù)值的屬性 getters就是get方法,actions就是對數(shù)據(jù)操作的其他方法
export const definedPerson = defineStore(
{
id: 'personPinia', //必須唯一
state:()=>{ // state中用于定義數(shù)據(jù)
return {
username:'張三',
age:0,
hobbies:['唱歌','跳舞']
}
},
getters:{// 用于定義一些通過數(shù)據(jù)計算而得到結(jié)果的一些方法 一般在此處不做對數(shù)據(jù)的修改操作
// getters中的方法可以當做屬性值方式使用
getHobbiesCount(){
return this.hobbies.length
},
getAge(){
return this.age
}
},
actions:{ // 用于定義一些對數(shù)據(jù)修改的方法
doubleAge(){
this.age=this.age*2
}
}
}
)
----------------------------------------------------------------------
import { createApp } from 'vue'
import App from './App.vue'
import router from './routers/router.js'
// 導pinia
import { createPinia } from 'pinia'
// 創(chuàng)建pinia對象
let pinia= createPinia()
let app =createApp(App)
app.use(router)
// app中使用pinia功能
app.use(pinia)
app.mount('#app')
------------------------------------------------------------------------
import { ref} from 'vue';
import { definedPerson} from '../store/store';
// 讀取存儲的數(shù)據(jù)
let person= definedPerson()
四.element-plus:一個 Vue 3 UI 框架 | Element Plus ?
到了這里,關于Javaweb基礎-前端工程化學習筆記的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!