Vue進階
生命周期
組件運行的程序

組件的生命周期是:組件從創建->運行(渲染)->銷毀的整個程序,是一個時間段
如何監聽組件的不同時刻
vue框架為組件內置了不同時刻的生命周期函式,是他在關鍵時刻幫我們呼叫的一些特殊名稱的函式,生命周期函式會伴隨著組件的運行而自動呼叫,
created函式 組件在記憶體中被創建完畢mounted函式 組件第一次被渲染到頁面上unmounted函式 組件被銷毀完畢了(隱藏)updated函式 當組件被重新渲染完畢后會自動呼叫
當組件被重新渲染完畢后,會自動呼叫updated生命周期函式
組件中全部的生命周期函式

問:為什么不在beforeCreate中發ajax請求?
此階段無法訪問data,請求到的資料無法掛載到data中供組件渲染去使用
完整的生命周期函式
Vue2.x
Vue3.x
組件化編程
模塊:向外提供特定功能的Js程式,一般是一個Js檔案,
組件:實作應用中區域功能代碼和資源的代碼集合,
模塊化:當應用中的Js都以模塊化來撰寫,那這個應用就是一個模塊化應用,
組件化:當應用中的功能都是多組件的方式來撰寫,那這個應用就是一個組件化的應用,
單檔案組件:一個檔案中只有一個組件
vue單檔案組件的構成
template 組件的模板結構(必須)
script 組件的js行為
style 組件的樣式
template節點
規定:每個組件對應的模板結構,都需要定義<template>節點中,是vue提供的容器標簽,<template>只起到包裹性質的作用,不會被渲染成真正的DOM元素,
在<template>節點中支持指令語法
在vue2.x的版本中,DOM結構僅支持單個根節點
在vue3.x的版本中,DOM結構僅支持多個根節點
script節點
<script>
export default{} //data資料和methods方法
</script>
name節點:為組件定義一個名稱
data節點:vue組件渲染期間需要用到的資料(data需指向一個函式,函式中再return物件)
methods節點:組件中的事件處理函式節點
style節點
style標簽上的lang=‘css’屬性是可選的,它表示所使用的樣式語言,默認css,還有less和scss語法
組件的基本使用
1、組件的命名
kebab-case命名法(短橫線命名法)、Camelcase命名法(大駝峰命名法)(后者可轉化為短橫線使用,只能在腳手架中使用)
也可以將name屬性作為注冊后組件的名稱,盡可能回避HTML已有的元素名稱,
2、組件的注冊
組件之間可以相互的參考,但必須先注冊后使用
全域和區域注冊
被全域注冊的組件可以在全域如何一個組件內使用,被區域注冊只能在當前注冊范圍內使用
.component(’ 名稱‘,組件名)方法全域注冊
component:{鍵值對}區域注冊
使用頻率高的進行全域注冊,使用頻率低的區域注冊
3、組件之間的樣式沖突問題
父組件的樣式會影響子組件
根本原因:SPA中,所有組件的DOM結構,都基于唯一的index.html頁面進行呈現,每個組件的樣式都會影響到整個index.html頁面中的DOM元素
解決:
方法一:為每個組件分配唯一的自定義屬性,在撰寫組件樣式時,通過屬性選擇器來控制樣式的作用域
<template>
<div data-v-001>
<h1 data-v-001> 這是App.vue組件</h1>
<p data-v-001>這是App中的p標簽</p>
</div>
</template>
<script>
</script>
<style lang="less">
p[data-v-001]{
color: red;
}
</style>
方法二:vue為style節點提供了scoped屬性,從而防止組件之間的樣式沖突問題
但如果給當前組件的style的節點添加了scoped屬性,則當前組件的樣式對其子組件是不生效的,如果想生效,可以使用/deep/深度選擇器,vue3.x中推薦 :deep()
/deep/.title{ } 等價于 [data-v-xxx].title 等價于 :deep(title){ }
4、組件的props
封裝vue組件時的基本原則:
- 組件的DOM結構、Style樣式盡量復用
- 組件中要展示的資料,盡量由使用者提供
為了方便使用者為組件提供要展示的資料,vue提供了props的概念
什么是組件的props?props是組件的自定義屬性,組件的使用者可以通過props把資料傳遞到子組件內部,供子組件內部使用
作用:父組件通過props向子組件傳遞要展示的資料
宣告:在封裝vue組件時,可以把動態的資料項宣告為props自定義屬性
(無法使用未宣告的props)
<template>
<div data-v-001>
<h1 data-v-001> 書名:{{title}}</h1>
<p data-v-001>作者:{{author}}</p>
</div>
</template>
<script>
export default{
name:'MyArticle',
props:['title','author']
}
</script>
動態系結props的值:可以使用v-bind屬性系結的形式,為組件動態系結props的值
props的大小寫命名:如果使用camelCase宣告props屬性的名稱,則可以使用:駝峰/短橫線的形式為組件系結屬性的值
5、Class和Style系結
vue允許開發者通過v-bind屬性系結指令,為元素動態系結class屬性的值和行內的style樣式,來動態操作元素樣式
- 動態系結HTML的class:可以通過三元運算式,動態的為元素系結class的類名
<template>
<div>
<h3 :>MyStyle組件</h3>
<button @click="isItalic=!isItalic">Toggle Italic</button>
</div>
</template>
<script>
export default{
name:'MyArticle',
data(){//防止一個組件被多次呼叫時,存在資料的參考關系
return{
isItalic:true,
}
}
}
</script>
<style lang="less">
.thin{
font-weight: 200;
}
.italic{
font-style: italic;
}
</style>
- 以陣列語法系結HTML的class
如果元素需要動態系結多個class類名,可以使用陣列的語法格式
<h3 :>MyStyle組件</h3>
- 以物件語法系結HTML的class
采用陣列語法會導致模板結構臃腫,故使用物件語法進行簡化
<h3 :>MyStyle組件</h3>
<script>
export default{
name:'MyArticle',
data(){
return{
isItalic:true,
classObj:{
isItalic:true,
}
}
}
}
</script>
- 以物件語法系結行內的style樣式
<template>
<div data-v-001>
<div :style="{color:active,fontsize:fsize+'px','background-color':bgcolor}"></div>
//不寫成駝峰就得用單引號包括,表示是一個字串的屬性
<button @click="isItalic=!isItalic">Toggle Italic</button>
</div>
</template>
<script>
export default{
name:'MyArticle',
data(){
return{
isItalic:true,
active:'red',
fsize:30,
bgcolor:'pink',
}
}
}
</script>
VueComponent建構式
- 組件本質是一個名為
VueComponent的建構式,且不是程式員定義的,由Vue.extend生成的, - 呼叫組件時,Vue決議時會幫我們創建組件的實體物件,即幫我們執行:
new VueComponent(options) - 注意:每次呼叫
Vue.extend,回傳的都是一個個全新的VueComponent
關于this指向:
組件配置中:
data函式、methods中的函式、watch中的函式、computed中的函式,this均是【VueComponent實體物件(vc)】
new Vue()配置中:
data函式、methods中的函式、watch中的函式、computed中的函式,this均是【Vue實體物件(vm)】
一個重要的內置關系:VueComponent.prototype.__proto__==Vue.prototype
讓組件實體物件可以訪問到Vue原型上的屬性、方法,

