日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

vue-day03-vue组件化开发

發布時間:2024/7/19 vue 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vue-day03-vue组件化开发 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

      • 組件
      • 組件注冊
        • 全局注冊
          • 組件基礎用
          • 組件注意事項
        • 局部注冊
      • Vue 調試工具
      • Vue組件之間傳值
        • 父組件向子組件傳值
        • 子組件向父組件傳值
        • 兄弟之間的傳遞
      • 組件插槽
        • 匿名插槽
        • 具名插槽
        • 作用域插槽
      • 購物車案例
        • 1. 實現組件化布局
        • 2、實現 標題和結算功能組件
        • 3. 實現列表組件刪除功能
        • 4. 實現組件更新數據功能 上
        • 5. 實現組件更新數據功能 下

組件

  • 組件 (Component) 是 Vue.js 最強大的功能之一

  • 組件可以擴展 HTML 元素,封裝可重用的代

    /*

    組件注冊注意事項

    如果使用駝峰式命名組件,那么在使用組件的時候,只能在字符串模板中用駝峰的方式使用組件,但是

    在普通的標簽模板中,必須使用短橫線的方式使用組件

    */

組件注冊

全局注冊

  • Vue.component(‘組件名稱’, { }) 第1個參數是標簽名稱,第2個參數是一個選項對象
  • 全局組件注冊后,任何vue實例都可以用
組件基礎用
<div id="example"><!-- 2、 組件使用 組件名稱 是以HTML標簽的形式使用 --> <my-component></my-component> </div> <script>// 注冊組件 // 1、 my-component 就是組件中自定義的標簽名Vue.component('my-component', {template: '<div>A custom component!</div>'})// 創建根實例new Vue({el: '#example'})</script>
組件注意事項
  • 組件參數的data值必須是函數同時這個函數要求返回一個對象
  • 組件模板必須是單個根元素
  • 組件模板的內容可以是模板字符串
<div id="app"><!-- 4、 組件可以重復使用多次 因為data中返回的是一個對象所以每個組件中的數據是私有的即每個實例可以維護一份被返回對象的獨立的拷貝 --> <button-counter></button-counter><button-counter></button-counter><button-counter></button-counter><!-- 8、必須使用短橫線的方式使用組件 --><hello-world></hello-world></div><script type="text/javascript">//5 如果使用駝峰式命名組件,那么在使用組件的時候,只能在字符串模板中用駝峰的方式使用組件,// 7、但是在普通的標簽模板中,必須使用短橫線的方式使用組件Vue.component('HelloWorld', {data: function(){return {msg: 'HelloWorld'}},template: '<div>{{msg}}</div>'});Vue.component('button-counter', {// 1、組件參數的data值必須是函數 // 同時這個函數要求返回一個對象 data: function(){return {count: 0}},// 2、組件模板必須是單個根元素// 3、組件模板的內容可以是模板字符串 template: `<div><button @click="handle">點擊了{{count}}次</button><button>測試123</button># 6 在字符串模板中可以使用駝峰的方式使用組件 <HelloWorld></HelloWorld></div>`,methods: {handle: function(){this.count += 2;}}})var vm = new Vue({el: '#app',data: {}});</script>

局部注冊

/*

局部組件注冊

局部組件只能在注冊他的父組件中使用

*/

  • 只能在當前注冊它的vue實例中使用
<div id="app"><my-component></my-component></div><script>// 定義組件的模板var Child = {template: '<div>A custom component!</div>'}new Vue({//局部注冊組件 components: {// <my-component> 將只在父模板可用 一定要在實例上注冊了才能在html文件中使用'my-component': Child}})</script>

Vue 調試工具

Vue組件之間傳值

父組件向子組件傳值

  • 父組件發送的形式是以屬性的形式綁定值到子組件身上。
  • 然后子組件用屬性props接收
  • 在props中使用駝峰形式,模板中需要使用短橫線的形式字符串形式的模板中沒有這個限制
