一.組件化開發(fā)
- 組件 (Component) 是 Vue.js 強大的功能之一。組件可以擴展 HTML 元素,封裝可重用的代 碼。在較高層面上,組件是自定義元素,Vue.js 的編譯器為它添加特殊功能。
- 在vue中都是組件化開發(fā)的,組件化開發(fā)就是把一個完整的頁面分割成一個一個的小組件
- 組件化開發(fā) 容易維護 可以復用
1.1.定義簡單的組件
1.1.1語法:
Vue.component()里面有兩個參數(shù):
組件名稱是個對象 對組件的設置 包括html模板 數(shù)據(jù)偵聽器等
Vue.component('first-component',{ template:'<h1>我愛我的祖國</h1>'})
1.1.2組件的使用:
<div id="app"> <first-component></first-component>
</div>
組件不能寫到#app的元素外面
1.1.3組件的重復使用
組件就是一個可以重復引用的Vue實例 可以在頁面中引用多次
<div id="app">
<first-component></first-component>
<first-component></first-component>
<first-component></first-component>
<first-component></first-component>
<first-component></first-component>
</div>
1.1.4定義的組件只能有一個根元素
案例:
下面定義組件中兩個h1都輸入根元素
Vue.component('aa',{
template:'<h1>愛我中華</h1><h1>建設我們的國家</h1>'
})
可以改寫成如下:
Vue.component('aa',{
template:'
<div><h1>愛我中華</h1><h1>建設我們的國家</h1>
</div>
'
})
1.2.組件中的事件
組件就是可以重復使用的Vue實例 所以組件中也有Vue中的事件
data computed watch methods 以及生命周期鉤子函數(shù)等 但是組件中沒有el
組件中也可以為元素添加事件:
Vue.component('aa', {template: `<div class="bottom"><button @click="turnOn">我是測試按鈕</button></div>`,methods: {turnOn(){console.log('我是組件中的事件')}}})
1.3.組件中的數(shù)據(jù)
組件中的data數(shù)據(jù) 與new Vue中的不同 為了保證組件中的數(shù)據(jù)是私有的所以組件中的data數(shù)據(jù)是一個返回函數(shù) 組件中的數(shù)據(jù)都在函數(shù)的作用域中 保證組件中的數(shù)據(jù)互不感染
data() {return {msg: '愛我中華'}}
二.組件通訊
因為組件對封閉的 但是在實際的開發(fā)中 組件之間的數(shù)據(jù)是相互依賴 需要相互傳遞的 具體來說組件通訊分為三大類:
- 父組件為子組件傳遞數(shù)據(jù)
- 子組件為父組件傳遞數(shù)據(jù)
- 非父子組件之間傳遞數(shù)據(jù)
2.1 父傳子
父組件向子組件傳遞數(shù)據(jù)
- 在子組件中定義props屬性 值為數(shù)組類似于data 但data中的數(shù)據(jù)來自本身 而props中的數(shù)據(jù)來自父組件
- 子組件使用模板中使用props中的屬性和data中的用法相同
- 父組件通過props傳值給子組件
輸出結果為:
說明:
創(chuàng)建Vue實例 data中的數(shù)據(jù)msg為一個數(shù)組創(chuàng)建組件 在整個項目中 2組件相對就是1的子組件通過3方式前者msg為props值中的數(shù)據(jù) 后者msg為newVue中data中的數(shù)據(jù)最后正是props中的屬性也有data中的使用方法 將數(shù)據(jù)進行遍歷在頁面中
**注意:props負責獲取父組件的傳遞過來的,props中的值是只讀的,不允許修改 **
2.2 子傳父
原理
- 父組件使用子組件時 在其中定義一個自定義事件 并且綁定父組件中的一個自定義函數(shù) 當事件被調(diào)用時執(zhí)行自定義函數(shù)
- 子組件通過this$emit執(zhí)行自定義事件
最終輸出結果為3
在子組件中定義一個點擊事件 觸發(fā)時執(zhí)行子組件中的dian函數(shù) 并且將參數(shù)傳入函數(shù)中在上面的函數(shù)中通過this.$emit(‘事件名稱’,參數(shù))調(diào)用3中的a自定義事件并且將參數(shù)傳過去當a事件被觸發(fā)時 會執(zhí)行4中的aaa自定義函數(shù) 同時獲取參數(shù) 最終實現(xiàn)子組件向父組件傳數(shù)據(jù)
實例改造
根據(jù)父子組件之間的數(shù)據(jù)傳遞實現(xiàn)產(chǎn)品列表的組件化開發(fā)
代碼如下
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>div {width: 1000px;margin: 100px auto;text-align: center;}table {width: 900px;margin: 50px auto;border-collapse: collapse;}table,th,td {border: 1px solid rgb(218, 124, 17);}.color {background-color: rgb(26, 172, 152);}</style>
</head><body><div id="app"><atitle @tian="tian" :aatitle="aupda" @cha="cha"></atitle><acontent :content="newcontent" @del="del" @upda="upda"></acontent></div><script src="./node_modules/vue/dist/vue.js"></script><script>Vue.component('atitle', {props: ['aatitle'],data() {return {keyword: ''}},template: `<div>型號 <input type="text" v-model=aatitle.name>價格 <input type="text" v-model=aatitle.may @keyup.enter="tian"><button @click="tian">錄入</button><br><input type="text" v-model="keyword"></div>`,methods: {tian() {this.$emit('tian', this.aatitle.name, this.aatitle.may)this.aatitle.name = ''this.aatitle.may = ''}},watch: {keyword: {handler(newvalue) {this.$emit('cha', newvalue)},immediate: true}}})Vue.component('acontent', {props: ['content'],template: `<table><tr><th>編號</th><th>機型</th><th>價格</th><th>時間</th><th>操作</th></tr><tr v-show="this.content.length==0"><td colspan="5">沒有任何發(fā)布任何產(chǎn)品</td></tr><tr v-for="(item,index) in content"><td>{{item.id}}</td><td>{{item.name}}</td><td>{{item.may}}</td><td>{{item.time}}</td><td><a href="#"" @click.prevent="del(item.id)">刪除</a><a href="#"" @click.prevent='upda(item.id)'>編輯</a></td></tr></table>`,methods: {del(id) {this.$emit('del', id)},upda(id) {this.$emit('upda', id)}}})const app = new Vue({el: '#app',data: {newcontent: [],aupda: {},isup: false,upid: '',content: [{id: 1,name: '華為',may: 5000,time: Date.now()},{id: 2,name: '小米',may: 6000,time: Date.now()},{id: 3,name: '蘋果',may: 4500,time: Date.now()},{id: 4,name: '1+',may: 3000,time: Date.now()},{id: 5,name: 'oppo',may: 2000,time: Date.now()},{id: 6,name: '1+2',may: 8000,time: Date.now()},{id: 7,name: '1+3',may: 12000,time: Date.now()}]},methods: {del(id) {let index = this.content.findIndex(item => {return item.id == id})this.content.splice(index, 1)this.newcontent.splice(index, 1)},tian(name, may) {if (this.isup) {let a = this.content.find(item => {return item.id == this.upid})a.name = namea.may = may} else {let id = this.content.length - 1 < 0 ? 1 : this.content[this.content.length - 1].id + 1let content = {id: id,name: name,may: may,time: Date.now()}this.content.push(content)this.newcontent.push(content)}},cha(value) {this.newcontent = this.content.filter(item => {return item.name.includes(value)})},upda(id) {let a = this.content.find(item => {return item.id == id})this.aupda = {name: a.name,may: a.may}this.isup = truethis.upid = id}}})</script>
</body></html>
2.3 非父子之間的組件通訊
原理:
通過一個空的Vue實例來傳遞數(shù)據(jù)
const bus =new Vue()
核心邏輯:
組件A給組件B傳值:
組件A給bus注冊一個事件,監(jiān)聽事件的處理程序組件B觸發(fā)bus上對應的事件,把 值當成參數(shù)來傳遞組件A通過事件處理程序獲取數(shù)據(jù)
最終點擊h2控制臺會輸出2
創(chuàng)建1和2兩個非父子組件以及3空vue實例bus在1組件中 鉤子函數(shù)created中通過bus.$on為bus自定義一個事件aa在2組件中 當點擊h2元素時觸發(fā)dian函數(shù) 并且將值出過去在2組件的dian函數(shù)中通過bus.$emit方觸發(fā)1中的aa事件 并傳參過去當1中的aa事件被觸發(fā)時會執(zhí)行其中的函數(shù)并獲取參數(shù)
實例:
通過非父子組件 實現(xiàn)開關燈案例
關閉狀態(tài):
開啟狀態(tài):
代碼如下
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>#app {width: 500px;height: 500px;margin: 100px auto;}.box {height: 200px;width: 200px;margin: 0 auto;background-color: black;border-radius: 50%;}.below {height: 200px;width: 400px;margin: 50px auto;}button {margin-left: 66px;width: 100px;height: 40px;}.on {background-color: rgb(160, 184, 25);}</style>
</head><body><div id="app"><zss></zss><sgy></sgy></div><script src="./node_modules/vue/dist/vue.js"></script><script>const bus = new Vue()Vue.component('zss', {data() {return {attribute: "on",state: false}},created() {bus.$on('lamp', result => {this.state = result})},template: `<div class="box" :class="state?attribute:''"></div>`})Vue.component('sgy', {template: `<div class="below"><button @click="on">開燈</button><button @click="off">關閉</button></div>`,methods: {on() {bus.$emit('lamp', true)},off() {bus.$emit('lamp', false)}}})const app = new Vue({el: '#app',data: {}})</script>
</body></html>
總結
以上是生活随笔為你收集整理的五分钟带你摸透 Vue组件及组件通讯的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。