單頁面應用程式(SPA)
一個Web網站中只有唯一的一個HTML頁面(所有的功能與互動)
特點:僅在該web頁面初始化時加載相應的資源,不會因為用戶操作來進行頁面的重新加載或跳轉
有點:良好的互動體驗(不會出現白屏現象)
? 良好的前后端作業分離模式(后端專注于提供API介面,前端專注于頁面的渲染)
? 減輕服務器的壓力(服務器只提供資料,不負責頁面合成和邏輯處理)
缺點:首屏加載慢(解決:路由懶加載、代碼壓縮、CDN加速、網路傳輸壓縮)
? 不利于SEO(引擎優化) (解決:SSR服務器端渲染)
腳手架—快速創建SPA專案
1、基于vite創建SPA專案
2、基于vue-cli創建SPA專案

vite的基本使用
1、創建vite專案
npm init vite-app 專案名稱
cd 專案名稱
npm install
npm run dev
2、梳理專案的結構


3、vite專案的運行流程
在工程化專案中,vue要做的事情很單純,通過main.js把App.vue渲染到index.html的指定區域中
App.vue用來撰寫待渲染的模板結構
index.html中需要預留一個el區域
main.js把App.vue渲染到index.html所預留的區域中
Vue-cli的基本使用
1、創建cli專案
npm i -g @vue/cli
npm create 專案名稱
cd 專案名稱
npm run serve