<div id="app"><div>{{pmsg}}</div><!--1、menu-item 在 APP中嵌套著 故 menu-item 為 子組件 --><!-- 給子組件傳入一個靜態的值 --><menu-item title='來自父組件的值'></menu-item><!-- 2、 需要動態的數據的時候 需要屬性綁定的形式設置 此時 ptitle 來自父組件data 中的數據 . 傳的值可以是數字、對象、數組等等--><menu-item :title='ptitle' content='hello'></menu-item></div><script type="text/javascript">Vue.component('menu-item', {// 3、 子組件用屬性props接收父組件傳遞過來的數據 props: ['title', 'content'],data: function() {return {msg: '子組件本身的數據'}},template: '<div>{{msg + "----" + title + "-----" + content}}</div>'});var vm = new Vue({el: '#app',data: {pmsg: '父組件中內容',ptitle: '動態綁定屬性'}});</script>

如果父組件向子組件中傳值,不用v-bind或者是:進行pp綁定,傳進去的都是字符串。

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title> </head> <body><div id="app"><div>{{pmsg}}</div><menu-item :pstr='pstr' :pnum='12' pboo='true' :parr='parr' :pobj='pobj'></menu-item></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript">/*父組件向子組件傳值-props屬性值類型*/Vue.component('menu-item', {props: ['pstr','pnum','pboo','parr','pobj'],template: `<div><div>{{pstr}}</div><div>{{12 + pnum}}</div><div>{{typeof pboo}}</div><ul><li :key='index' v-for='(item,index) in parr'>{{item}}</li></ul><span>{{pobj.name}}</span><span>{{pobj.age}}</span></div></div>`});var vm = new Vue({el: '#app',data: {pmsg: '父組件中內容',pstr: 'hello',parr: ['apple','orange','banana'],pobj: {name: 'lisi',age: 12}}});</script> </body> </html>

子組件向父組件傳值

/*

子組件向父組件傳值-基本用法

props傳遞數據原則:單向數據流

*/

  • 子組件用$emit()觸發事件
  • $emit() 第一個參數為 自定義的事件名稱 第二個參數為需要傳遞的數據
  • 父組件用v-on 監聽子組件的事件
<div id="app"><div :style='{fontSize: fontSize + "px"}'>{{pmsg}}</div><!-- 2 父組件用v-on 監聽子組件的事件這里 enlarge-text 是從 $emit 中的第一個參數對應 handle 為對應的事件處理函數 --> <menu-item :parr='parr' @enlarge-text='handle($event)'></menu-item></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript">/*子組件向父組件傳值-攜帶參數*/Vue.component('menu-item', {props: ['parr'],template: `<div><ul><li :key='index' v-for='(item,index) in parr'>{{item}}</li></ul>### 1、子組件用$emit()觸發事件### 第一個參數為 自定義的事件名稱 第二個參數為需要傳遞的數據 <button @click='$emit("enlarge-text", 5)'>擴大父組件中字體大小</button><button @click='$emit("enlarge-text", 10)'>擴大父組件中字體大小</button></div>`});var vm = new Vue({el: '#app',data: {pmsg: '父組件中內容',parr: ['apple','orange','banana'],fontSize: 10},methods: {handle: function(val){// 擴大字體大小this.fontSize += val;}}});</script>

兄弟之間的傳遞

  • 兄弟之間傳遞數據需要借助于事件中心,通過事件中心傳遞數據
    • 提供事件中心 var hub = new Vue()
  • 傳遞數據方,通過一個事件觸發hub.$emit(方法名,傳遞的數據)
  • 接收數據方,通過mounted(){} 鉤子中 觸發hub.$on()方法名
  • 銷毀事件 通過hub.$off()方法名銷毀之后無法進行傳遞數據
<div id="app"><div>父組件</div><div><button @click='handle'>銷毀事件</button></div><test-tom></test-tom><test-jerry></test-jerry></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript">/*兄弟組件之間數據傳遞*///1、 提供事件中心var hub = new Vue();Vue.component('test-tom', {data: function(){return {num: 0}},template: `<div><div>TOM:{{num}}</div><div><button @click='handle'>點擊</button></div></div>`,methods: {handle: function(){//2、傳遞數據方,通過一個事件觸發hub.$emit(方法名,傳遞的數據) 觸發兄弟組件的事件hub.$emit('jerry-event', 2);}},mounted: function() {// 3、接收數據方,通過mounted(){} 鉤子中 觸發hub.$on(方法名hub.$on('tom-event', (val) => {this.num += val;});}});Vue.component('test-jerry', {data: function(){return {num: 0}},template: `<div><div>JERRY:{{num}}</div><div><button @click='handle'>點擊</button></div></div>`,methods: {handle: function(){//2、傳遞數據方,通過一個事件觸發hub.$emit(方法名,傳遞的數據) 觸發兄弟組件的事件hub.$emit('tom-event', 1);}},mounted: function() {// 3、接收數據方,通過mounted(){} 鉤子中 觸發hub.$on()方法名hub.$on('jerry-event', (val) => {this.num += val;});}});var vm = new Vue({el: '#app',data: {},methods: {handle: function(){//4、銷毀事件 通過hub.$off()方法名銷毀之后無法進行傳遞數據 hub.$off('tom-event');hub.$off('jerry-event');}}});</script>

組件插槽

vue中slot理解,以及應用場景

Props傳值可以,但是無法傳遞dom節點,類似這種:

  • 組件的最大特性就是復用性,而用好插槽能大大提高組件的可復用能力

匿名插槽

<div id="app"><!-- 這里的所有組件標簽中嵌套的內容會替換掉slot 如果不傳值 則使用 slot 中的默認值 --> <alert-box>有bug發生</alert-box><alert-box>有一個警告</alert-box><alert-box></alert-box></div><script type="text/javascript">/*組件插槽:父組件向子組件傳遞內容*/Vue.component('alert-box', {template: `<div><strong>ERROR:</strong># 當組件渲染的時候,這個 <slot> 元素將會被替換為“組件標簽中嵌套的內容”。# 插槽內可以包含任何模板代碼,包括 HTML<slot>默認內容</slot></div>`});var vm = new Vue({el: '#app',data: {}});</script> </body> </html>

具名插槽

  • 具有名字的插槽
  • 使用 中的 “name” 屬性綁定元素
<div id="app"><base-layout><!-- 2、 通過slot屬性來指定, 這個slot的值必須和下面slot組件得name值對應上如果沒有匹配到 則放到匿名的插槽中 --> <p slot='header'>標題信息</p><p>主要內容1</p><p>主要內容2</p><p slot='footer'>底部信息信息</p></base-layout><base-layout><!-- 注意點:template臨時的包裹標簽最終不會渲染到頁面上 --> <template slot='header'><p>標題信息1</p><p>標題信息2</p></template><p>主要內容1</p><p>主要內容2</p><template slot='footer'><p>底部信息信息1</p><p>底部信息信息2</p></template></base-layout></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript">/*具名插槽*/Vue.component('base-layout', {template: `<div><header>### 1、 使用 <slot> 中的 "name" 屬性綁定元素 指定當前插槽的名字<slot name='header'></slot></header><main><slot></slot></main><footer>### 注意點: ### 具名插槽的渲染順序,完全取決于模板,而不是取決于父組件中元素的順序<slot name='footer'></slot></footer></div>`});var vm = new Vue({el: '#app',data: {}});</script> </body> </html>

作用域插槽

  • 父組件對子組件加工處理
  • 既可以復用子組件的slot,又可以使slot內容不一致
<div id="app"><!-- 1、當我們希望li 的樣式由外部使用組件的地方定義,因為可能有多種地方要使用該組件,但樣式希望不一樣 這個時候我們需要使用作用域插槽 --> <fruit-list :list='list'><!-- 2、 父組件中使用了<template>元素,而且包含scope="slotProps",slotProps在這里只是臨時變量 ---> <template slot-scope='slotProps'><strong v-if='slotProps.info.id==3' class="current">{{slotProps.info.name}} </strong><span v-else>{{slotProps.info.name}}</span></template></fruit-list></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript">/*作用域插槽*/Vue.component('fruit-list', {props: ['list'],template: `<div><li :key='item.id' v-for='item in list'>### 3、 在子組件模板中,<slot>元素上有一個類似props傳遞數據給組件的寫法msg="xxx",### 插槽可以提供一個默認內容,如果如果父組件沒有為這個插槽提供了內容,會顯示默認的內容。如果父組件為這個插槽提供了內容,則默認的內容會被替換掉<slot :info='item'>{{item.name}}</slot></li></div>`});var vm = new Vue({el: '#app',data: {list: [{id: 1,name: 'apple'},{id: 2,name: 'orange'},{id: 3,name: 'banana'}]}});</script> </body> </html>

購物車案例

1. 實現組件化布局

  • 把靜態頁面轉換成組件化模式
  • 把組件渲染到頁面上
<div id="app"><div class="container"><!-- 2、把組件渲染到頁面上 --> <my-cart></my-cart></div></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript"># 1、 把靜態頁面轉換成組件化模式# 1.1 標題組件 var CartTitle = {template: `<div class="title">我的商品</div>`}# 1.2 商品列表組件 var CartList = {# 注意點 : 組件模板必須是單個根元素 template: `<div><div class="item"><img src="img/a.jpg"/><div class="name"></div><div class="change"><a href="">-</a><input type="text" class="num" /><a href="">+</a></div><div class="del">×</div></div><div class="item"><img src="img/b.jpg"/><div class="name"></div><div class="change"><a href="">-</a><input type="text" class="num" /><a href="">+</a></div><div class="del">×</div></div><div class="item"><img src="img/c.jpg"/><div class="name"></div><div class="change"><a href="">-</a><input type="text" class="num" /><a href="">+</a></div><div class="del">×</div></div><div class="item"><img src="img/d.jpg"/><div class="name"></div><div class="change"><a href="">-</a><input type="text" class="num" /><a href="">+</a></div><div class="del">×</div></div><div class="item"><img src="img/e.jpg"/><div class="name"></div><div class="change"><a href="">-</a><input type="text" class="num" /><a href="">+</a></div><div class="del">×</div></div></div>`}# 1.3 商品結算組件 var CartTotal = {template: `<div class="total"><span>總價:123</span><button>結算</button></div>`}## 1.4 定義一個全局組件 my-cartVue.component('my-cart',{## 1.6 引入子組件 template: `<div class='cart'><cart-title></cart-title><cart-list></cart-list><cart-total></cart-total></div>`,# 1.5 注冊子組件 components: {'cart-title': CartTitle,'cart-list': CartList,'cart-total': CartTotal}});var vm = new Vue({el: '#app',data: {}});</script>

2、實現 標題和結算功能組件

  • 標題組件實現動態渲染
    • 從父組件把標題數據傳遞過來 即 父向子組件傳值
    • 把傳遞過來的數據渲染到頁面上
  • 結算功能組件
    • 從父組件把商品列表list 數據傳遞過來 即 父向子組件傳值
    • 把傳遞過來的數據計算最終價格渲染到頁面上
<div id="app"><div class="container"><my-cart></my-cart></div></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript"># 2.2 標題組件 子組件通過props形式接收父組件傳遞過來的uname數據var CartTitle = {props: ['uname'],template: `<div class="title">{{uname}}的商品</div>`}# 2.3 商品結算組件 子組件通過props形式接收父組件傳遞過來的list數據 var CartTotal = {props: ['list'],template: `<div class="total"><span>總價:{{total}}</span><button>結算</button></div>`,computed: {# 2.4 計算商品的總價 并渲染到頁面上 total: function() {var t = 0;this.list.forEach(item => {t += item.price * item.num;});return t;}}}Vue.component('my-cart',{data: function() {return {uname: '張三',list: [{id: 1,name: 'TCL彩電',price: 1000,num: 1,img: 'img/a.jpg'},{id: 2,name: '機頂盒',price: 1000,num: 1,img: 'img/b.jpg'},{id: 3,name: '海爾冰箱',price: 1000,num: 1,img: 'img/c.jpg'},{id: 4,name: '小米手機',price: 1000,num: 1,img: 'img/d.jpg'},{id: 5,name: 'PPTV電視',price: 1000,num: 2,img: 'img/e.jpg'}]}},# 2.1 父組件向子組件以屬性傳遞的形式 傳遞數據# 向 標題組件傳遞 uname 屬性 向 商品結算組件傳遞 list 屬性 template: `<div class='cart'><cart-title :uname='uname'></cart-title><cart-list></cart-list><cart-total :list='list'></cart-total></div>`,components: {'cart-title': CartTitle,'cart-list': CartList,'cart-total': CartTotal}});var vm = new Vue({el: '#app',data: {}});</script>

3. 實現列表組件刪除功能

  • 從父組件把商品列表list 數據傳遞過來 即 父向子組件傳值
  • 把傳遞過來的數據渲染到頁面上
  • 點擊刪除按鈕的時候刪除對應的數據
    • 給按鈕添加點擊事件把需要刪除的id傳遞過來
      • 子組件中不推薦操作父組件的數據有可能多個子組件使用父組件的數據 我們需要把數據傳遞給父組件讓父組件操作數據
      • 父組件刪除對應的數據
<div id="app"><div class="container"><my-cart></my-cart></div></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript">var CartTitle = {props: ['uname'],template: `<div class="title">{{uname}}的商品</div>`}# 3.2 把列表數據動態渲染到頁面上 var CartList = {props: ['list'],template: `<div><div :key='item.id' v-for='item in list' class="item"><img :src="item.img"/><div class="name">{{item.name}}</div><div class="change"><a href="">-</a><input type="text" class="num" /><a href="">+</a></div># 3.3 給按鈕添加點擊事件把需要刪除的id傳遞過來<div class="del" @click='del(item.id)'>×</div></div></div>`,methods: {del: function(id){# 3.4 子組件中不推薦操作父組件的數據有可能多個子組件使用父組件的數據 # 我們需要把數據傳遞給父組件 讓父組件操作數據 this.$emit('cart-del', id);}}}var CartTotal = {props: ['list'],template: `<div class="total"><span>總價:{{total}}</span><button>結算</button></div>`,computed: {total: function() {// 計算商品的總價var t = 0;this.list.forEach(item => {t += item.price * item.num;});return t;}}}Vue.component('my-cart',{data: function() {return {uname: '張三',list: [{id: 1,name: 'TCL彩電',price: 1000,num: 1,img: 'img/a.jpg'},{id: 2,name: '機頂盒',price: 1000,num: 1,img: 'img/b.jpg'},{id: 3,name: '海爾冰箱',price: 1000,num: 1,img: 'img/c.jpg'},{id: 4,name: '小米手機',price: 1000,num: 1,img: 'img/d.jpg'},{id: 5,name: 'PPTV電視',price: 1000,num: 2,img: 'img/e.jpg'}]}},# 3.1 從父組件把商品列表list 數據傳遞過來 即 父向子組件傳值 template: `<div class='cart'><cart-title :uname='uname'></cart-title># 3.5 父組件通過事件綁定 接收子組件傳遞過來的數據 <cart-list :list='list' @cart-del='delCart($event)'></cart-list><cart-total :list='list'></cart-total></div>`,components: {'cart-title': CartTitle,'cart-list': CartList,'cart-total': CartTotal},methods: {# 3.6 根據id刪除list中對應的數據 delCart: function(id) {// 1、找到id所對應數據的索引var index = this.list.findIndex(item=>{return item.id == id;});// 2、根據索引刪除對應數據this.list.splice(index, 1);}}});var vm = new Vue({el: '#app',data: {}});</script> </body> </html>

4. 實現組件更新數據功能 上

  • 將輸入框中的默認數據動態渲染出來
  • 輸入框失去焦點的時候 更改商品的數量
  • 子組件中不推薦操作數據 把這些數據傳遞給父組件 讓父組件處理這些數據
  • 父組件中接收子組件傳遞過來的數據并處理
<div id="app"><div class="container"><my-cart></my-cart></div></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript">var CartTitle = {props: ['uname'],template: `<div class="title">{{uname}}的商品</div>`}var CartList = {props: ['list'],template: `<div><div :key='item.id' v-for='item in list' class="item"><img :src="item.img"/><div class="name">{{item.name}}</div><div class="change"><a href="">-</a># 1. 將輸入框中的默認數據動態渲染出來# 2. 輸入框失去焦點的時候 更改商品的數量 需要將當前商品的id 傳遞過來<input type="text" class="num" :value='item.num' @blur='changeNum(item.id, $event)'/><a href="">+</a></div><div class="del" @click='del(item.id)'>×</div></div></div>`,methods: {changeNum: function(id, event){# 3 子組件中不推薦操作數據 因為別的組件可能也引用了這些數據# 把這些數據傳遞給父組件 讓父組件處理這些數據this.$emit('change-num', {id: id,num: event.target.value});},del: function(id){// 把id傳遞給父組件this.$emit('cart-del', id);}}}var CartTotal = {props: ['list'],template: `<div class="total"><span>總價:{{total}}</span><button>結算</button></div>`,computed: {total: function() {// 計算商品的總價var t = 0;this.list.forEach(item => {t += item.price * item.num;});return t;}}}Vue.component('my-cart',{data: function() {return {uname: '張三',list: [{id: 1,name: 'TCL彩電',price: 1000,num: 1,img: 'img/a.jpg'}]},template: `<div class='cart'><cart-title :uname='uname'></cart-title># 4 父組件中接收子組件傳遞過來的數據 <cart-list :list='list' @change-num='changeNum($event)' @cart-del='delCart($event)'></cart-list><cart-total :list='list'></cart-total></div>`,components: {'cart-title': CartTitle,'cart-list': CartList,'cart-total': CartTotal},methods: {changeNum: function(val) {//4.1 根據子組件傳遞過來的數據,跟新list中對應的數據this.list.some(item=>{if(item.id == val.id) {item.num = val.num;// 終止遍歷return true;}});},delCart: function(id) {// 根據id刪除list中對應的數據// 1、找到id所對應數據的索引var index = this.list.findIndex(item=>{return item.id == id;});// 2、根據索引刪除對應數據this.list.splice(index, 1);}}});var vm = new Vue({el: '#app',data: {}});</script>

5. 實現組件更新數據功能 下

  • 子組件通過一個標識符來標記對用的用戶點擊 + - 或者輸入框輸入的內容
  • 父組件拿到標識符更新對應的組件
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title><style type="text/css">.container {}.container .cart {width: 300px;margin: auto;}.container .title {background-color: lightblue;height: 40px;line-height: 40px;text-align: center;/*color: #fff;*/ }.container .total {background-color: #FFCE46;height: 50px;line-height: 50px;text-align: right;}.container .total button {margin: 0 10px;background-color: #DC4C40;height: 35px;width: 80px;border: 0;}.container .total span {color: red;font-weight: bold;}.container .item {height: 55px;line-height: 55px;position: relative;border-top: 1px solid #ADD8E6;}.container .item img {width: 45px;height: 45px;margin: 5px;}.container .item .name {position: absolute;width: 90px;top: 0;left: 55px;font-size: 16px;}.container .item .change {width: 100px;position: absolute;top: 0;right: 50px;}.container .item .change a {font-size: 20px;width: 30px;text-decoration:none;background-color: lightgray;vertical-align: middle;}.container .item .change .num {width: 40px;height: 25px;}.container .item .del {position: absolute;top: 0;right: 0px;width: 40px;text-align: center;font-size: 40px;cursor: pointer;color: red;}.container .item .del:hover {background-color: orange;}</style> </head> <body><div id="app"><div class="container"><my-cart></my-cart></div></div><script type="text/javascript" src="js/vue.js"></script><script type="text/javascript">var CartTitle = {props: ['uname'],template: `<div class="title">{{uname}}的商品</div>`}var CartList = {props: ['list'],template: `<div><div :key='item.id' v-for='item in list' class="item"><img :src="item.img"/><div class="name">{{item.name}}</div><div class="change"># 1. + - 按鈕綁定事件 <a href="" @click.prevent='sub(item.id)'>-</a><input type="text" class="num" :value='item.num' @blur='changeNum(item.id, $event)'/><a href="" @click.prevent='add(item.id)'>+</a></div><div class="del" @click='del(item.id)'>×</div></div></div>`,methods: {changeNum: function(id, event){this.$emit('change-num', {id: id,type: 'change',num: event.target.value});},sub: function(id){# 2 數量的增加和減少通過父組件來計算 每次都是加1 和 減1 不需要傳遞數量 父組件需要一個類型來判斷 是 加一 還是減1 以及是輸入框輸入的數據 我們通過type 標識符來標記 不同的操作 this.$emit('change-num', {id: id,type: 'sub'});},add: function(id){# 2 數量的增加和減少通過父組件來計算 每次都是加1 和 減1 不需要傳遞數量 父組件需要一個類型來判斷 是 加一 還是減1 以及是輸入框輸入的數據 我們通過type 標識符來標記 不同的操作this.$emit('change-num', {id: id,type: 'add'});},del: function(id){// 把id傳遞給父組件this.$emit('cart-del', id);}}}var CartTotal = {props: ['list'],template: `<div class="total"><span>總價:{{total}}</span><button>結算</button></div>`,computed: {total: function() {// 計算商品的總價var t = 0;this.list.forEach(item => {t += item.price * item.num;});return t;}}}Vue.component('my-cart',{data: function() {return {uname: '張三',list: [{id: 1,name: 'TCL彩電',price: 1000,num: 1,img: 'img/a.jpg'},{id: 2,name: '機頂盒',price: 1000,num: 1,img: 'img/b.jpg'},{id: 3,name: '海爾冰箱',price: 1000,num: 1,img: 'img/c.jpg'},{id: 4,name: '小米手機',price: 1000,num: 1,img: 'img/d.jpg'},{id: 5,name: 'PPTV電視',price: 1000,num: 2,img: 'img/e.jpg'}]}},template: `<div class='cart'><cart-title :uname='uname'></cart-title> # 3 父組件通過事件監聽 接收子組件的數據 <cart-list :list='list' @change-num='changeNum($event)' @cart-del='delCart($event)'></cart-list><cart-total :list='list'></cart-total></div>`,components: {'cart-title': CartTitle,'cart-list': CartList,'cart-total': CartTotal},methods: {changeNum: function(val) {#4 分為三種情況:輸入框變更、加號變更、減號變更if(val.type=='change') {// 根據子組件傳遞過來的數據,跟新list中對應的數據this.list.some(item=>{if(item.id == val.id) {item.num = val.num;// 終止遍歷return true;}});}else if(val.type=='sub'){// 減一操作this.list.some(item=>{if(item.id == val.id) {item.num -= 1;// 終止遍歷return true;}});}else if(val.type=='add'){// 加一操作this.list.some(item=>{if(item.id == val.id) {item.num += 1;// 終止遍歷return true;}});}}}});var vm = new Vue({el: '#app',data: {}});</script> </body> </html>

總結

以上是生活随笔為你收集整理的vue-day03-vue组件化开发的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。