Java EE框架(SSM + Spring Boot + Vue.js 3)整合開發(fā) 課件 第15章 Vue3 進階_第1頁
Java EE框架(SSM + Spring Boot + Vue.js 3)整合開發(fā) 課件 第15章 Vue3 進階_第2頁
Java EE框架(SSM + Spring Boot + Vue.js 3)整合開發(fā) 課件 第15章 Vue3 進階_第3頁
Java EE框架(SSM + Spring Boot + Vue.js 3)整合開發(fā) 課件 第15章 Vue3 進階_第4頁
Java EE框架(SSM + Spring Boot + Vue.js 3)整合開發(fā) 課件 第15章 Vue3 進階_第5頁
已閱讀5頁,還剩99頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

J

a

v

a

E

E框架整合開發(fā)第十五章Vue3進階本章目標了解render函數(shù)的原理了解靜態(tài)模塊打包工具webpack的用法了解組合API的用法掌握路由vue-router的基本用法掌握Vue.js應用程序開發(fā)的狀態(tài)管理模式本章內(nèi)容render函數(shù)組合API使用webpack路由vue-router狀態(tài)管理與Vuex15.1

render函數(shù)15.1.1什么是render函數(shù)15.1.2

h()函數(shù)15.1.1什么是render函數(shù)render函數(shù)與模板template一樣,都是創(chuàng)建HTML。在多數(shù)情況下,Vue推薦使用模板template來創(chuàng)建HTML。然而在一些應用場景中,需要使用Javascript創(chuàng)建HTML。這時可以用渲染函數(shù)render,它比模板更方便?!纠齝h15-1】根據(jù)不同等級的錨點,顯示不同的標題。代碼沒有任何問題,但是缺點非常明顯:代碼冗長、重復率高。?請思考為什么學習render函數(shù)?【例15-2】使用render函數(shù)改寫【例15-1】ponent("anchored-heading",

{render()

{return

Vue.h("h"+this.level,//tag參數(shù)[//children參數(shù)

Vue.h("a",//tag參數(shù){//props參數(shù)href:

"#"

+

this.title},this.$slots.default()//children參數(shù))])},props:

{level:

{……},title:

{……}}})app.mount("#app")render函數(shù)通過Vue的h函數(shù)來創(chuàng)建虛擬DOM,代碼精簡很多。15.1

render函數(shù)15.1.1什么是render函數(shù)15.1.2

h()函數(shù)15.1.2

h()函數(shù)h()函數(shù)是一個用于創(chuàng)建虛擬節(jié)點(VNode)的程序。也許可以更準確地將其命名為createVNode(),以便簡潔使用,被稱為h()。tag參數(shù)代表一個HTML標簽(String)、一個組件(Object)、一個函數(shù)(Function)或者null。使用null將渲染一個注釋。這是一個必選參數(shù)。例如,【例15-2】中的"a’。props參數(shù)一個與attribute、prop和事件相對應的對象(Object),用于向創(chuàng)建的節(jié)點對象設置屬性值,在模板中使用。這是一個可選參數(shù)。例如,【例15-2】中的{href:"#"+this.title}。children參數(shù)子Vnodes,使用h()函數(shù)構(gòu)建,或使用字符串獲取“文本Vnode”(String|Array)或者有slot的對象(Object)。這是一個可選參數(shù)。例如,【例15-2】中的代碼:[//childrenVue.h("a",//

tag{//

propshref:

"#"

+

this.title},this.$slots.default()//children)]本章內(nèi)容render函數(shù)組合API使用webpack路由vue-router狀態(tài)管理與Vuex15.2組合API15.2.1

setup15.2.2響應性15.2.3模板引用?請思考為什么學習組合API?15.2.1

setupVue組件提供setup選項,供開發(fā)者使用組合API。setup選項在創(chuàng)建組件前執(zhí)行,一旦props被解析,便充當組成API的入口點。由于在執(zhí)行setup時尚未創(chuàng)建組件實例,因此在setup選項中沒有this。這意味著,除了props之外,無法訪問組件中聲明的任何屬性,包括本地狀態(tài)、計算屬性或方法。setup選項是一個接受props和context的函數(shù)。此外,從setup返回的所有內(nèi)容都將暴露給組件的其余部分(計算屬性、方法、生命周期鉤子、模板等等)。setup函數(shù)的參數(shù)propssetup函數(shù)中的props是響應式的,當傳入新的屬性時,它將被

更新。但是,因為props是響應式的,不能響應式引用props的

屬性,因為它會消除屬性的響應性。如果需要響應式引用props的屬性,可通過使用toRefs來創(chuàng)建對props的屬性的響應式引用。setup(props)

{//使用toRefs創(chuàng)建對props的屬性的響應式引用const{user}=toRefs(props)console.log(user.uname)}setup函數(shù)的參數(shù)contextcontext上下文是一個普通的Javascript對象,它暴露組件的3個屬性:attrs、slots、emit。setup(props,

context)

{//Attribute(非響應式對象)console.log(context.attrs)//插槽(非響應式對象)console.log(context.slots)//觸發(fā)事件(方法)console.log(context.emit)}context是一個普通的Javascript對象,也就是說,它不是響應式的,這意味著可以安全地對context使用ES解構(gòu)。setup(props,

{

attrs,

slots,

emit

})

{...}attrs和slots是有狀態(tài)的對象,它們隨組件本身的更新而更新。這

意味著應該避免對它們進行解構(gòu),并始終以attrs.x或slots.x的方式引用屬性。setup函數(shù)的返回值——對象<template

id="stesting"><!--模板中使用readersNumber對象會被自動開箱,所以不需要.value--><div>{{

readersNumber

}}

{{

book.title

}}</div></template><div

id="app"><setup-testing></setup-testing></div><script

src="js/vue.global.js"></script>如果setup返回一個對象,則可以在組件的模板中訪問該對象的屬性?!纠?5-3】在該實例中,setup函數(shù)返回一個對象。<script>const

app

=

Vue.createApp({})ponent("setup-testing",

{setup()

{const

readersNumber

=

Vue.ref(1000)const

book=Vue.reactive({title:"好書"})

return{readersNumber,book}},template:

"#stesting"})app.mount("#app")</script>setup函數(shù)的返回值——渲染函數(shù)<div

id="app"><setup-testing></setup-testing></div><script

src="js/vue.global.js"></script>setup還可以返回一個渲染函數(shù),該函數(shù)可以直接使用在同一作用域中聲明的響應式狀態(tài)。<script>const

app

=

Vue.createApp({})ponent("setup-testing",

{setup()

{const

readersNumber

=

Vue.ref(1000)const

book=Vue.reactive({title:"好書"})//返回渲染函數(shù)return

()

=>

Vue.h("div",

[readersNumber.value,

book.title])}})app.mount("#app")</script>返回代理對象booksetup內(nèi)部調(diào)用生命周期鉤子函數(shù)在setup內(nèi)部,可通過在生命周期鉤子函數(shù)前面加上“on”來訪問組件的生命周期鉤子函數(shù)。因為setup是圍繞beforeCreate和created生命周期鉤子函數(shù)運行的,所以不需要顯式地定義它們。換句話說,在這些鉤子函數(shù)中編寫的任何代碼都應該直接在

setup函數(shù)中編寫。這些on函數(shù)接受一個回調(diào)函數(shù),當鉤子函數(shù)

被組件調(diào)用時將會被執(zhí)行。setup()

{//

mountedonMounted(()

=>

{console.log("Component

is

mounted!‘)})}15.2組合API15.2.1

setup15.2.2響應性15.2.3模板引用15.2.2響應性響應性是一種允許我們以聲明式的方式去適應變化的一種編程范例。例如,我們在某個excel電子表格中,將數(shù)字x放在第一個單元格中,數(shù)字y放在第二個單元格中,并要求自動計算x+y的值放在第三個單元格中。同時,如果更新數(shù)字x或y,第三個單元格的值也會自動更新。Vue如何追蹤變化呢?在生成Vue實例時,

使用帶有getter和setter的處理程序遍歷傳入的data,將其所有

property轉(zhuǎn)換為Proxy對象。Proxy對象對于用戶來說是不可見

的,但在內(nèi)部,它使Vue能夠在property的值被訪問或修改的情況下進行依賴跟蹤和變更通知。1.聲明響應式狀態(tài)要為Javascript對象創(chuàng)建響應式狀態(tài),可以使用reactive()方法。reactive()方法接收一個普通對象然后返回該對象的響應式代理。const

book=Vue.reactive({title:"好書"})reactive()方法響應式轉(zhuǎn)換是“深層的”即影響對象內(nèi)部所有嵌套的屬性?;贓S的Proxy實現(xiàn),返回的代理對象不等于原始對象。建議使用代理對象,避免依賴原始對象。例如,在【例15-3】中,使用代理對象book。2.使用ref創(chuàng)建獨立的響應式值對象ref接受一個參數(shù)值并返回一個響應式且可改變的ref對象。ref對象擁有一個指向內(nèi)部值的單一屬性.value。const

readersNumber

=

Vue.ref(1000)console.log(readersNumber.value)

//1000readersNumber.value++console.log(readersNumber.value)

//

1001當ref作為渲染上下文的屬性返回(即在setup()返回的對象中)并在模板中使用時,它會自動開箱,無需在模板內(nèi)額外書寫.value。例如,在【例15-3】中,這樣使用{{readersNumber}}。當嵌套在響應式對象中時,ref才會自動開箱。從Array或者Map等原生集合類中訪問ref時,不會自動開箱。const

map

=

reactive(new

Map([["foo",

ref(0)]]))//這里需要.valueconsole.log(map.get("foo").value)3.響應性計算使用響應式計算computed方法有兩種方式:傳入一個getter函數(shù),返回一個默認不可手動修改的ref對象;傳入一個擁有get和set函數(shù)的對象,創(chuàng)建一個可手動修改的計算狀態(tài)。const

count

=

ref(1)const

plusOne=computed(()=>count.value+1)console.log(plusOne.value)//2plusOne.value++//錯誤!返回一個可手動修改的ref對象的示例代碼如下:onst

count

=

ref(1)const

plusOne

=

computed({get:

()

=>

count.value

+

1,set:

(val)

=>

{count.value

=

val

-

1},})plusOne.value

=

1console.log(count.value)

//

04.響應性監(jiān)聽watchEffect可使用響應性監(jiān)聽watchEffect方法,對響應性進行監(jiān)聽。該方法立即執(zhí)行傳入的一個函數(shù),同時響應式追蹤其依賴,并在其依賴變更時重新運行該函數(shù)。【例15-5】響應性監(jiān)聽watchEffect方法的使用。<script

src="js/vue.global.js"></script><script>const

count

=

Vue.ref(0)Vue.watchEffect(()

=>

console.log(count.value))//->打印出0setTimeout(()=>{count.value++//->打印出1},

100)</script>(1)停止偵聽當watchEffect在組件的setup()函數(shù)或生命周期鉤子被調(diào)用時,

偵聽器會被鏈接到該組件的生命周期,并在組件卸載時自動停止。在一些情況下,也可以顯式調(diào)用返回值以停止偵聽。const

stop

=

watchEffect(()

=>

{/*

...

*/})//之后stop()(2)清除副作用有時副作用函數(shù)會執(zhí)行一些異步的副作用,這些響應需要在其失效時清除(即完成前狀態(tài)已改變)。所以偵聽副作用傳入的函數(shù)可以接收一個oninvalidate函數(shù)作為入?yún)?,用來注冊清理失效時的回調(diào)。當副作用即將重新執(zhí)行或偵聽器被停止時,觸發(fā)失效回調(diào)函數(shù)。watchEffect((oninvalidate)

=>

{const

token

=

performAsyncOperation(id.value)oninvalidate(()

=>

{//id改變時或停止偵聽時//取消之前的異步操作token.cancel()})})(3)偵聽器調(diào)試onTrack和onTrigger選項可用于調(diào)試一個偵聽器的行為。當一個響應性對象屬性或一個ref作為依賴被追蹤時,將調(diào)用

onTrack;依賴項變更導致副作用被觸發(fā)時,將調(diào)用onTrigger。這兩個回調(diào)都將接收到一個包含有關所依賴項信息的調(diào)試器事件。

onTrack和onTrigger僅在開發(fā)模式下生效。watchEffect(()

=>

{/*副作用的內(nèi)容*/},{onTrigger(e)

{debugger語句來檢查依賴關系},})5.響應性監(jiān)聽watchwatch

需要偵聽特定的數(shù)據(jù)源,并在回調(diào)函數(shù)中執(zhí)行副作用。默認情況是懶執(zhí)行的,也就是說僅在偵聽的源變更時才執(zhí)行回調(diào)。與watchEffect比較,watch允許:懶執(zhí)行副作用;更明確哪些狀態(tài)的改變會觸發(fā)偵聽器重新運行副作用;訪問偵聽狀態(tài)變化前后的值。(1)偵聽單個數(shù)據(jù)源偵聽器的數(shù)據(jù)源可以是一個擁有返回值的getter函數(shù),也可以是

ref。//偵聽一個getterconst

state

=

reactive({

count:

0

})watch(()

=>

state.count,(count,

prevCount)

=>

{/*

...

*/})//直接偵聽一個refconst

count=ref(0)watch(count,

(count,

prevCount)

=>

{/*

...

*/})偵聽多個數(shù)據(jù)源watcher也可以使用數(shù)組來同時偵聽多個源。示例代碼如下:watch([fooRef,barRef],([foo,bar],[prevFoo,prevBar])=>{/*

...

*/})與watchEffect共享的行為watch和watchEffect在停止偵聽、清除副作用、副作用刷新時機和偵聽器調(diào)試等方面行為一致。15.2組合API15.2.1

setup15.2.2響應性15.2.3模板引用15.2.3模板引用在使用組合API時,響應式引用和模板引用的概念是統(tǒng)一的。為了獲得對模板內(nèi)元素或組件實例的引用,可以聲明一個ref并從

setup()返回。【例15-6】在模板中使用ref引用響應式對象。<template

id="st"><div

ref="root">這是根元素</div></template><div

id="app"><setup-testing></setup-testing></div><script

src="js/vue.global.js"></script><script>const

app

=

Vue.createApp({})ponent("setup-testing",

{setup()

{const

root

=

Vue.ref(null)Vue.onMounted(()

=>

{console.log(root.value)//<div>這是根元素</div})return

{root}},template:

"#st"})app.mount("#app")渲染上下文時暴露root,并通過ref="root",將其綁定到div作為其ref。本章內(nèi)容render函數(shù)組合API使用webpack路由vue-router狀態(tài)管理與Vuex15.3使用webpack15.3.1

webpack介紹15.3.2安裝webpack與webpack-dev-server15.3.3

webpack配置文件15.3.4加載器Loaders與插件Plugins15.3.5單文件組件與vue-loader15.3.1

webpack介紹webpack根據(jù)模塊的依賴關系進行靜態(tài)分析,然后將這些模塊按照指定的規(guī)則生成對應的靜態(tài)資源。webpack的主要適用場景是單頁面應用(SPA),SPA通常是由一個html文件和一堆按需加載的js文件組成。15.3使用webpack15.3.1

webpack介紹15.3.2安裝webpack與webpack-dev-server15.3.3

webpack配置文件15.3.4加載器Loaders與插件Plugins15.3.5單文件組件與vue-loader15.3.2安裝webpack與webpack-dev-server1.安裝Node.js和NPM通過訪問官網(wǎng)/en/即可下載對應版本的Node.js,本書下載的是“14.15.4

LTS”。下載完成后運行安裝包node-v14.15.4-x64.msi,一直下一步即可完成安裝。然后在命令行窗口中輸入命令node-v,檢查是否安裝成功。如上圖所示,出現(xiàn)了版本號,說明Node.js已安裝成功。同時,npm包也已經(jīng)安裝成功,可以輸入npm-v查看版本號。輸入npm-g

install

npm命令,將npm更新至最新版本。2.安裝webpack首先,創(chuàng)建一個目錄,例如C:\webpack-firstdemo,使用VSCode打開該目錄,并進入Terminal控制臺,如下圖所示。初始化配置在上圖中輸入命令npm

init初始化配置,該命令執(zhí)行后,將有一系列選項,可以按回車快速確認,結(jié)束后將在webpack-firstdemo目錄下生成一個package.json文件。安裝webpack初始化配置后,接著在上圖中輸入命令npm

install

webpack--save-dev在本地局部(項目中)安裝webpack。--save-dev將作為開發(fā)依賴來安裝webpack。3.安裝webpack-dev-server接著安裝webpack-dev-server,它可以在開發(fā)環(huán)境中提供很多服務,例如啟動一個服務器、熱更新、接口代理等。在

Terminal控制臺中輸入命令npm

install

webpack-dev-server--save-dev在本地局部安裝webpack-dev-server。4.安裝webpack-cli在Terminal控制臺中輸入命令npm

install

webpack-cli--

save-dev在本地局部安裝webpack-cli。如果在package.json文件的devDependencies中包含webpack、webpack-dev-server和webpack-cli,如下圖所示,說明已成功安裝。15.3使用webpack15.3.1

webpack介紹15.3.2安裝webpack與webpack-dev-server15.3.3

webpack配置文件15.3.4加載器Loaders與插件Plugins15.3.5單文件組件與vue-loader15.3.3

webpack配置文件1.初始化配置在webpack-firstdemo目錄下創(chuàng)建一個名為webpack.config.js的.js文件,并初始化配置內(nèi)容:const

config

=

{}module.exports

=

config2.添加快速啟動webpack-dev-server腳本在package.json的scripts里面添加一個快速啟動webpack-dev-server服務的腳本:"scripts":{"build":"webpack

-p","test":

"echo

\"Error:

no

test

specified\"

&&

exit

1","dev":

"webpack-dev-server

--open

Chrome.exe

--config

webpack.config.js"}在Terminal終端執(zhí)行npm

run

build命令時,將執(zhí)行webpack-p命令進行打包。在Terminal終端執(zhí)行npm

run

dev命令時,將執(zhí)行webpack-dev-server–open

Chrome.exe--config

webpack.config.js命令,其中--config是指向webpack-dev-server讀取配置文件的路徑,這里指向上面步驟中創(chuàng)建的webpack.config.js文件。--open將在執(zhí)行命令時自動使用谷歌瀏覽器打開頁面(如果

open后面沒有指定瀏覽器,則使用默認瀏覽器打開),默認地址是:8080,但IP和端口號可

以修改,示例如下:"dev":

"webpack-dev-server

--host

1

--port

9999

--open

--config

webpack.config.js"3.配置入口和出口在webpack配置中,最重要的也是必選的兩項是入口(entry)和出口(output)。入口的作用是告訴webpack從哪里開始尋找依賴并編譯;出口的作用是配置編譯后的文件存儲位置和文件名。在webpack-firstdemo目錄下創(chuàng)建一個名為main.js空文件作為入口的文件,然后在webpack.config.js中進行入口和出口的配置:const

path

=

require("path")const

config

=

{entry:

{main:

"./main"},output:

{path:

path.resolve(

dirname,

"dist"),publicPath:

"/dist/",filename:

"bundle.js"},mode:

"development"}module.exports

=

config配置entry中的main就是配置的入口,webpack將

從main.js文件開始工作。output中path選項用來存放打包后文件的輸出目錄,是必填項。publicPath指定資源文件引用的目錄,如果資源存放在CDN上,這里可以填CDN的網(wǎng)址。filename用于指定輸出文件的名稱。所以這里配置的output意為打包后的文件將存儲在webpack-firstdemo/dist/bundle.js文件,在html中引入它即可。4.創(chuàng)建index.html文件在webpack-firstdemo目錄下,新建一個名為index.html文件,作為SPA的入口程序:<div

id="app">Hello

Webpack!</div><script

type="text/javascript"

src="/dist/bundle.js"></script>5.在瀏覽器中打開webpack項目在Terminal終端執(zhí)行npm

run

dev命令,將會自動在瀏覽器中打開頁面,如下圖所示。!?。∽⒁猓簣?zhí)行npm

run

dev命令時,可能會報如下錯誤:Cannot

find

module

"webpack-cli/bin/config-yargs"出現(xiàn)上述錯誤的原因是webpack-cli的新版本與webpack-dev-server兼容性的問題,解決辦法是:首先,執(zhí)行npm

uninstall-g

webpack-cli命令,卸載webpack-cli。然后,執(zhí)行npm

installwebpack-cli@3.3.12

--save-dev命令,安裝低版本的webpack-cli。最后,執(zhí)行npm

run

dev命

令,將會自動在瀏覽器中打開頁面。15.3使用webpack15.3.1

webpack介紹15.3.2安裝webpack與webpack-dev-server15.3.3

webpack配置文件15.3.4加載器Loaders與插件Plugins15.3.5單文件組件與vue-loader15.3.4加載器Loaders與插件Plugins1.加載器Loaders在webpack中,一切皆模塊,例如.css、.js、.html、.jpg等。對于不同的模塊,需要使用不同的加載器(Loaders)來處理。Loaders是webpack最強大的功能之一。webpack通過使用不同的Loader,處理不同格式的文件,例如處理CSS樣式文件,需要使用style-loader和css-loader。下面通過NPM安裝它們:npm

install

css-loader

--save-devnpm

install

style-loader

--save-devLoaders安裝后,需要在webpack.config.js的module對象的rules屬性中配置。rules是一個數(shù)組配置規(guī)則,可以指定一系列Loaders,每個Loader都必須包含test和use兩個選項。配置規(guī)則告訴webpack符合test規(guī)

定格式的文件,使用use后面的Loader處理。配置style-loader和css-loader示例代碼如下:rules:[{test:

/\.css$/,use:

["style-loader","css-loader"]}]配置的意思是當webpack編譯過程中遇到require()或import語句導入后綴名.css的文件時,先將.css文件通過css-loader轉(zhuǎn)換,再通過style-loader轉(zhuǎn)換,然后繼續(xù)打包。配置style-loader和css-loader完成后,就可以在配置的入口文件main.js中使用require()或import語句導入.css文件了。2.插件Plugins插件Plugins是實現(xiàn)webpack的自定義功能,可實現(xiàn)Loaders不能實現(xiàn)的復雜功能。使用Plugins豐富的

自定義API以及生命周期事件,可以控制webpack打包流程的每個環(huán)節(jié)。現(xiàn)在我們用一個mini-css-

extract-plugin插件將散落在webpack-firstdemo中的css提取出來,并生成一個common.css文件,最終在index.html中通過<link>的形式加載它。在【例15-7】的基礎上實現(xiàn)該插件。創(chuàng)建.css文件在C:\webpack-firstdemo目錄中創(chuàng)建css文件夾,并在該文件夾中創(chuàng)建style.css,內(nèi)容如下:#app{font-size:

24px;color:

#f50;}導入.css文件配置style-loader和css-loader的前提下,在配置的入口文件main.js中使用import語句導入.css文件,具體如下:import

"./css/style.css‘安裝mini-css-extract-plugin插件通過npm

install--save-dev

mini-css-extract-plugin命令安裝mini-css-extract-plugin插件。(4)配置插件const

path

=

require("path")//導入插件const

MiniCssExtractPlugin

=

require("mini-css-extract-plugin")const

config

=

{entry:

{main:"./main.js"},output:

{path:

path.resolve(

dirname,

"dist"),publicPath:

"/dist/",filename:

"bundle.js"},mode:

"development",plugins:

[new

MiniCssExtractPlugin({filename:"common.css"http://導出的文件名})],//添加的module里面的rules(5)使用CSS在index.html中,使用<link>元素引用common.css,具體代碼如下:<head><link

rel="stylesheet"

type="text/css"

href="/dist/common.css"></head><div

id="app">Hello

Webpack!</div><script

type="text/javascript"

src="/dist/bundle.js"></script>(6)測試插件在Terminal終端執(zhí)行npm

run

dev命令,將會自動在瀏覽器中打開頁面,如下圖所示。從上圖可以看出,導出CSS的插件已生效。15.3使用webpack15.3.1

webpack介紹15.3.2安裝webpack與webpack-dev-server15.3.3

webpack配置文件15.3.4加載器Loaders與插件Plugins15.3.5單文件組件與vue-loader15.3.5單文件組件與vue-loaderVue.js是一個漸進式的Javascript框架,在使用webpack構(gòu)建Vue應用時,可以使用一種新的構(gòu)建模式:.vue單文件組件。.vue是Vue.js自定義的一種文件格式,一個.vue文件就是一個單獨的組件,在文件內(nèi)封裝了組件相關的代碼:html、css、js。.vue文件由三部分組成:<template>、<style>、<script>,示例如下:<template>html</template><style>css</style><script>js</script>可是,瀏覽器本身并不識別.vue文件,所以必須對.vue文件進行加載解析,此時需要webpack的vue-loader加載器?!纠?5-9】使用vue-loader實現(xiàn)單文件組件。在【例15-8】的基礎上完成【例15-9】。1.安裝開發(fā)依賴使用vue-loader加載解析.vue文件時,需要使用vue-template-compiler編譯器對模板內(nèi)容預編譯為Javascript渲染函數(shù)。安裝Vue、vue-loader以及vue-template-compiler依賴時,保證版本一致(編寫本書時,還沒有對應Vue

3的vue-template-compiler,因此本節(jié)使用的是Vue

2)。另外,還需要安裝babel-loader加載器解析ES語法。進入webpack-firstdemo目錄按照以下命令安裝依賴:npm

install

-D

vue

vue-loader

vue-template-compilernpm

install

-D

vue-style-loadernpm

install

-D

babel-loader

@babel/core

@babel/preset-env2.修改配置文件在配置文件webpack.config.js中,添加vue-loader和babel-loader的配置。3.創(chuàng)建app.vue文件在webpack-firstdemo目錄下新建一個app.vue文件作為根實例組件,具體內(nèi)容如下:<template><div>你好,{{vname}}</div></template><script>export

default

{data(){return

{vname:

"Vue"}}}</script><!--因為本項目使用mini-css-extract-plugin插件打包css,加了scoped這部分樣式只對當前組件(app.vue)有效--><style

scoped>div

{color:

red;font-size:

40pt;}</style>4.修改入口main.js.vue是沒有名稱的組件,在父組件中使用時可以對它自定義。現(xiàn)在需要在main.js中使用它。修改后的main.js內(nèi)容如下:import

"./css/style.css"http://下面是Vue3的寫法/*//導入Vue框架中的createApp方法,在Vue3中不能全局導入Vueimport

{createApp}

from

"vue"http://導入app.vue組件import

App

from

"./app.vue"http://創(chuàng)建Vue根實例createApp(App).mount("#app")*///下面是Vue2的寫法import

Vue

from

"vue"http://導入app.vue組件import

App

from

"./app.vue"http://創(chuàng)建Vue根實例const

vm=new

Vue({//指定vm實例要控制的頁面區(qū)域el:

"#app",//通過render函數(shù),把指定的組件渲染到el區(qū)域中render:h=>h(App)/**相當于render:function(h){return

h(app)}*/})5.運行測試執(zhí)行命令npm

run

dev,運行結(jié)果如下圖所示。下面在webpack-firstdemo目錄中再新建一個.vue文件input.vue<template><div><input

v-model="uname"><p>輸入的用戶名是:{{uname

}}</p></div></template><script>

export

default

{props:

{uname:

{type:

String}}}</script>在根實例app.vue組件中,導入input.vue組件,修改后的app.vue代碼如下:<template><div>你好,{{vname}}<!--使用子組件vInput渲染--><v-input></v-input></div></template>執(zhí)行命令npm

run

dev,運行結(jié)果如下圖所示。<script>import

vInput

from

"./input.vue"export

default

{data(){return

{vname:

"Vue"}},components:{//vInput作為根組件的子組件vInput}}</script>從上圖可以看出,我們在index.html中渲染了多個組件內(nèi)容,這就是一個簡單的單頁面應用,即僅有index.html頁面。本章內(nèi)容render函數(shù)組合API使用webpack路由vue-router狀態(tài)管理與Vuex15.4路由vue-router15.4.1什么是路由15.4.2使用Vue

CLI搭建vue-router項目15.4.3

vue-router基本用法15.4.4跳轉(zhuǎn)與傳參15.4.5路由鉤子函數(shù)15.4.1什么是路由在Web前端單頁面應用中,路由描述的是URL與UI之間的映射

關系,這種映射是單向的,即URL變化引起UI更新(無需刷新頁面)。15.4路由vue-router15.4.1什么是路由15.4.2使用Vue

CLI搭建vue-router項目15.4.3

vue-router基本用法15.4.4跳轉(zhuǎn)與傳參15.4.5路由鉤子函數(shù)15.4.2使用Vue

CLI搭建vue-router項目Vue

CLI是一個基于Vue.js進行快速開發(fā)的完整系統(tǒng),提供如下功能:通過@vue/cli實現(xiàn)交互式項目腳手架。通過@vue/cli

+@vue/cli-service-global實現(xiàn)零配置原型開發(fā)。

一個運行時依賴@vue/cli-service,該依賴可升級,基于webpack構(gòu)建,并帶有合理的默認配置;可通過項目的配置文件進行配置;可通過插件進行擴展。一個豐富的官方插件集合,集成了前端生態(tài)工具。提供一套創(chuàng)建和管理Vue.js項目的用戶界面。Vue

CLI致力于將Vue生態(tài)工具基礎標準化。確保各種構(gòu)建工具平穩(wěn)銜接,讓開發(fā)者專注在撰寫應用上,而不必糾結(jié)配置的問題。1.全局安裝Vue

CLI打開cmd命令行窗口,輸入命令npm

install-g

@vue/cli全局安裝Vue腳手架,輸入命令vue--version查看版本(測試是否安裝成功)。2.打開用戶界面安裝成功后,在命令行窗口,繼續(xù)輸入命令vue

ui打開一個瀏覽器窗口,并以圖形化界面引導至項目創(chuàng)建的流程。3.創(chuàng)建項目4.使用VSCode打開項目使用VSCode打開(File—>Open

Folder,選擇項目目錄)第3步創(chuàng)建的項目router-demo。打開后,在Terminal終端輸入

npm

run

serve命令啟動服務。5.運行項目通過http://localhost:8080/訪問時,打開的頁面是public目錄下的index.html。index.html是一個普通的html文件,讓它與眾不同的是“<div

id="app"></div>”這句程序,下面有一行注釋,構(gòu)建的文件將會被自動注入,也就是說我們編寫的其它的內(nèi)容都將在這個div中展示。另外,整個項目只有這一個html文件,所以這是一個單頁面應用,當我們打開這個應用,表面上可以看到很多頁面,實際上它們都在這一個div中顯示。在main.js中,創(chuàng)建了一個Vue對象。該Vue對象的掛載目標是“#app”(與index.html中的id="app"對應);router代表該對象包含VueRouter,并使用項目中定義的路由(在src/router目錄下的index.js文件里定義)。綜上所述,main.js與index.html是項目啟動的首加載頁面資源與js資源,App.vue則是vue頁面資源的首加載項,稱為根組件。Vue項目的具體執(zhí)行過程如下:首先啟動項目,找到index.html與main.js,執(zhí)行main.js(入口程序),根據(jù)import加載App.vue根組件;然后將組件內(nèi)容渲染到index.html中id="app"的DOM元素上。15.4路由vue-router15.4.1什么是路由15.4.2使用Vue

CLI搭建vue-router項目15.4.3

vue-router基本用法15.4.4跳轉(zhuǎn)與傳參15.4.5路由鉤子函數(shù)15.4.3

vue-router基本用法打開使用Vue

CLI搭建好的vue-router項目router-demo。在

router-demo/src目錄中找到main.js,可看到使用use方法加載

vue-router插件:import

{

createApp

}

from

"vue’import

App

from

"./App.vue’import

router

from

"./router"http://導入router目錄中的index.js,路由的創(chuàng)建與配置在該文件中createApp(App).use(router).mount("#app")【例15-10】配置路由。1.創(chuàng)建視圖在src/views目錄下,創(chuàng)建兩個.vue文件:MView1.vue和MView2.vue。MView1.vue的內(nèi)容如下:<template><div>第一個頁面</div></template>

Mview2.vue的內(nèi)容如下:<template><div>第二個頁面</div></template>2.配置路由import

MView1

from

"../views/MView1.vue"import

MView2

from

"../views/MView2.vue"const

routes

=

[{path:

"/",name:

"MView1",component:

MView1},{path:

"/MView2",name:

"MView2",component:

MView2}]在src/router目錄中,找到路由配置文件index.js。在該文件中制定路由匹配列表,即URL與UI的對應關系。每個路由映射一個組件。import{createRouter,createWebHistory}from

"vue-router"http://創(chuàng)建路由實例const

router

=

createRouter({//開啟history路由模式,通過“/”設置路徑history:createWebHistory(process.env.BASE_URL),routes})export

default

router3.修改根組件App.vue在src目錄下,找到App.vue文件,修改后的模板內(nèi)容如下:<template><div

id="nav"><router-link

to="/">第一個頁面</router-link>|<router-link

to="/MView2">第二個頁面</router-link></div><!--路由視圖掛載所有路由組件--><router-view/></template>4.運行項目在Terminal終端輸入npm

run

serve命令啟動服務,訪問

http://localhost:8080/即可運行項目。單擊上圖的超鏈接,進行路由切換,切換的是<router-view/>掛載的組件,其它內(nèi)容不變。15.4路由vue-router15.4.1什么是路由15.4.2使用Vue

CLI搭建vue-router項目15.4.3

vue-router基本用法15.4.4跳轉(zhuǎn)與傳參15.4.5路由鉤子函數(shù)vue-router的第二種跳轉(zhuǎn)方式需要在Javascript里進行,類似于window.location.href。這種方式需要使用router實例方法push或replace。例如,在MView1.vue中,通過點擊事件跳轉(zhuǎn)。<template><div>第一個頁面</div><button

@click="goto">去第二個頁面</button></template><script>

export

default

{methods:

{goto

()

{//也可以使用replace方法,與replace屬性一樣不會向history添加新記錄this.$router.push("/MView2")}}}</script>2.傳參路由傳參,一般有兩種方式:query和params。不管哪種方式都是通過修改URL來實現(xiàn)。query傳參Query傳遞參數(shù)的示例代碼如下:<router-link

to="/?id=888&pwd=999">通過$route.query獲取路由中的參數(shù),示例代碼如下:<h4>id:{{$route.query.id}}</h4><h4>pwd:{{$route.query.pwd}}</h4>params傳參在路由規(guī)則中定義參數(shù),修改路由規(guī)則的path屬性,示例代碼如下;{path:

"/:id/:pwd",name:

"MView1",component:

MView1}<router-link

to="/888/999">通過$route.params獲取路由中的參數(shù),示例代碼如下:<h4>id:{{$route.params.id}}</h4><h4>pwd:{{$route.params.pwd}}</h4>15.4路由vue-router15.4.1什么是路由15.4.2使用Vue

CLI搭建vue-router項目15.4.3

vue-router基本用法15.4.4跳轉(zhuǎn)與傳參15.4.5路由鉤子函數(shù)15.4.5路由鉤子函數(shù)在路由跳轉(zhuǎn)時,我們可能需要一些權限判斷或者其它操作。這時候需要使用路由的鉤子函數(shù)。路由鉤子函數(shù)主要是給使用者在路由發(fā)生變化時進行一些特殊的處理而定義的函數(shù)。1.全局前置鉤子函數(shù)2.全局后置鉤子函數(shù)3.某個路由的鉤子函數(shù)4.組件內(nèi)的鉤子函數(shù)1.全局前置鉤子函數(shù)可以使用router.beforeEach注冊一個全局前置鉤子函數(shù)(在跳轉(zhuǎn)前執(zhí)行),示例代碼如下:const

router

=

new

createRouter({

...

})router.beforeEach((to,

from,

next)

=>

{//

...})beforeEach函數(shù)接收三個參數(shù):to:Route:即將要進入的目標路由對象from:Route:當前導航正要離開的路由

next:Function:一定要調(diào)用該方法來解析

beforeEach鉤子。執(zhí)行效果依賴next方法的調(diào)用參數(shù)。next參數(shù)的相關說明,具有如下:next():進行管道中的下一個鉤子。如果全部鉤子執(zhí)行完,則導航的狀態(tài)就是confirmed(確認的)。

next(false):中斷當前的導航。如果瀏覽器的URL改變(可能是用戶手動或者瀏覽器后退按鈕),那么URL地址會重置到from路由對應的地址。next("/")或者next({path:"/"}):跳轉(zhuǎn)到一個不同的地址。當前的導航被中斷,然后進行一個新的導航。可以向next傳遞任意位置對象,且允許設置諸如replace:true、name:"home"之類的選項以及任何用在router-link的to屬性或router.push中的選項。next(error):如果傳入next的參數(shù)是一個Error實例,則導航被終止且該錯誤被傳遞給router.onerror()注冊過的回調(diào)。2.全局后置鉤子函數(shù)也可以注冊全局后置鉤子函數(shù),該鉤子函數(shù)不接收next參數(shù),也改變導航本身,在跳轉(zhuǎn)之后判斷。示例代碼如下:router.afterEach((to,

from)

=>

{//

...})3.某個路由的鉤子函數(shù)顧名思義,它是寫在某個路由里的函數(shù),本質(zhì)上跟組件內(nèi)的函數(shù)沒有區(qū)別。示例代碼如下:const

router

=

new

VueRouter({routes:

[{path:

"/foo",component:

Foo,beforeEnter:

(to,

from,

next)

=>

{//

...}beforeLeave:

(to,

from,

next)

=>

{//

...}}]})4.組件內(nèi)的鉤子函數(shù)可以在路由組件內(nèi)直接定義路由導航鉤子函數(shù):beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。示例代碼如下:const

Foo

=

{template:

`...`,beforeRouteEnter

(to,

from,

next)

{//在渲染該組件的對應路由被確認前調(diào)用,不能獲取組件實例`this`//因為當該鉤子函數(shù)執(zhí)行前,組件實例還沒被創(chuàng)建},beforeRouteUpdate

(to,

from,

next)

{//在當前路由改變,但是該組件被復用時調(diào)用//舉例來說,對于一個帶有動態(tài)參數(shù)的路徑/foo/:id,在/foo/1和/foo/2之間跳轉(zhuǎn)的時候//由于會渲染同樣的Foo組件,因此組件實例會被復用。而這個鉤子就會在此情況下被調(diào)用。//可以訪問組件實例`this`},beforeRouteLeave

(to,

from,

next)

{//導航離開該組件的對應路由時調(diào)用,可以訪問組件實例`this`}}本章內(nèi)容render函數(shù)組合API使用webpack路由vue-router狀態(tài)管理與Vuex15.5狀態(tài)管理與Vuex15.5.1狀態(tài)管理與應用場景15.5.2

Vuex基本用法15.5.3登錄權限驗證15.5.1狀態(tài)管理與應用場景狀態(tài)管理,管理的是全局狀態(tài),即全局變量。在較大型的項目中,將有許多組件用到同一變量,比如,一個登錄的狀態(tài),很多頁面

組件都需要這個信息。這樣的情景下,使用Vuex進行登錄狀態(tài)的統(tǒng)一管理就很方便。當然,雖然麻煩但也可以時刻在對應頁面操作cookie。所以,狀態(tài)管理不是必需的,所有狀態(tài)管理能做的,都能用其它方式實現(xiàn),但是狀態(tài)管理提供了統(tǒng)一管理的地方,操作方便,也更加明確。但一些狀態(tài)只是父組件和子組件共享,

不推薦使用狀態(tài)管理實現(xiàn),而用$emit和props即可簡單實現(xiàn)。15.5狀態(tài)管理與Vuex15.5.1狀態(tài)管理與應用場景15.5.2

Vuex基本用法15.5.3登錄權限驗證15.5.2

Vuex基本用法使用Vue

CLI搭建基于Router和Vuex功能的項目vuex-demo。Vuex的用法與路由vue-router類似,在main.js中,通過use()方法調(diào)用。示例代碼如下:倉庫store包含了應用的數(shù)據(jù)(狀態(tài))和操作過程。Vuex中的數(shù)據(jù)都是響應式的,即任何組件使用同一store的數(shù)據(jù)時,只要

store的數(shù)據(jù)變化,對應的組件立即更新。import

{

createApp

}

from

"vue"import

App

from

"./App.vue"import

router

from

"./router"http://導入router目錄中的index.js,路由的創(chuàng)建與配置在該文件中import

store

from

"./store"http://導入store目錄中的index.js,Vuex的創(chuàng)建與配置在該文件中createApp(App).use(store).use(router).mount("#app")1.state需要狀態(tài)跟蹤(管理)的數(shù)據(jù)保存在Vuex選項的state字段內(nèi),例如我們要實現(xiàn)一個計算器,可以在store目錄的index.js中定義一個數(shù)據(jù)count,初始值為0。那么,在任何組件內(nèi),都可以直接通過$store.state.count讀取數(shù)據(jù)。import{createStore}from

"vuex"export

default

createStore({state:{//state用來存儲數(shù)據(jù)變量count:

0}})<template><div>計數(shù)器值為{{$store.state.count}}</div></template>2.mutations在組件內(nèi),來自倉庫store的數(shù)據(jù)只能讀取,不能修改。改變

store中數(shù)據(jù)的唯一辦法是顯示提交mutations。mutations是Vuex的一個選項,用來直接修改store中數(shù)據(jù)。import

{

createStore

}

from

"vuex"export

default

createStore({state:{//state用來存儲數(shù)據(jù)變量count:0},mutations:{/*提交更新數(shù)據(jù)的方法,必須是同步的。add(state,data){state.count

+=

data},sub(state,

data){state.count

-=

data}}})在組件內(nèi),通過this.$mit()方法執(zhí)行mutations3.gettersVuex允許我們在store中定義“getter”(可以認為是store的計算屬性)。注意,從Vue

3.0開始,getter的結(jié)果不像計算屬性那樣被緩存。import

{

createStore

}

from

"vuex"export

default

createStore({state:

{mylist:

[100,

20,

30,

300,

200,

400]},getters:

{//統(tǒng)計列表mylist中大于等于100的項

filterList

(state){return

state.mylist.filter(item

=>

item

>=

100)}}})在組件中,可以通過$store.getters訪問getters中的方法。<template><div>統(tǒng)計列表中大于100的數(shù)據(jù):{{$store.getters.filterList}}</div></template>4.a(chǎn)ctionsimport

{

createStore

}

from

"vuex"export

default

createStore({state:

{count:

0},mutations:

{add(state,

data){state.count

+=

data}},actions:

{add

(context)

{//提交mutations中的add方法

mit("add",10)}}})actions類似于mutations,不同在于:actions提交的是mutations,而不是直接變更狀態(tài)。actions可以包含任意異步操作。在組件中,可以通過$store.dispatch()觸發(fā)actions中的方法。<template><button@click="$store.dispatch("add")">actions+10</button></template>import

{

createStore

}

from

"vuex"export

default

createStore({state:

{count:

0},mutations:

{add(state,

data){state.count

+=

data}},actions:

{addAsync

({

commit

})

{setTimeout(()

=>

{commit("add",

10)},

5000)}}})上述actions的用法感覺多此一舉,就目前示例確實如此。但加上異步操作就不一樣了,因為mutations是同步操作。在組件中,同樣通過$store.dispatch()觸發(fā)actions中的方法。<template><button

@click="$store.dispatch("addAsync"

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論