2、查看具體的webpack配置
vue inspect > output.js
組件通訊
組件之間的資料共享的6種方案
組件之間的關系
- 父子關系
- 兄弟關系
- 后代關系
父子組件之間的資料共享
1、父->子共享資料
父組件通過v-bind屬性系結向子組件共享資料,同時,子組件需要使用props接受資料
2、子->父共享資料
子組件通過自定義事件的方式向父組件共享資料,emit傳參
3、父<->子雙向資料同步
使用v-model指令維護組件內外資料的雙向同步
兄弟組件之間的資料共享
4、兄<->弟共享資料
共享方案:EventBus,可以借助第三方包mitt來創建eventBus物件

- 安裝mitt依賴包
npm install [email protected]
- 創建公共的EventBus模塊
import mitt from 'mitt'
//創建Eventbus的實體物件
const bus=mitt()
//將Eventbus的是實體物件共享出去
export default bus
- 在資料接收方宣告自定義事件
呼叫bus.on('事件名稱',事件處理函式)方法注冊一個自定義事件
<script>
import bus from 'eventBus.js'
export default{
data(){return { count 0}},
created(){
bus.on('',(count)=>{
this.count=count
})
}
}
</script>
- 在資料發送方觸發事件
呼叫bus.emit('事件名稱',要發送的資料)方法觸發自定義事件
<script>
import bus from 'eventBus.js'
export default{
data(){return { count 0}},
methods:{
add(){
this.count++
bus.on('',this.count)
}
}
}
</script>
后代組件之間的資料共享
5、父<->子孫共享資料
指的是父節點組件向其子孫組件共享資料,此時組件之間的嵌套關系比較復雜,可以使用provide和inject實作后代關系組件之間的資料共享
- 父組件通過provide共享資料
<script>
export default{
data(){return { count 0}},
provide(){
return {
color:this.color
}
}
}
</script>
- 子孫組件通過inject接收資料
<script>
export default{
data(){return { count 0}},
inject:['color'],
}
</script>
- 父節點對外共享回應式資料(provide非回應式)
<script>
import {computed} from 'vue'//從vue中匯入computed函式
export default{
data(){return {color:'red'}},
provide(){
return {
//使用computed函式,可以把要共享的資料包裝為回應式資料
color:computed(()=>this.color)
}
}
}
</script>
- 子孫節點使用回應式資料
子孫節點必須使用.value的形式進行使用
6、Vuex全域資料共享
總結

