文章目錄
- 前言
- 一、全局元件
- 子元件應用
- 元件優點:元件的可複用性
- 全局元件缺點描述
- 二、局部元件
- 建立與注冊局部元件(認識components屬性)
- 局部元件的預設規定(元件名稱首字母全都大寫)
- 三、父子元件的傳值(靜态、動态)
- 3.1、靜态傳值(name="技小胖")
- 3.2、動态傳值(v-bind:xx="xx"配合子元件中的props數組接收)
- 動态傳遞值
- 動态傳遞函數
- 3.3、三種校驗方式
- ①類型校驗(props需要寫成{}形式)
- ②必填校驗與預設值設定(required與default)
- ③精準校驗(validator)
- 四、單項資料流
- 4.1、父子元件傳遞屬性補充
- ①以對象形式傳遞多個參數
- ②xx-xx=''傳遞,props中xxXx接收
- 4.2、認識單項資料流
- 4.3、解決方案:實作在子元件中修改父元件傳遞過來的參數
- 4.4、設計單向資料流原因
- 五、No-Props屬性
- 5.1、不使用props傳遞時效果(預設會繼承到子元件中,僅僅是單标簽情況)
- 5.2、認識$attrs
- 六、父子元件通信(子元件來發出訓示讓父元件執行指定函數)
- 6.1、$emit來向外觸發父元件函數(無參與有參)
- 6.2、emits屬性(友善管理向外觸發的函數名稱,有警告效果,數組以及對象形式)
- 6.3、v-model配合$emit():實作非調用父元件函數來修改父元件對象屬性值
- 6.3.1、v-model="xxx"預設值接收
- 6.3.2、v-model:屬性="xxx"(設定别名接收)
- 七、slot插槽(5個知識點)
- 八、動态元件(切換元件)
- 8.1、原生切換元件方式(借助v-if、v-show,keep-alive标簽儲存input狀态)
- 8.2、動态元件(component标簽以及:is)
- 九、異步元件(實作異步加載元件)
- 十、補充知識點
- 10.1、v-once(讓某個元素标簽隻渲染一次)
- 10.2、$refs(定位擷取到指定設定ref的dom元素)
- 10.3、provide屬性以及inject屬性(嵌套元件中傳遞值)
- 10.3.1、引出provide以及使用
- 10.3.2、注意點provide屬性綁定inject屬性并不是雙向綁定!!!
前言
本篇部落格是在學習技術胖-Vue3.x從零開始學-第一季 基礎文法篇過程中記錄整理的筆記,若文章中出現相關問題,請指出!
- 目前該連結失效了,有需要的小夥伴可以去b站或者技術胖官網去找相應的視訊與筆記。
所有部落格檔案目錄索引:部落格目錄索引(持續更新)
一、全局元件
子元件應用
<body>
<div id="app"></div>
</body>
<script>
//根元件(全局元件)
const app = Vue.createApp({
//直接應用兩個自元件
template: `
<website />
<describe />
`
});
//子元件
app.component('website', {
template: ` <h2>JSPang.com</h2>`
})
app.component('describe', {
template: ` <h2>技術胖的部落格</h2>`
})
app.mount("#app");
</script>

