文章目錄
- 前言
- 組件化開發
- 底部菜單 TabMenu
- 父子組件相互傳數據
- 父傳子:自定義屬性
- 子傳父:自定義事件
- 父子組件互傳案例
- 插槽 slot
- 多個插槽
- 總結
- 組件化開發總結
- Vue組件的基本組成
- 子組件使用的三個步驟
- 父子組件相互傳遞數據
前言
提示:這里可以添加本文要記錄的大概內容:
Vue.js 是一種現代化的前端框架,可以用于構建可復用的組件化應用程序。Vue.js 提供了一種基于組件的架構,使得開發人員可以將應用程序分解為多個可重用的組件。
Vue.js 組件是一個可復用的代碼模塊,可以在 Vue.js 應用程序中使用。組件包括 HTML 模板、JavaScript 代碼和 CSS 樣式,并且可以包含其他組件。
Vue.js 組件化開發的主要優勢包括:
-
模塊化:Vue.js 組件使得應用程序變得更易于管理和維護,可以將應用程序分解為多個小模塊,每個模塊都有自己的功能和樣式。
-
可重用性:組件化開發使得開發人員可以編寫可重用的代碼片段,可以在不同的項目中使用,并且可以在同一應用程序中多次使用。
-
維護性:組件化開發使得代碼更加模塊化,更易于維護和測試。
-
性能:在 Vue.js 中使用組件可以提高應用程序的性能,因為它可以在需要時延遲加載組件。
總之,Vue.js 組件化開發是一種高效的方式,可以幫助開發人員構建可維護和可重用的應用程序。
提示:以下是本篇文章正文內容,下面案例可供參考
組件化開發
首先Ctrl+c
停止上面項目訪問,新建一個項目
cd ..
:返回上一級
接下來就是把【創建Vue-Cli工程】的過程再來一遍:
完整過程:
- 新建文件夾【vue create 小寫名字】:
vue create component
。component(組件化開發) - 選擇最后一個:
Manually select features
- 空格去掉倒數第三個:
( * ) Linter / Formatter
- 默認選擇3.x
- 選擇倒數第二個:
In package.json
- 不保存:
n
出現Successfully代表創建成功
打開項目,進行一些默認操作:
①、用腳手架創建項目時,把腳手架生成的代碼刪除掉
②、刪除App.vue內所有代碼,隨后輸入vue
選擇第一個
在template標簽中加代碼:
<h1>{{ title }}</h1>
在script標簽中的data函數的返回對象加代碼:
title:'我是根組件'
打開終端輸入:npm run serve
,就可以運行了
在components文件夾下新建個子組件TabMenu.vue,名字是駝峰式命名
生成基本結構,輸入vue回車,加點代碼與樣式,這里可以隨便寫,主要是展示子組件的使用
現在一個根組件(App.vue),一個子組件(TabMenu.vue),運行:
那么如何在根組件中使用子組件呢?
底部菜單 TabMenu
以App.vue根組件,TabMenu.vue子組件為例:
- 導入需要的子組件(在script標簽內)
import TabMenu from '@/components/TabMenu.vue'; //@相當于src
或者寫成:
import TabMenu from '../components/TabMenu.vue';
當然需要在components 文件夾下新建 TabMenu 視圖:
詳細代碼:
<!-- 定義組件的模板 -->
<template><div><!-- 底部選項卡 --><ul class="tab-menu"><!-- 首頁選項 --><li @click="gotoIndex"><i class="fa fa-home"></i><p>首頁</p></li><!-- 發現選項 --><li @click="gotoBusiness"><i class="fa fa-compass"></i><p>發現</p></li><!-- 訂單選項 --><li @click="gotoMyOrders"><i class="fa fa-file-text-o"></i><p>訂單</p></li><!-- 我的選項 --><li @click="gotoMy"><i class="fa fa-user-o"></i><p>我的</p></li></ul></div>
</template><script>
// 引入路由
import router from '@/router';export default {data() {return {}},methods: {// 跳轉到首頁gotoIndex() {router.push('/')},// 跳轉到個人中心gotoMy() {// 判斷是否登錄let login = sessionStorage.getItem('login')if (login == null) {// 未登錄則跳轉到登錄頁router.push('/login')} else{// 已登錄則跳轉到個人中心頁router.push('/my')}},// 跳轉到發現頁gotoBusiness() {router.push('/business')},// 跳轉到我的訂單頁gotoMyOrders() {router.push('/myOrders')}},components: {},computed: {},watch: {},mounted() {},
}
</script><style scoped>/* 底部選項卡樣式 */.tab-menu{width: 100vw; /* 設置選項卡寬度為屏幕寬度 */height: 14vw; /* 設置選項卡高度為14vw */background-color: #fff; /* 設置選項卡背景色為白色 */border-top: 0.2vw solid #ddd; /* 設置選項卡上邊框為0.2vw寬的灰色實線 */display: flex; /* 設置選項卡為彈性布局 */justify-content: space-around; /* 設置選項卡內子元素沿主軸間距相等 */align-items: center; /* 設置選項卡內子元素沿側軸居中對齊 */position: fixed; /* 設置選項卡為固定定位 */left: 0; /* 設置選項卡距離左側為0 */bottom: 0; /* 設置選項卡距離底部為0 */}/* 選項樣式 */.tab-menu li{display: flex; /* 設置選項為彈性布局 */flex-direction: column; /* 設置選項內子元素排列方向為垂直方向 */justify-content: center; /* 設置選項內子元素沿主軸居中對齊 */align-items: center; /* 設置選項內子元素沿側軸居中對齊 */color: #999; /* 設置選項內子元素顏色為灰色 */}
</style>
- 在 components 的配置項中注冊子組件
components: {TabMenu},
- 在template中以標記的語法使用子組件
<TabMenu></TabMenu>
當然在命令行中運行上這句:npm i font-awesome
效果:
父子組件相互傳數據
在父子組件中如何讓他倆可以相互發數據?
以App.vue根組件,Data.vue子組件為例:
父傳子:自定義屬性
先寫先接受數據的一方
- 父給子傳數據,先給子組件里面增加一個新個配置項
props
,自定義屬性的意思
在components
文件中新建子組件Data.vue(script標簽內)
vue生成基本結構后,增加props
配置項
// 數組形式,里面自定義名字props: ['test']
- 在template標簽內加上插值語法把上面的自定義名字加上去
<template><div><h1>數據子組件</h1><h1>這是父組件傳遞給我的數據:{{ test }}</h1></div>
</template>
- 在父組件中再導入該子組件(在script標簽內)
import Data from '@/components/Data.vue'
- 在components的配置項中注冊子組件
components: {TabMenu,Data}, //TabMenu是另一個子組件,多個子組件用逗號隔開
- 在template中以標記的語法使用子組件
<Data></Data>
父組件App.vue中完整代碼:
<template><div><h1>{{ title }}</h1><!-- 3.在template中以標記的語法使用子組件 --><TabMenu></TabMenu><Data></Data></div>
</template><script>
// 1.導入需要的子組件
import TabMenu from '@/components/TabMenu.vue';
import Data from '@/components/Data.vue'
export default {data () {return {title:'我是根組件'}},methods: {},//2.在components的配置項中注冊子組件components: {TabMenu,Data}, //TabMenu是另一個子組件,多個子組件用逗號隔開computed: {},watch: {},mounted () {}
}
</script>
<style scoped>
</style>
輸出效果:
但是現在里面還沒有數據,因為在Data.vue中test是自定義屬性
- 接下來在父組件中加入自定義屬性:
<Data test="你好啊"></Data>
如果說要在子組件里再定義一個屬性,父組件再傳一個,只需要在相應位置加上屬性后用逗號隔開即可
子組件中:
父組件中:
子傳父:自定義事件
recive()
:接收子給父傳上來的數據,有參,代表傳來的數據
在父組件中:
- 自定義一個事件,這里取名abc
<Data test="你好啊" test1="世界" @abc = "recive"></Data>
- 在methods配置項中定義recive()函數方法
methods: {recive(d){// d:代表子給父發的數據this.title = d //更改title值}},
子組件中:
-
在子組件中編寫一個函數,加入一個事件:
-
給v-model的屬性tes在data函數的return里面配置一下
-
methods內加上send方法
send(){this.$emit('abc',this.text)//this.$emit('在父組件中配置的事件名字',this.發送給父組件的數據)}
最后輸出:
父子組件互傳案例
一個App父組件
兩個子組件:一個添加待辦事項組件、一個待辦列表組件
如果之前有項目在終端開著先Ctrl+c關掉
然后新建一個待辦項目:vue create todo
,然后依次回車選擇配置選項
然后進入到 todo 項目中,刪掉HelloWorld.vue文件 和 App.vue中所有代碼(輸入vue重新生成)
在components文件夾中創建新子組件AddItem.vue 和 List.vue
在父組件中使用子組件:
- 導入需要的子組件
- 在 components 的配置項中注冊子組件
- 在 template 中以標記的語法使用子組件
目前為止父組件中代碼:
<template><div><h1>待辦事項</h1><!-- 3.使用 --><AddItem></AddItem><List></List></div>
</template><script>
// 1. 導入
import AddItem from '@/components/AddItem.vue';
import List from '@/components/List.vue';
export default {data () {return {}},methods: {},// 2.注冊components: {AddItem,List},computed: {},watch: {},mounted () {}
}
</script>
<style scoped>
</style>
接下來先把List待辦列表弄出來再寫待辦事項,也就是寫個父給子的數據傳遞
增加自定義的屬性,使用 v-for
指令對 todolist
進行循環渲染,將 todolist
中的每個元素都顯示為一個有序列表中的一條,{{ item }}
則是將前面 item
變量名插入到模板中進行渲染。
由于本組件需要從父組件中接收一個名為 todolist 的屬性,所以使用 props
選項來聲明了一個具名的 todolist
屬性
最后加了點CSS樣式
下面是完整的 List.vue 代碼:
<template><div><ul><!-- 使用 v-for 指令遍歷傳入的 todolist 數據,生成 li 列表項 --><li v-for="(item, index) in todolist" :key="index">{{ item }}</li><!-- 2.使用插值語法把上面的自定義名字加上去 --></ul></div>
</template><script>
export default {// 1.定義一個 props 屬性,接收父組件傳遞的 todolist 數據 (自定義的屬性)props: ['todolist']
}
</script><style scoped>
/* 為 ul 列表設置樣式 */
ul {list-style: none; /* 取消列表項的默認樣式 */margin: 0; /* 去除外邊距 */padding: 0; /* 去除內邊距 */display: flex; /* 將列表項設為彈性項目 */flex-wrap: wrap; /* 當空間不足時,自動換行 */
}/* 為 li 列表項設置樣式 */
li {font-size: 1.2rem; /* 設置字體大小 */color: #333; /* 設置字體顏色 */background-color: #f5f5f5; /* 設置背景顏色 */border-radius: 5px; /* 設置圓角 */margin: 0.5rem; /* 設置外邊距 */padding: 1rem; /* 設置內邊距 */box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 0 12px rgba(0, 0, 0, 0.1); /* 設置陰影 */text-align: center; /* 設置文本居中 */transition: transform 0.2s cubic-bezier(0, 0, 0.2, 1), box-shadow 0.2s cubic-bezier(0, 0, 0.2, 1); /* 設置過渡效果 */
}/* 當鼠標懸停在 li 列表項上時的樣式 */
li:hover {transform: translateY(-5px);box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2), 0 0 12px rgba(0, 0, 0, 0.2);
}
</style>
第一步:在父組件data
中把待辦事項的數據定義出來
data () {return {items: ['學習','做事','賺錢']// a.把items數據傳給list組件去用,用屬性todolist去傳}},
第二步:用list組件動態綁定items數據
<List :todolist="items"></List>
最后父組件中完整代碼:
<template><div><h1>待辦事項</h1><!-- 3.使用 --><AddItem></AddItem><!-- b.list組件 加上冒號是動態綁定items數據--><List :todolist="items"></List></div>
</template><script>
// 1. 導入
import AddItem from '@/components/AddItem.vue';
import List from '@/components/List.vue';
export default {data () {return {items: ['學習','做事','賺錢']// a.把items數據傳給list組件去用,用屬性todolist去傳}},methods: {},// 2.注冊components: {AddItem,List},computed: {},watch: {},mounted () {}
}
</script>
<style scoped>
</style>
現在打開終端進入該項目路徑下啟動該項目:npm run serve
啟動后運行
接下來是子給父傳數據
第一步:加上自定義事件
第二步:放在methods
,接受要帶參數
<!-- 第一步:自定義事件 -->
<AddItem @item="recive"></AddItem>
...
//中間代碼勝率
...methods: {// 第二步:放在methods,接受的話要帶參數recive(d){this.items.unshift(d) }},
父組件中完整代碼是:
<template><div><h1>待辦事項</h1><!-- 3.使用 --><!-- 第一步:自定義事件 --><AddItem @item="recive"></AddItem> <!-- b.list組件 加上冒號是動態綁定items數據--><List :todolist="items"></List></div>
</template><script>
// 1. 導入
import AddItem from '@/components/AddItem.vue';
import List from '@/components/List.vue';
export default {data () {return {items: ['學習','做事','賺錢']// a.把items數據傳給list組件去用,用屬性todolist去傳}},methods: {// 第二步:放在methods,接受的話要帶參數recive(d){this.items.unshift(d) }},// 2.注冊components: {AddItem,List},computed: {},watch: {},mounted () {}
}
</script>
<style scoped>
</style>
下一步到子組件AddItem.vue里面
1:在里面加一個輸入框和按鈕
<input type="text" v-model="item"><button @click="send">添加</button>
2:data里面配數據
data () {return {item: ''}},
3:在methods里把數據發送給父組件
methods: {send(){this.$emit('item,this.item')}},
然后在給css內加點樣式
最后AddItem.vue完整代碼
<template><div class="input-container"> <!-- 輸入框容器 --><input type="text" v-model="item" placeholder="輸入待辦事項" class="input-field"> <!-- 輸入框 --><button @click="send" class="add-btn">添加</button> <!-- 添加按鈕 --></div>
</template><script>
export default {data () {return {item: '' // 輸入框綁定的數據}},methods: {send(){this.$emit('item',this.item) // 發出事件,傳遞輸入框數據}},
}
</script><style scoped>
.input-container { /* 輸入框容器樣式 */display: flex; /* flex 布局 */align-items: center; /* 垂直居中 */margin-bottom: 20px; /* 底部外邊距 */
}.input-field { /* 輸入框樣式 */border: none; /* 取消邊框 */border-bottom: 2px solid #aaa; /* 底部邊框 */padding: 0.5rem; /* 內邊距 */margin-right: 1rem; /* 右外邊距 */font-size: 1rem; /* 字體大小 */font-family: Arial, sans-serif; /* 字體樣式 */width: 300px; /* 寬度 */
}.add-btn { /* 添加按鈕樣式 */background-color: #20A3FF; /* 背景顏色 */border: none; /* 取消邊框 */color: white; /* 字體顏色 */padding: 0.5rem; /* 內邊距 */border-radius: 5px; /* 圓角 */cursor: pointer; /* 鼠標樣式 */transition: all 0.3s ease; /* 過渡效果 */box-shadow: 0 2px 3px rgba(0, 0, 0, 0.3); /* 陰影 */
}.add-btn:hover { /* 鼠標懸停樣式 */background-color: #2186e2;transform: translateY(-2px); /* 上移 */box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3); /* 增加陰影 */
}.input-field:focus { /* 輸入框獲得焦點時的樣式 */outline: none; /* 取消選中時的邊框 */border-bottom: 2px solid #2186e2; /* 底部邊框顏色更改 */
}
</style>
輸出效果:
插槽 slot
新建子組件Slot.vue,用vue生成格式后在HTML位置輸入
<template><div><h1>我是插槽子組件</h1><!-- 插槽位置 --><slot></slot></div>
</template>
在父組件App.vue中在相應位置進行導入、注冊、使用(可以新建一個項目,看起來更直觀)
import Slot from '@/components/Slot.vue';components: {Slot},<Slot><h1>你好</h1><!-- 將會顯示在子組件的Slot插槽位置上 --></Slot>
運行項目:
多個插槽
通過名字區分
比如在子組件中再加一個slot
標簽加個名字
<slot name="a"></slot>
在父組件中加上template v-slot:a
<Slot><!-- 將會顯示在子組件的Slot插槽位置上 --><h1>你好</h1><!-- 通過名字單獨指令子組件的Slot插槽位置 --><template v-slot:a><h2>hello</h2></template></Slot>
另外在 css 位置加了點樣式(可以忽略)
總結
組件化開發總結
Vue組件的基本組成
- template——模版 html代碼
- script——腳本 vue配置對象中的各種配置項
- style——樣式 css代碼
子組件使用的三個步驟
- 在父組件中導入所需子組件
- 在父組件的配置對象中的components配置項中注冊子組件
- 在父組件的template中以標記的語法使用子組件
父子組件相互傳遞數據
-
父傳子
a.在子組件配置對象中增加props配置項(自定義屬性)
b.在父組件使用子組件時通過自定義的屬性名傳數據 -
子傳父
a.在父組件中增加自定義事件,并編寫接受數據的方法 【@item=“recive”】
b.在子組件中增加一個發送數據的方法,調用this.$emit(‘自定義的事件名’,發送的數據)
那么如何在根組件中使用子組件呢?
以App.vue根組件,TabMenu.vue子組件為例:
- 導入需要的子組件(在script標簽內)
import TabMenu from '@/components/TabMenu.vue'; //@相當于src
- 在components的配置項中注冊子組件
components: {TabMenu},
- 在template中以標記的語法使用子組件
<TabMenu></TabMenu>