ref參考
ref用來輔助開發者在不依賴jQuery的情況下,獲取DOM元素或組件的參考,
每個vue組件實體上,都包含一個$refs物件,里面存盤這對應DOM元素或組件的參考,默認情況下,組件里的$refs指向一個空物件
使用ref參考DOM元素
<h1 ref="myh111"> nihao</h1>
<button @click="getRefs">
獲取“$refs”參考
</button>
<script>
export default {
name:'MyApp',
methods:{
getRefs(){
this.$refs.myh111.style.color='red'
}
}
}
</script>
使用ref參考組件
<h1 ref="myh111"> nihao</h1>
<button @click="getRefs">
獲取“$refs”參考
</button>
<my-counter ref="countRef"></my-counter>
<script>
export default {
name:'MyApp',
methods:{
getRefs(){
this.$refs.countRef.reset()//呼叫組件內的reset()方法
}
}
}
</script>
控制文本框的按鈕的按需切換(文本框自動獲得焦點.focus()方法)
組件是異步執行DOM更新的
解決:this.$nextTick(cb) cb回呼被延遲到DOM重新渲染完成之后執行,保證cd回呼函式可以操作最新的DOM元素
<script>
export default {
name:'MyApp',
methods:{
getRefs(){
this.$nextTick(()=>{
this.$refs.ipt.focus()
})
}
}
}
</script>
mixin混入
在components撰寫mixin.js檔案,可以把多個組件共用的配置提取成一個混入物件,
export const mixin={
methods:{
showNmae(){
alert(this.name)
}
}
}
//區域混入
<script>
import {hunhe} from '../mixin'
export default {
name:'MyApp',
data(){
return {
name:''
}
},
mixin:[hunhe],
}
</script>
//全域混入
Vue.mixin(xxx)
動態組件
指的是動態切換組件的顯示與隱藏,vue提供了一個內置的
實作動態組件渲染
<component :is="組件名稱"></component>
使用keep-alive保持狀態(快取)
隱藏組件時會將組件在記憶體中銷毀,不會保持最后的狀態,可以使用
<keep-alive>
<component :is="組件名稱"></component>
</keep-alive>
scoped樣式
為什么會產生樣式類名沖突?
Vue決議組件時,會將所有的style合并,當類名相同時會以后引入的樣式為主,
使用scoped解決css樣式類名沖突問題,但App組件不適用,
插槽
什么是插槽?
插槽(slot)是vue為組件封裝者提供的能力,允許開發者在封裝組件時,把不確定的,希望用戶指定的部分定義為插槽,(為用戶預留的內容的占位符),
在封裝組件時,可以通過<slot></slot>元素定義插槽,從而為用戶預留內容占位符
沒有預留插槽的自定義內容會被丟棄(Vue不知道將該DOM渲染到何處)
<--header組件!-->
<template>
<div>
<slot></slot>
</div>
</template>
<--參考!-->
<header>
<ul>
<li></li>
<li></li>
</ul>
<--將ul插入header組件!-->
</header>
插槽的默認內容(后備內容)
可以為預留的<slot>插槽提供后備內容(默認內容),如果使用者沒有提供內容,則后備內容將會生效
具名插槽
上述定義的是默認插槽,如果在封裝組件時需要預留多個插槽節點,則需要為每個<slot>插槽指定具體的name名稱,這種帶有具體名稱的插槽叫做:具名插槽
<slot name=" "></slot>
<slot ></slot> //默認名:default
<--header組件!-->
<template>
<div>
<slot name="center"></slot>
<slot name="footer"></slot>
</div>
</template>
<--參考!-->
<header>
<ul slot="center">
<li></li>
<li></li>
</ul>
<a slot="footer"></a>
</header>
<--另一種寫法!-->
<header>
<ul slot="center">
<li></li>
<li></li>
</ul>
<template v-slot:header>
<h1>
滕王閣序
</h1>
</template>
</header>
<header>
<ul slot="center">
<li></li>
<li></li>
</ul>
<template #header>
<h1>
滕王閣序
</h1>
</template>
</header>
作用域插槽
在封裝組件的程序中,可以為預留的<slot>插槽系結props資料,使得子組件可以向參考傳參(資料逆流),這種帶有props資料的<slot>叫做:作用域插槽,
<--header組件!-->
<template>
<div>
<slot :games="games"></slot>
</div>
</template>
......
data(){
return{
games:['first','second','third']
}
}
<header>
<template scope="games">
<ul>
<li></li>
<li></li>
</ul>
<h1>
滕王閣序
</h1>
</template>
</header>
解構作用域插槽的prop
scope是一個物件,那么能否直接使用物件的解構賦值呢?
<header>
<template scope="{games}">
<ul>
<li></li>
<li></li>
</ul>
<h1>
滕王閣序
</h1>
</template>
</header>
<header>
<template slot-scope="{games}">
<ul>
<li></li>
<li></li>
</ul>
<h1>
滕王閣序
</h1>
</template>
</header>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/547214.html
標籤:其他
上一篇:萬字血書Vue—Vue語法
