組件化
注冊組件的基本步驟
- 創建組件構造器 (調用Vue.extend()方法)
- 注冊組件 (調用Vue.component()方法)
- 注冊組件語法糖
- 省去了調用Vue.extend()的步驟,而是可以直接使用一個對象來代替
- 注冊組件語法糖
- 使用組件 (在Vue實例的作用范圍內使用組件)
組件模板的分離寫法
- 語法糖簡化了Vue組件的注冊過程,但是template模塊中js和html代碼混雜的寫法仍讓我們苦惱
- 於是Vue提供了兩種方式,來分離模板中的js和html代碼
- 使用標簽 ,再通過id來關聯 <script type="text/x-template" id="cpn"> 模板內容 </script> Vue.component('cpn', { template: '#cpn' }) //全局組件
- 使用`<template>`標簽,再通過id來關聯
```js
<template id="cpn"> 模板內容 </template>
注冊組件方式於上相同
```
組件可以訪問Vue實例數據嗎?
- 組件是一個單獨功能模塊的封裝
- 這個模板有屬於自己的HTML模板,也應該有自己的數據data
- 組件中的數據是保存再哪里呢?頂層的Vue實例中的data嗎
- 通過實踐,我們發現是不能訪問的,即使可以,如果將所有的數據都放在Vue實例中,Vue也會變的非常臃腫
- 結論:Vue組件應該有自己保存數據的地方
- 組件中的data為什么是函數且返回對象類型?
- 為了組件的復用性和各個組件的獨立性,當多次調用的時候,能為各個組件中的數據單獨開辟存儲空間,互補影響
父子組件的通信
- 在上面提到,子組件是不能引用父組件或者Vue實例的數據的
- 但是,在開發中,往往一些數據確實需要從上層傳遞到下層:
- 比如在一個頁面中請求到了很多數據
- 其中一部分數據,並非是我們整個頁面的大組件來展示的,而是需要下面的子組件進行展示
- 這時,並不會讓子組件再次發送一個網絡請求,而是直接讓大組件(父組件)/將數據傳遞給小組件(子組件)
- 如何進行父子間的通信呢?
- 通過props(properties:屬性)向子組件傳遞數據(父->子)
- 通過自定義事件emit向父組件發送消息(子->父)
1父級向子級傳遞數據:
- 在子組件中,使用選項props來聲明需要從父組件中接收到的數據(props:數組或者對象)
- 在使用子組件時通過綁定自定義屬性來將數據從父組件傳到子組件當中
- props駝峰標識:props定義了駝峰標識的變量數據時,在使用時要用-小寫,aMessage -> a-message
- props數據驗證:props使用對象可以進行數據驗證和設置默認值(type,defult)
-
<div id='app'> <cpn :message='message'></cpn> </div> <template id="cpn"> <h2>{{ message }}</h2> </template> <script src='./vue1/js/vue.js'></script> <script> const app=new Vue({ el:'#app', data:{ message:'你好啊' }, components:{ cpn:{ template:'#cpn', props:{ message:{ type:string, defult(){ return {} } }, } } } })
2子級向父級傳遞數據:
- 使用自定義事件和$emit
- 通常是子組件發生了一些事件,然后告訴父組件我們發生了什么事件,並且告訴父組件對應事件的數據
-
<div id='app'> <cpn @itemclick='cpnclick'></cpn> </div> <template id="cpn"> <div> <button v-for="item in aaa" @click='btnclick(item)'>{{item.name}}</button> </div> </template> <script> const cpn = { template:'#cpn', data(){ return { aaa:[ {id:'aaa',name:'熱門推薦'}, {id:'bbb',name:'手機數碼'}, {id:'ccc',name:'家用家電'} ] } }, methods:{ btnclick(item){ //emit 發射 this.$emit('itemclick',item) } } } const app=new Vue({ el:'#app', data:{ message:'你好啊' }, components:{ cpn }, methods:{ cpnclick(item){ console.log('cpnclick',item); } } })
3父級組件訪問子級組件
- 使用
$children(通常不推薦使用)或者$refs(refrence:引用) this.$children是一個數組類型,它包含了所有子組件對象$refs和ref指令通常一起使用,首先我們通過ref給某一個子組件綁定一個特定的ID,其次,通過this.$refs.ID就可以訪問到該組件了-
<child-cpn ref='child'></cpn> <button @click='showRefscpn'></button> showRefscpn(){ console.log(this.$refs.child.message) }
4.子級組件訪問父級組件
- 可以通過$parent來實現 ,this.$parent
- 但是在開發中一般不會這樣做,因為應該避免直接訪問父組件的數據,因為這樣耦合度太高了
插槽的使用(slot)
- 在子組件中使用
,就可以為子組件開啟一個插槽 - 具名插槽:
-
<div id="app"> <cpn><span slot="center">標題</span></cpn> <cpn><button slot="left">返回</button></cpn> </div> <template id="cpn"> <div> <slot name="left"><span>左邊</span></slot> <slot name="center"><span>中間</span></slot> <slot name="right"><span>右邊</span></slot> </div> </template>
模塊化
為什么要模塊化
- 隨着ajax異步請求的出現,慢慢形成了前后端的分離,客戶端的代碼也越來越多,為了對應代碼的劇增,通常會將代碼阻止在多個js文件當中,但是,這種維護方式,依然不能避免一些災難性的問題
- 當js文件過多的時候,比如有幾十個的時候,弄清楚他們的順序是一件比較尷尬的事情
- 多個變量名沖突的問題
- 即使使用匿名函數解決了重名問題,但是如果講匿名函數中的變量和方法給其他文件調用
如何模塊化
-
模塊化雛形 var moudle=(function(){ var obj={}; obj.flag=true; obj.myfunc=function(info){ console.log(info) } return obj })() -
上面的是模塊化概念的雛形,前端發展到現在,也有了很多現有的規范和對應的實現方案
- es6 :
export{}導出 ,import{} form '文件路徑'導出- 引入時需要在上type
<script src='...' type='module'></script> - export default + 導出成員,在導入是可以自定義命名
- 引入時需要在上type
- commonjs:
moudle.exports={xx}導出,let={xx}=require('文件路勁')導入 - AMD
- CMD
- es6 :