元件優點:元件的可複用性
優點:元件與元件之間互不幹擾,互相獨立。
<body>
<div id="app"></div>
</body>
<script>
//根元件
const app = Vue.createApp({
//複用多個元件
template: `
<m-count />
<m-count />
<m-count />
`
});
//子元件(全局元件)
app.component('m-count', {
data() {
return {
count: 0
}
},
methods: {
addFun() {
this.count++;
}
},
template: `
<sapn>{{count}}</sapn>
<button @click="addFun()">增加</button>
<br/>
`
})
app.mount("#app");
</script>
全局元件缺點描述
一旦定義了,就會占用系統資源,它是一直存在的,你在任何地方都可以使用這個全局元件,對性能産生影響。
全局元件(通過vue執行個體調用
component()
)的概括:隻要定義了,處處可以使用,性能不高,但是使用起來簡單。
二、局部元件
建立與注冊局部元件(認識components屬性)
建立局部元件:直接使用一個對象{}來表示。
注冊局部元件:需要配合傳入到components對象屬性中。
示例:
<body>
<div id="app"></div>
</body>
<script>
//1、建立局部元件:直接在一個對象中設定參數
const counter = {
data() {
return {
count: 0
}
},
template: `<div>{{count}}<button @click="count++">增加1</button></div>`
};
const app = Vue.createApp({
//2、注冊局部元件,其完整寫法:components: { counter:counter },前面一個是設定的别名,後一個是實際局部元件名稱
//下面我示範别名的寫法,若是不使用别名使用components: { counter }即可!!!
components: { changlu: counter },
template: `
<h2>JSPang.com</h2>
<changlu />
`
});
const vm = app.mount("#app")
</script>
局部元件的預設規定(元件名稱首字母全都大寫)
對于元件的名稱采用全部首字母大寫(駝峰命名法),示例如下:
const XieDaJiao = {
template: `<h2>謝大腳</h2>`
}
三、父子元件的傳值(靜态、動态)
父子元件的傳值,包括靜态傳值和動态傳值。
3.1、靜态傳值(name=“技小胖”)
靜态傳值
核心:直接在标簽中使用
name="技小胖"
,該種方式vue會進行自動解析并傳入到props數組中。
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
//1、通過屬性name傳入到子元件中
template: `
<h2>JSPang.com</h2>
<Son name="技小胖" />
`
});
app.component('Son', {
//2、通過使用props數組形式根将值接收到name屬性裡
props: ['name'],
template: `<div>{{name}} div </div>`
})
const vm = app.mount("#app");
</script>
效果:動态傳值使用
props
屬性接收後,對應的标簽中不會有該鍵值了!
3.2、動态傳值(v-bind:xx="xx"配合子元件中的props數組接收)
動态傳遞值
動态傳值
将這個可改變的動态值放置在
data
對象裡,之後使用v-bind動态從data對象中找到屬性值并指派給指定屬性:
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
//在data對象中包含一個可修改的屬性值(動态的)
name: "cl"
}
},
//1、綁定data對象中的name值也就是cl指派到name參數并傳遞到全局元件中
template: `
<h2>JSPang.com</h2>
<Son v-bind:name="name" />
`
})
app.component('Son', {
//2、同樣使用name屬性來進行接收這個屬性值
props: ['name'],
template: `
<h2>JSPang.com</h2>
<div>{{name}}</div>
`
})
const vm = app.mount("#app");
</script>
注意點:靜态傳值一定傳的是字元串string,而動态傳值是根據data對象中的屬性來決定!!!
動态傳遞函數
動态傳遞函數:本質與上面傳遞值相同,都是傳遞的data對象裡的值。
示例:
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
appFun: () => alert("我是根元件的appFun()方法")
}
},
//1、還是老樣子,編寫v-bind:appFun = "appFun"來綁定對應data對象中的屬性進行動态傳函數
template: `
<h2>JSPang.com</h2>
<Son :appFun="appFun" />
`
})
app.component('Son', {
//2、接收該函數
props: ['appFun'],
methods: {
divClick() {
//3、調用傳入進行的函數
this.appFun();
}
},
//為标簽添加點選事件來間接調用動态傳入的父元件的函數
template: `
<h2>JSPang.com</h2>
<div @click="divClick()">點我試試</div>
`
})
const vm = app.mount("#app");
</script>
3.3、三種校驗方式
①類型校驗(props需要寫成{}形式)
此時props需要寫成{}形式,key為得到的資料,value表示需要校驗的值:這種方式隻是會在console中報出黃色警告資訊,依舊還是将值傳遞過來的!
- Vue支援的校驗類型包括:String、Boolean、Array、Object、Function和Symbol。
效果:僅僅有警告資訊,傳遞依舊會執行。
app.component('Son', {
//校驗name是否為string類型
props: {
name: String
},
template: `<div>{{name}} div </div>`
})
②必填校驗與預設值設定(required與default)
required
required
(布爾值true,false):必須傳遞參數,若是設定了類型參數就必須要校驗指定傳遞的類型。
效果:會報黃色警告資訊,傳遞空值也就是阻止傳遞,程式也會依舊運作!
注意:與default同時存在時,default失效!
示例:
const app = Vue.createApp({
data() {
return {
name: 123
}
},
//進行傳遞值,隻是傳遞的是number類型
template: `
<h2>JSPang.com</h2>
<Son :name="name"/>
`
})
app.component('Son', {
//包含requred屬性進行校驗是否為String類型,不是就會阻止傳遞進來
props: {
name: {
type: String,
// required: false
default: 'i am changlu'
}
},
template: `<div>{{name}} div </div>`
})
default
default
(預設值):沒有傳遞指定參數會設定預設值給指定參數。
效果:當沒有傳遞過來指定值時,就會使用預設參數(沒有required情況下)。
示例:
const app = Vue.createApp({
data() {
return {
name: 123
}
},
//沒有進行傳遞值
template: `
<h2>JSPang.com</h2>
<Son />
`
})
app.component('Son', {
//由于name沒有接受到傳遞值并且沒有required,就會使用default預設值
props: {
name: {
type: String,
default: 'i am changlu'
}
},
template: `<div>{{name}} div </div>`
})
③精準校驗(validator)
validator
:精準校驗是一個函數:通過布爾類型傳回值來表示校驗失敗還是通過。
- true:表示通過校驗。
- false:表示沒有通過校驗,僅僅在console上報警告資訊,傳值同樣成功!
示例:
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
name: 'xxxSPan'
}
},
template: `
<h2>JSPang.com</h2>
<Son :name="name"/>
`
})
app.component('Son', {
props: {
name: {
type: String,
//validator屬性是一個函數用于進行簡單校驗,根據傳回值來表示是否通過
//與default不會有任何聯系,記住default隻是沒有傳遞值的時候進行設定預設值的
validator: function (value) {
console.log(value.search("JSPang"))
return value.search("JSPang") != -1
},
default: 'JSPang.com'
}
},
template: `<div>{{name}} div </div>`
})
const vm = app.mount("#app")
</script>
四、單項資料流
4.1、父子元件傳遞屬性補充
①以對象形式傳遞多個參數
之前僅僅學習了單個值單個值傳遞,若是參數有多個在父元件标簽中需要寫大量的綁定傳值,造成備援。
效果:将要傳遞的多個參數封裝到一個對象中傳遞即可!
示例:
<body>
<div id="app">
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
//1、将多個參數綁定至一個對象
params: {
content: 'xxx内容',
a: 'a',
b: 'b'
}
}
},
//2、使用v-bind='xx',來綁定某個對象進行傳值
template: `
<exerTab v-bind="params" />
`
});
app.component('exerTab', {
//3、可直接使用對象内部的屬性名來接收
props: ['content', 'a', 'b'],
template: `
<span>{{ content }}-{{ a }}-{{ b }}</span>
`
});
app.mount("#app");
</script>
</body>
②xx-xx=''傳遞,props中xxXx接收
靜态傳遞帶有-号的屬性:
content-aa='xxx内容'
,需要使用
props: ['contentAa']
接收。
-
=>content-aa
,去掉-,并且之後字母大寫拼接來接收!contentAa
示例:
<body>
<div id="app">
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
//1、傳遞帶有-的參數:content-aa
template: `
<exerTab content-aa='xxx内容' />
`
});
app.component('exerTab', {
//2、對應該類參數props接收,需要去掉-以及其後大寫:contentAa
props: ['contentAa'],
template: `
<span>{{ contentAa }}</span>
`
});
app.mount("#app");
</script>
</body>
4.2、認識單項資料流
單項資料流
:子元件可以使用父元件傳遞過來的資料,但是決定不能修改傳遞過來的資料!(可以想成調用函數時傳遞過來的是基本類型,而非位址引用傳遞)
效果:若是在子元件中修改父元件傳遞過來的值時就會報出warning提示并且會阻止修改該值!
<body>
<div id="app"></div>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
content: '父元件中的content'
}
},
template: `
<exerTab :content='content' />
`
});
app.component('exerTab', {
props: ['content'],
methods: {
modifyContent() {
this.content = '子元件修改了content';
}
},
//綁定單擊事件來嘗試修改
template: `
<span @click="modifyContent()">{{ content }}</span>
`
});
app.mount("#app");
</script>
</body>
4.3、解決方案:實作在子元件中修改父元件傳遞過來的參數
方案:通過在data對象中設定一個新屬性來接收傳遞來的參數,之後對該新屬性進行指派修改也能夠達成目的!
示例:
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
count: 0
}
},
template: `
<div>
<changlu :count="count"/>
</div>
`
});
app.component('changlu', {
props: ['count'],
data() {
return {
//1、建立一個屬性來進行代替count
mycount: this.count
}
},
methods: {
//2、對新建立的屬性進行指派操作
handlerClick() {
this.mycount++;
}
},
template: `
<span @click="handlerClick()">{{mycount}}</span>
`
});
app.mount("#app");
</script>
4.4、設計單向資料流原因
核心:通過父元件傳遞到子元件中的data對象裡的值不能夠随意更改否則就會影響到其他複用的元件了!!!
五、No-Props屬性
5.1、不使用props傳遞時效果(預設會繼承到子元件中,僅僅是單标簽情況)
簡而言之:就是不使用props屬性來接收的屬性!
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
count: 0
}
},
template: `
<div>
<changlu msg="hello,cl!"/>
</div>
`
});
app.component('changlu', {
//若是不使用props接收預設就會放置在template的标簽中
template: `
<span>changlu元件</span>
`
});
app.mount("#app");
</script>
效果:可以看到對應的鍵值對繼承到了子元件标簽中。若是不想讓鍵值對繼承到子元件上,可以在元件對象中添加如下屬性:
inheritAttrs: false
5.2、認識$attrs
若是不使用props屬性接收且template模闆有多個标簽:不會生效
若此時有個需求就是讓某個标簽具有對應的屬性:此時就使用到了
$attrs
對象
[外鍊圖檔轉存失敗,源站可能有防盜鍊機制,建議将圖檔儲存下來直接上傳(img-5AmAOaDB-1652144855684)(C:\Users\93997\AppData\Roaming\Typora\typora-user-images\image-20210708223102983.png)]
實際應用$attrs
this.$attrs
:一個代理對象,其中包含了所有父元件傳遞子元件時的鍵值對中,可以從這裡擷取!
示例:
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
count: 0
}
},
template: `
<div>
<changlu msg="hello,cl!" msg1="changlugege"/>
</div>
`
});
app.component('changlu', {
methods: {
//this.$attrs:是一個代理對象,該對象中包含父元件傳值過來的所有屬性
handleClick() {
console.log(this.$attrs);
}
},
//v-bind:msg="$attrs.msg1" => 綁定單個值
//v-bind="$attrs" => 綁定所有父元件傳遞過來的值
template: `
<span @click="handleClick()">changlu元件</span>
<span v-bind:msg="$attrs.msg1">changlu元件</span>
<span v-bind="$attrs">changlu元件</span>
`
});
app.mount("#app");
</script>
六、父子元件通信(子元件來發出訓示讓父元件執行指定函數)
目的:通過子元件來調用父元件的函數來改變父元件的data對象中的屬性。
6.1、$emit來向外觸發父元件函數(無參與有參)
無參向外觸發
this.$emit('addOne');
:意思是子元件向外發出了一個
addOne
的信号,外部可使用
@add-one="handleAdd"
來表示收到資訊并執行父元件中的
handleAdd()
函數!
- 這裡
并不是必須要使用的,@add-one
比較特殊對應的是xx-xx
,對于普通名稱也是可以的。xxXx
示例:
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
count: 0
}
},
methods: {
//1、父元件定義方法函數來操控data對象中的屬性
handleAdd() {
this.count++;
}
},
//2、:count="count":父元件向子元件傳遞屬性
// @add-one="handleAdd":其中addOne為子元件向外進行觸發的動作,handleAdd為父元件中本身的方法
template: `
<div>
<changlu :count="count" @add-one="handleAdd"/>
</div>
`
});
app.component('changlu', {
//來接收傳遞過來的屬性
props: ['count'],
methods: {
handleClick() {
//重要:向外觸發父元件的函數(通過傳遞的方式)
this.$emit('addOne');
}
},
template: `
<span @click="handleClick()">{{count}}</span>
`
});
app.mount("#app");
</script>
有參向外觸發
方式:将需要向父元件傳遞的參數寫在第二個參數中即可,如
this.$emit(信号名,參數)
。
6.2、emits屬性(友善管理向外觸發的函數名稱,有警告效果,數組以及對象形式)
目的:配合$emit向外抛出的名稱填寫,用于友善檢視該元件向外觸發的函數!
使用方式:直接在元件對象中設定屬性
emits: ['xxx','xxx']
來進行聲明表示向外觸發的函數!
效果:一旦使用了該emits屬性,那麼就會對内部向外發出($emit)的函數名稱進行校驗,若是向外觸發的沒有在數組中顯示就會出現警告資訊,依舊執行父元件函數的!
數組形式
對象形式
附加功能:使用對象形式你能夠編寫對應的一個校驗函數,若是傳回true表示校驗通過不會有警告資訊,若是沒有通過就會有警告資訊依舊向外觸發執行!
6.3、v-model配合$emit():實作非調用父元件函數來修改父元件對象屬性值
6.3.1、v-model="xxx"預設值接收
方式:原本需要先将指定值進行傳遞之後配合
$emit()
向外抛出執行指令來進行執行,使用了v-model直接讓父元件的對象某屬性與子元件進行綁定連通在子元件中即可對其進行修改隻不過需要配合
$emit
使用`
示例如下:
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
count: 0
}
},
//1、直接使用v-model來進行綁定對應屬性值
template: `
<div>
<changlu v-model="count"/>
</div>
`
});
app.component('changlu', {
//2、使用v-model傳遞的預設必須使用modelValue來接收
props: ['modelValue'],
methods: {
handleClick() {
//3、依舊調用$emit()函數來執行,其中第一參數必須為update:modelValue
//參數一:必須為update:modelValue
//參數二:對于modelValue的操作,也就是說可以直接對外部屬性進行修改
this.$emit('update:modelValue', this.modelValue + 3);
}
},
template: `
<span @click="handleClick()">{{modelValue}}</span>
`
});
app.mount("#app");
</script>
6.3.2、v-model:屬性=“xxx”(設定别名接收)
針對于
6.3.1
進行簡單修改即可!
好處:不用再在外部元件專門寫一個方法來讓内部向外觸發調用了以及通過使用v-bind:xxx來進行傳參!這裡的方式更加的簡潔明了推薦使用!!!
七、slot插槽(5個知識點)
①目的。②引用父元件還是子元件值。③插槽預設值。④具名标簽(區分傳遞指定插槽)。⑤作用域插槽(子元件傳值到父元件要傳遞的插槽内容中)。
1、
slot
插槽目的是為了從父元件中傳遞指定标簽到子元件中來進行使用。
2、父元件中的插槽内容若是使用了
{{}}
就是引用的父元件中的值,在子元件中使用
{{}}
就是引用的子元件值。
const app = Vue.createApp({
data() {
return {
content: '我是父元件'
}
},
//将傳遞的标簽内容寫在<子元件></子元件>中
template: `
<changlu>
<span>{{content}}</span>
</changlu>
`
});
app.component('changlu', {
//在對應的位置使用<slot></slot>即可插入
template: `
<div>
<slot></slot>
</div>
`
});
3、插槽預設值:若是父元件中沒有傳遞指定插槽内容,slot标簽就會失效。若是我們想要給插槽中添加一些預設值(可以是标簽或值),直接寫在slot标簽中即可!但要注意一旦父元件傳遞了插槽内容就不會顯示定義在插槽中的預設值了!
//<slot>标簽中可以定義預設内容,若是父元件不傳遞就會使用預設内容!傳遞就使用傳遞過來的内容
template: `
<div>
<slot>
<button @click="handleclick()">點我下試試</button>
</slot>
</div>
`
4、若是插槽中有多個标簽,此時不同的标簽我們想用在不同位置,就可以使用具名标簽,也就是使用
template
标簽包裹并使用
v-slot:xxx
來進行辨別寫在
template
中,可簡寫為
#
,在子元件中的
slot
标簽裡并配置
name="xxx"
來進行配對父元件傳遞過來的
//父元件:将傳遞的内容子產品化<template v-slot:xxx></template>
//v-slot:btn1 => #btn1,可進行簡化
template: `
<changlu>
<template v-slot:btn1>
<button >按鈕1</button>
</template>
<template v-slot:btn2>
<button >按鈕2</button>
</template>
</changlu>
`
//子元件:對應slot标簽中設定name="xxx"來指定接收
template: `
<div>
<slot name="btn1"></slot>
<div>content</div>
<slot name="btn2"></slot>
</div>
`
5、作用域插槽:若是我們想要周遊父元件傳遞的插槽内容時,如何讓插槽内容能夠引用子元件裡的data對象的值?
在插槽中使用
:xx="xx"
用來傳遞到父元件,在父元件使用子元件标簽中使用
v-slot="obj"
來接收,傳遞來的值以鍵值對形式儲存在
obj
對象裡中,之後即可使用該對象中的屬性進行
{{}}
顯示操作了!!!
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
content: '我是父元件'
}
},
//v-slot="{item}"來接收子元件傳遞過來的值,這裡使用到了對象解構
template: `
<changlu v-slot="{item,dataArr}">
<span>{{item}}</span>
</changlu>
`
});
app.component('changlu', {
data() {
return {
dataArr: [1, 2, 3]
}
},
//使用:item="item"來進行傳值綁定
//可以傳多個值都是可以的,因為是通過對象的形式來接收的
template: `
<div>
<slot v-for="item in dataArr" :item="item" :dataArr="dataArr"></slot>
</div>
`
});
app.mount("#app");
</script>
八、動态元件(切換元件)
8.1、原生切換元件方式(借助v-if、v-show,keep-alive标簽儲存input狀态)
原生切換自定義元件:
v-if
來進行切換時
input
标簽中的内容會清空,不會儲存狀态。若是想要儲存狀态使用
<keep-alive>
标簽包裹。
v-show
會儲存狀态。(原理是
display:none
,僅僅隻是隐藏元件)
//父元件的template
data() {
return {
isSpan: true
}
},
methods: {
//改變isSpan的布爾值達到切換效果
handleclick() {
this.isSpan = this.isSpan ? false : true;
}
},
template: `
<m-span v-if="isSpan"></m-span>
<keep-alive>
<m-input v-if="!isSpan" ></m-input>
</keep-alive>
<button @click="handleclick">點我切換</button>
`
//兩個子元件
app.component('m-span', {
template: `
<span>span标簽顯示</span>
`
});
app.component('m-input', {
template: `
<input type="text"/>
`
});
8.2、動态元件(component标簽以及:is)
好處:解放了之前切換元件時要将多個元件都寫在template模闆裡,切換幾個就需要寫幾個之後通過控制data對象裡的布爾屬性來進行靜态顯示!
方式:
<component :is="自定義标簽名"></component>
,就是這麼簡單,我們隻需要在data對象中定義對應的自定義标簽名就能夠實作動态切換不同的元件,牛逼!
- 特殊:對于
标簽,我們要想儲存切換前的狀态就需要在外面包裹input
标簽。<keep-alive>
示例:
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
//目标要顯示的自定義元件名
showlabel: 'm-span'
}
},
methods: {
handleclick() {
//更改标簽名
this.showlabel = this.showlabel == 'm-span' ? 'm-input' : 'm-span';
}
},
//動态元件實作:不需要通過v-if、v-show來進行判斷顯示,而是直接通過:is="元件名"的顯示動态顯示元件
//<component :is="showlabel"></component> => 動态元件
//<keep-alive> => 儲存input輸入框狀态
template: `
<keep-alive>
<component :is="showlabel"></component>
</keep-alive>
<button @click="handleclick">點我切換</button>
`
});
//自定義的兩個元件
app.component('m-span', {
template: `
<span>span标簽顯示</span>
`
});
app.component('m-input', {
template: `
<input type="text"/>
`
});
const vm = app.mount("#app");
</script>
九、異步元件(實作異步加載元件)
原本之前我們直接定義的
{}
,或者
app.component('元件名',{})
定義的元件都是同步元件。
異步元件目的:通過使用異步元件來動态的加載一些元件,可以将一些大型的項目拆分為小的js檔案,在需要這些元件的時候就可以進行引入并進行使用元件
- 在父标簽中若是使用了異步元件就會進行異步加載元件,不是同步加載了!
核心:
1、
Vue.defineAsyncComponent
(函數),需要傳入一個函數。
2、函數要傳回一個
Promise
,也就是異步,最終通過
resolve({})
或
reject({})
将對應的元件對象傳遞出去就稱為異步元件!
//自定義異步元件
app.component('asynCom', Vue.defineAsyncComponent(() => {
//傳回一個Promise對象
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
template: `
<span>異步顯示的span</span>
`
});//将對應的元件進行傳遞!!!
}, 3000);
})
}));
示例:令元件延時3秒出現,可以看出異步的效果
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
item: 'synCom'
}
},
template: `
<asynCom/>
<br/>
<synCom/>
`
});
//自定義的兩個元件
app.component('synCom', {
template: `
<span>span标簽顯示</span>
`
});
//自定義異步元件
app.component('asynCom', Vue.defineAsyncComponent(() => {
//傳回一個Promise對象
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
template: `
<span>異步顯示的span</span>
`
});//将對應的元件進行傳遞!!!
}, 3000);
})
}));
const vm = app.mount("#app");
</script>
十、補充知識點
10.1、v-once(讓某個元素标簽隻渲染一次)
v-once
:隻顯示一次值在頁面上,之後若是動态修改值也不會進行渲染。(實際值進行了修改)
示例:
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
count: 1
}
},
methods: {
handleclick() {
this.count += 1;
}
},
//v-once="xxx"進行綁定
template: `
<span v-once="count">{{count}}</span>
<button @click="handleclick">點我切換</button>
`
});
const vm = app.mount("#app");
</script>
10.2、$refs(定位擷取到指定設定ref的dom元素)
方式:在某個标簽中添加
ref="xxx"
,之後可通過js中使用
$refs.xxx
來擷取到指定标簽!
應用:擷取到某個結點之後可以對其中内容來進行一些操作,最好還是操作dom元素!
示例:點選按鈕之後來更改按鈕中的值(其實完全可以進行雙向綁定修改值的)
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
count: 1
}
},
methods: {
handleclick() {
//2、擷取到指定設定ref的dom元素
console.log(this.$refs.mspan);
//應用:插入新的内容
this.$refs.mspan.innerHTML = "changlu";
}
},
//1、在指定标簽上定義ref="xxx"
template: `
<button ref="mspan" @click="handleclick">{{count}}</button>
`
});
const vm = app.mount("#app");
</script>
10.3、provide屬性以及inject屬性(嵌套元件中傳遞值)
10.3.1、引出provide以及使用
引出provide以及inject屬性
若是我們定義了兩個子元件,在父元件中使用了第一個子元件,接着在第一個子元件中複用了第二個子元件,此時第二個子元件想要使用父元件中的值就需要一層一層借助通
:xx="xx"+props屬性
來進行一層層往下傳遞。
弊端:若是有大量嵌套元件,需要重複進行v:bind以及props設定傳參!
使用provide以及inject屬性
方式:父元件定義
provide: {}
屬性,孫子元件或其他子元件使用
inject: ['xx']
即可拿到!
注意:
provide
對象想要動态使用
this.屬性
拿到父元件data對象裡的值,需要寫成如
provide(){ return {xxx=this.xxx}}
//想要拿到data對象裡的值,需要編寫provide函數接着子啊傳回對象裡進行擷取!
provide() {
return {
count: this.count
}
},
示例:
<body>
<div id="app"></div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
<script>
const app = Vue.createApp({
data() {
return {
count: 1
}
},
//1、定義可供其他元件使用的provide屬性
provide: {
count: 1
},
template: `
<firstspan></firstspan>
`
});
//子元件:嵌套了子元件
app.component('firstspan', {
template: `
<secspan/>
`
});
//子元件
//2、想要擷取到provide對象中的屬性,需要使用inject數組設定對應屬性名來進行接收
app.component('secspan', {
inject: ['count'],
template: `
<span>{{count}}</span>
`
})
const vm = app.mount("#app");
</script>
10.3.2、注意點provide屬性綁定inject屬性并不是雙向綁定!!!
使用了provide屬性可以友善父元件與嵌套元件友善進行傳值,但是需要注意的是
provide
屬性綁定
inject
屬性并不是雙向綁定,父元件中的值發生改變并不會重新傳值過去來讓子元件進行修改。
解決方案:之後會使用進階的文法來進行解決!(笨方法就是:xxx綁定以及使用props進行接收)
我是長路,感謝你的耐心閱讀。如有問題請指出,我會積極采納!
歡迎關注我的公衆号【長路Java】,分享Java學習文章及相關資料
Q群:851968786 我們可以一起探讨學習
注明:轉載可,需要附帶上文章連結