vue封裝組件js版基本步驟
什么是組件化:
組件化就是將一個(gè)頁(yè)面拆分成一個(gè)個(gè)小的功能模塊,每個(gè)功能模塊完成屬于自己這部分獨(dú)立的功能,使得整個(gè)頁(yè)面的管理和維護(hù)變得非常容易。
Vue組件化思想
- 組件化是Vue中的重要思想,當(dāng)我們對(duì)vue的基本知識(shí)有了一定的基礎(chǔ)就要開(kāi)始封裝組件了
它提供了一種抽象,讓我們可以開(kāi)發(fā)出一個(gè)個(gè)獨(dú)立可復(fù)用的小組件來(lái)構(gòu)造我們的應(yīng)用。組件樹(shù)。
- 組件化思想的應(yīng)用
1.在項(xiàng)目中充分利用組件化的思想
2.盡可能的將也頁(yè)面拆分成一個(gè)個(gè)小的可復(fù)用的組件
3.好處:代碼更加方便組織和管理,擴(kuò)展性也更強(qiáng)
一.注冊(cè)組件的基本步驟
下面我們用一個(gè)封裝一個(gè)Element Ui 的輸入框組件為例,貫徹全文
組件的使用分成三個(gè)步驟
1.創(chuàng)建組件構(gòu)造器c-input
組件的模板 template
注意:只能有一個(gè)根元素,否則警告報(bào)錯(cuò)
1 template 可以是字面量字符串,缺點(diǎn)是沒(méi)有高亮,內(nèi)置在 JavaScript 中,寫起來(lái)麻煩
2 template 可以寫在 script 標(biāo)簽中,雖然解決了高亮的問(wèn)題,但是也麻煩
3 以上方式都不好,我們最終的解決方案是使用 Vue 的 .vue 單文件組件來(lái)寫。(webpack)
但是要想使用這種方式必須結(jié)合一些構(gòu)建工具
<template>
<el-input >
</el-input>
</template>2.注冊(cè)組件
注冊(cè)組件 分為 局部注冊(cè) 與 全局注冊(cè),下一章再講
......使用代碼.........
import cInput from "組件地址/c-ipunt.vue";
export default {
components: {cInput},
.......3.父組件使用
<template>
<c-ipunt/>
</template>
<script>
import cInput from "組件地址/c-ipunt.vue";
export default {
components: {cInput},
.......
</script>二.豐富組件
組件是獨(dú)立的作用域,就像我們 Node 中的 JavaScript 模塊一樣,獨(dú)立的
組件其實(shí)就是一個(gè)特殊的 Vue 實(shí)例,可以有自己的 data、methods、computed、watch 等等選項(xiàng)
組件的 data 必須是函數(shù)
函數(shù)中返回一個(gè)對(duì)象作為組件的 data
<template>
<el-input >
</el-input>
</template>
<script>
export default {
name: 'c-input',
model: {
prop: 'value',
event: 'input',
},
props: {
},
data() {
return {
}
},
watch: {
},
methods: {
},
mounted() {
},
}
</script>
<style scoped>
</style>三.父子組件間的通訊
1.父---->子通信 [props Down]
父組件通過(guò) props 向下傳遞數(shù)據(jù)給子組件
所以子組件要定義接收的參數(shù)
我們可以看到Element Ui 的輸入框組件,有這些屬性我們可以重新定義封裝


<template>
<el-input :disabled="disabled" ref="input" :placeholder="placeholder"
:type="type" :auto-complete="autocomplete">
</el-input>
</template>
<script>
export default {
name: 'c-input',
model: {
prop: 'value',
event: 'input',
},
props: {
labelwidth: {
type: String,
default: undefined,
},
autosize: {
default() {
return { minRows: 2, maxRows: 4 }//如果不使用這個(gè)屬性的默認(rèn)值
},
},
inputCss: {
type: String,
default: '',
},
label: {
type: String,
default: '',
},
value: {
default: undefined,
},
prop: {
type: String,
default: null,
},
placeholder: {
type: String,
default: undefined,
},
required: {
type: Boolean,
default: false,
},
width: {
type: String,
},
type: {
type: String,
default: undefined,
},
autocomplete: {
type: String,
default: 'on',
},
disabled: {
type: Boolean,
default: false,
},
span: {
type: Number,
},
},
data() {
return {
}
},
watch: {
},
methods: {
},
mounted() {
},
}
</script>
<style scoped>
</style>父組件使用
<template>
<c-input label="用戶名" :span="12" />
</template>
<script>
import cInput from "組件地址/c-ipunt.vue";
export default {
components: {cInput},
.......
</script>2. 子----> 父?jìng)髦?[Events Up]
子組件通過(guò) events 給父組件發(fā)送消息,實(shí)際上就是子組件把自己的數(shù)據(jù)發(fā)送到父組件。
在 element ui 的 el-input中是有@input.native="updateValue($event.target.value)" 獲取現(xiàn)在輸入值 @keyup.enter.native="handleEnter" 回車 @focus="focus" 得到焦點(diǎn) 等事件的

<template>
<el-input :disabled="disabled" ref="input" :placeholder="placeholder"
:type="type" :auto-complete="autocomplete" @input.native="updateValue($event.target.value)" @keyup.enter.native="handleEnter" @focus="focus">
</el-input>
</template>
<script>
export default {
name: 'c-input',
model: {
prop: 'value',
event: 'input',
},
props: {
labelwidth: {
type: String,
default: undefined,
},
autosize: {
default() {
return { minRows: 2, maxRows: 4 }//如果不使用這個(gè)屬性的默認(rèn)值
},
},
inputCss: {
type: String,
default: '',
},
label: {
type: String,
default: '',
},
value: {
default: undefined,
},
prop: {
type: String,
default: null,
},
placeholder: {
type: String,
default: undefined,
},
required: {
type: Boolean,
default: false,
},
width: {
type: String,
},
type: {
type: String,
default: undefined,
},
autocomplete: {
type: String,
default: 'on',
},
disabled: {
type: Boolean,
default: false,
},
span: {
type: Number,
},
},
data() {
return {
}
},
watch: {
},
methods: {
updateValue(val) {
this.$emit('input', val)
},
handleEnter() {
this.$emit('keyup-enter')
},
focus() {
this.$emit('focus')
},
},
mounted() {
},
}
</script>
<style scoped>
</style>父組件使用
<template>
<c-input label="用戶名" :span="12" @keyup-enter="mykeyupEnter" @focus="myfocus"/>
</template>
<script>
import cInput from "組件地址/c-ipunt.vue";
export default {
components: {cInput},
.......
methods: {
mykeyupEnter(){
console.log("我是父組件的輸入框回車")},
myfocus(){
console.log("我是父組件的輸入框得到焦點(diǎn)")
}
},
......
</script>3. 子<----> 父 雙向傳值
我們知道Vue的核心特性之一是雙向綁定,
v-model是一個(gè)指令用來(lái)實(shí)現(xiàn)雙向綁定,限制在<input>、<select>、<textarea>、components中使用,修飾符.lazy(取代input監(jiān)聽(tīng)change事件)、.number(輸入字符串轉(zhuǎn)為有效的數(shù)字)、.trim(輸入首尾空格過(guò)濾)。那么我們封裝的組件怎么進(jìn)行雙向綁定呢。
- 首先 props添加一個(gè)value,接收父組件的數(shù)據(jù)變化。
- 再添加一個(gè)value的監(jiān)聽(tīng),監(jiān)聽(tīng)父組件的數(shù)據(jù)變化。
- 而子組件數(shù)據(jù)變化的時(shí)候會(huì)出發(fā)這個(gè)事件@input.native="",所以這個(gè)時(shí)間觸發(fā)this.$emit('input',val),向父組件傳遞 子組件的數(shù)據(jù)變化
<template>
<el-input :disabled="disabled" ref="input" :placeholder="placeholder"
:type="type" :auto-complete="autocomplete" @input.native="updateValue($event.target.value)" @keyup.enter.native="handleEnter" @focus="focus" v-model="modelValue">
</el-input>
</template>
<script>
export default {
name: 'c-input',
model: {
prop: 'value',
event: 'input',
},
props: {
labelwidth: {
type: String,
default: undefined,
},
autosize: {
default() {
return { minRows: 2, maxRows: 4 }//如果不使用這個(gè)屬性的默認(rèn)值
},
},
inputCss: {
type: String,
default: '',
},
label: {
type: String,
default: '',
},
value: {
default: undefined,
},
prop: {
type: String,
default: null,
},
placeholder: {
type: String,
default: undefined,
},
required: {
type: Boolean,
default: false,
},
width: {
type: String,
},
type: {
type: String,
default: undefined,
},
autocomplete: {
type: String,
default: 'on',
},
disabled: {
type: Boolean,
default: false,
},
span: {
type: Number,
},
},
data() {
return {
modelValue: undefined,
}
},
watch: {
value: {
handler(newValue) {
this.modelValue = newValue
},
immediate: true,
},
},
methods: {
updateValue(val) {
this.$emit('input', val)
},
handleEnter() {
this.$emit('keyup-enter')
},
focus() {
this.$emit('focus')
},
},
mounted() {
},
}
</script>
<style scoped>
</style>使用
<template>
<c-input label="用戶名" :span="12" @keyup-enter="mykeyupEnter" @focus="myfocus" v-model="myName"/>
</template>
<script>
import cInput from "組件地址/c-ipunt.vue";
export default {
components: {cInput},
data() {
return {
myName: undefined,
}},
.......
methods: {
mykeyupEnter(){
console.log("我是父組件的輸入框回車")},
myfocus(){
console.log("我是父組件的輸入框得到焦點(diǎn)")
}
},
......
</script>四.slot插槽
什么是插槽?
插槽(Slot)是Vue提出來(lái)的一個(gè)概念,正如名字一樣,插槽用于決定將所攜帶的內(nèi)容,插入到指定的某個(gè)位置,從而使模板分塊,具有模塊化的特質(zhì)和更大的重用性。
插槽顯不顯示、怎樣顯示是由父組件來(lái)控制的,而插槽在哪里顯示就由子組件來(lái)進(jìn)行控制
怎么用插槽?
默認(rèn)插槽
父組件
<template>
<div>
我是父組件
<slotOne1>
<p style="color:red">我是父組件插槽內(nèi)容</p>
</slotOne1>
</div>
</template>在父組件引用的子組件中寫入想要顯示的內(nèi)容(可以使用標(biāo)簽,也可以不用)
子組件(slotOne1)
<template>
<div class="slotOne1">
<div>我是slotOne1組件</div>
<slot></slot>
</div>
</template>在子組件中寫入slot,slot所在的位置就是父組件要顯示的內(nèi)容

具名插槽
子組件
<template>
<div class="slottwo">
<div>slottwo</div>
<slot name="header"></slot>
<slot></slot>
<slot name="footer"></slot>
</div>
</template>在子組件中定義了三個(gè)slot標(biāo)簽,其中有兩個(gè)分別添加了name屬性header和footer
父組件
<template>
<div>
我是父組件
<slot-two>
<p>啦啦啦,啦啦啦,我是賣報(bào)的小行家</p>
<template slot="header">
<p>我是name為header的slot</p>
</template>
<p slot="footer">我是name為footer的slot</p>
</slot-two>
</div>
</template>在父組件中使用template并寫入對(duì)應(yīng)的slot值來(lái)指定該內(nèi)容在子組件中現(xiàn)實(shí)的位置(當(dāng)然也不用必須寫到template),沒(méi)有對(duì)應(yīng)值的其他內(nèi)容會(huì)被放到子組件中沒(méi)有添加name屬性的slot中

作用域插槽
子組件
<template>
<div>
我是作用域插槽的子組件
<slot :data="user"></slot>
</div>
</template>
<script>
export default {
name: 'slotthree',
data () {
return {
user: [
{name: 'Jack', sex: 'boy'},
{name: 'Jone', sex: 'girl'},
{name: 'Tom', sex: 'boy'}
]
}
}
}
</script>在子組件的slot標(biāo)簽上綁定需要的值
父組件
<template>
<div>
我是作用域插槽
<slot-three>
<template slot-scope="user">
<div v-for="(item, index) in user.data" :key="index">
{{item}}
</div>
</template>
</slot-three>
</div>
</template>在父組件上使用slot-scope屬性,user.data就是子組件傳過(guò)來(lái)的值

以上就是vue封裝組件js版基本步驟的詳細(xì)內(nèi)容,更多關(guān)于js封裝vue組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Element中el-select下拉框?qū)崿F(xiàn)選中圖標(biāo)并回顯圖標(biāo)
本文主要介紹了Element中el-select下拉框?qū)崿F(xiàn)選中圖標(biāo)并回顯圖標(biāo),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-12-12
Vue實(shí)例中生命周期created和mounted的區(qū)別詳解
這篇文章主要給大家介紹了關(guān)于Vue實(shí)例中生命周期created和mounted區(qū)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08
flutter使用tauri實(shí)現(xiàn)一個(gè)一鍵視頻轉(zhuǎn)4K軟件
這篇文章主要為大家介紹了flutter使用tauri實(shí)現(xiàn)一個(gè)一鍵視頻轉(zhuǎn)4K軟件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
vue中選中多個(gè)選項(xiàng)并且改變選中的樣式的實(shí)例代碼
這篇文章主要介紹了vue中選中多個(gè)選項(xiàng)并且改變選中的樣式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
Vue實(shí)現(xiàn)簡(jiǎn)單選項(xiàng)卡效果
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)簡(jiǎn)單選項(xiàng)卡效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
Vue SPA單頁(yè)面的應(yīng)用和對(duì)比
單頁(yè)面是指整個(gè)應(yīng)用程序只有一個(gè)唯一完整的 HTML 頁(yè)面,而其它所謂的頁(yè)面,其實(shí)都是組件片段而已,切換頁(yè)面也只是切換一個(gè) HTML 中顯示不同的組件片段。在今后所有的開(kāi)發(fā)項(xiàng)目都是單頁(yè)面應(yīng)用2022-08-08

