Vue組件
組件的構成
一個.vue文件就是一個組件
組件都是由三部分組成:html結構(html結構都是在template標簽中)、js邏輯、css樣式
- 1)template只能解析一個根標簽
- 2)js邏輯都是在script標簽中,必須設置導出,export default {...}
- 3)css樣式都是在style標簽中,必須設置scoped屬性,是樣式組件化
<template> <div class="first-cp"> <h1>第一個組件</h1> </div> </template> <script> // .vue文件類似於模塊,可以直接相互導入,所以在組件內部要設置導出 export default { } </script> <style scoped> /* scoped可以使樣式組件化,只在自己內部起作用 */ </style>
根組件占位渲染頁面組件
<!-- 1) App.vue是項目的根組件,是唯一由main.js加載渲染的組件,就是替換index頁面中的<div id="app"></div>的占位標簽 2) 實際開發中App.vue文件中,只需要書寫下方五行代碼即可(可以在此基礎上額外增加其他代碼) 3)router-view是前台路由占位標簽,由router插件控制,可以在router的配置文件中進行配置 4) router-view就是根據router在index.js中配置的路由關系,完成指定路徑匹配指定頁面組件,進行渲染 5) router-view會被不同的頁面組件替換,就形成了頁面跳轉 --> <template> <div id="app"> <!-- 前台路由占位標簽,末尾的/代表單標簽的結束 --> <router-view /> </div> </template>
"""
1)不管是頁面組件還是小組件,都可能會被多次復用
2)復用組件,其實就是復用組件的 頁面結構、頁面樣式、頁面邏輯
3)但是頁面上的數據需要區分(被復用的兩個組件數據多少是有區別的),所以組件的數據要做局部化處理
4)借助函數可以產生局部作用域的特點,為每一次復用組件產生一個獨立的作用域
語法:
data () {
return {
// 數據們
}
}
"""
子組件
<template> <div class="beat" @click="count += 1"> {{ count }}下 </div> </template> <script> export default { name: "Beat", // 不管是頁面組件還是小組件,都可能被復用,頁面結構與樣式都可以采用一套,但是數據一定要相互獨立 data () { return { count: 0 } } } </script> <style scoped> .beat { width: 100px; height: 100px; background-color: orange; text-align: center; line-height: 100px; border-radius: 50%; } </style>
<template> <div class="home"> <Beat/> <Beat/> </div> </template> <script> import Beat from '@/components/Beat' export default { components: { Beat, } } </script>
父組件傳遞數據給子組件
""" 一、組件傳參 - 父傳子 1)在子組件內部通過props設置組件的自定義屬性 props: ['abc', 'goods'] 2)在父組件中渲染子組件是對自定義屬性賦值即可 <GoodsBox v-for="goods in goods_list" :abc="goods" :goods="goods"/> """
子組件:
<template> <div class="goods-box"> <img :src="goods.img" alt=""> <p>{{ goods.title }}</p> </div> </template> <script> export default { name: "GoodsBox", // 在組件內部通過props定義組件的自定義屬性 props: ['abc', 'goods'], } </script> <style scoped> .goods-box { width: 260px; height: 300px; border: 1px solid black; border-radius: 5px; margin: 20px; float: left; overflow: hidden; text-align: center; } img { width: 260px; height: 260px; } </style>
父組件:
<template> <div class="goods"> <div class="main"> <!-- 在使用子組件是對自定義屬性賦值即可 --> <GoodsBox v-for="goods in goods_list" :abc="goods" :goods="goods" /> </div> </div> </template> <script> import GoodsBox from "../components/GoodsBox"; let goods_list = [ { img: require('@/assets/img/001.jpg'), title: '小貓', }, { img: require('@/assets/img/004.jpg'), title: '小狗', }, ]; export default { name: "Goods", data () { return { goods_list, } }, components: { GoodsBox, }, } </script>
子組件傳遞數據給父組件
""" 二、組件傳參 - 子傳父 前提:子組件是被父組件渲染的,所以子組件渲染要晚於父組件 1)子組件一定要滿足一個條件,才能對父組件進行傳參(某個時間節點 === 某個被激活的方法) eg:i)子組件剛剛加載成功,給父組件傳參 ii)子組件某一個按鈕被點擊的時刻,給父組件傳參 iii)子組件要被銷毀了,給父組件傳參 2)在子組件滿足條件激活子組件的方法中,對父組件發出一個通知,並將數據攜帶處理(自定義組件事件) <div class="goods-box" @click="boxClick"></div> methods: { boxClick () { this.$emit('receiveData', this.goods.title, '第二個數據', '第三個數據') } } 3)在父組件渲染子組件時,為自定義事件綁定方法 <GoodsBox @receiveData="recFn"/> 4)在父組件實現綁定方法時,就可以拿到子組件傳參的內容(接收到了通知並在父組件中相應) methods:{ recFn(title,data2,data3){ console.log('接收到了'+title); this.goodsTitle = title } 注意:組件標簽不能綁定系統定義的事件,沒有意義,子組件的事件都是在自己內部完成 """
子組件
<template> <div class="goods-box" @click="boxClick"> <img :src="goods.img" alt=""> <p>{{ goods.title }}</p> </div> </template> <script> export default { props: ['abc', 'goods'], methods: { boxClick () { // 通知父級 - 自定義組件的事件 'receiveData',然后把數據 this.goods.title 傳給父組件 this.$emit('receiveData', this.goods.title) } } } </script>
父組件
<template> <div class="goods"> <div class="main"> <!-- 實現自定義事件,接收子組件通知的參數 --> <GoodsBox v-for="goods in goods_list" @receiveData="recFn"/> </div> </div> </template> <script> import GoodsBox from "../components/GoodsBox"; export default { name: "Goods", data () { return { goodsTitle: '哪個', } }, methods: { recFn(title) { console.log('接收到了' + title); this.goodsTitle = title; } }, components: { GoodsBox, }, } </script>
"""
一、組件的生命周期:一個組件從創建到銷毀的整個過程
二、生命周期鈎子:在一個組件生命周期中,會有很多特殊的時間節點,且往往會在特定的時間節點完成一定的邏輯,特殊的時間節點可以綁定鈎子
注:鈎子 - 提前為某個事件綁定方法,當滿足這個事件激活條件時,方法就會被調用 | 滿足特定條件被回調的綁定方法就稱之為鈎子
"""
<template> <div class="goods"> <Nav /> </div> </template> <script> import Nav from "../components/Nav"; export default { name: "Goods", components: { Nav, }, beforeCreate() { console.log('該組件要被加載了') }, created() { // 重要:請求后台數據,將請求的結果保存在前台頁面 console.log('該組件被加載成功了') }, updated() { // 以及beforeUpdate鈎子,監聽着頁面中的所有數據 console.log('數據更新了') }, destroyed() { console.log('該組件銷毀了') } } </script>