vue組件化開發 將一個頁面分割成若幹個組件,一個頁面js+css+html,將自己類容分割出來,方便開發,更好了維護我們的代碼,每個組件封裝自己的js+html+css,樣式命名衝突 將一個頁面分割成若幹個組件,一個頁面js+css+html,將自己類容分割出來,方便開發,更好了維護我們的代碼,每 ...
-
將一個頁面分割成若幹個組件,一個頁面js+css+html,將自己類容分割出來,方便開發,更好了維護我們的代碼,每個組件封裝自己的js+html+css,樣式命名衝突
組件分類
-
頁面級組件( 例如詳情頁頁面)
-
基礎組件(頁面的一部分,例如輪播圖)
-
組件的目的為了實現復用
指令和組件
-
在標簽內增加的行內屬性,實現功能指令
-
組件就是一個自定義(擴展)的標簽<hello></hello>,封裝代碼的,組件的標簽名不能破壞原有的html標簽
組件:全局組件(不需要引用),局部組件(需要引用)
-
在vue中一個對象就是一個組件
-
在組件中data是一個函數,目的是不受別人干擾,因為組件是獨立的
-
使用組件的步驟,
-
1.聲明組件,並且引入到當前頁面
-
2.在組件的父級模板中調用這個組件
-
組件名稱不能和標簽相同
-
-
全局組件
-
Vue.component('my-handsone',{ //template只會有一個根元素,而且不能直接放置文本節點 template:'<h1>{{msg}}</a></h1>', data(){ return { //可以用來定義數據 msg:"帥嗎", types:[1,2,3] } } }); let vm=new Vue({ el:"#app", data:{} })
- 局部組件
-
//一個對象就是一個組件 let webeautiful={ template:'<h1>{{msg}}</h1>', data(){ return { msg:"很帥呀" } } }; let vm=new Vue({ el:"#app", //掛載在vue實例中components components:{ webeautiful } })
-
父傳子屬性傳遞 子組件通過props接收
-
props的api
-
type 接收數據的類型
-
default 預設數據的值
-
required 必須傳遞數據 不能和default同時引用
-
validator 自定義驗證
-
-
子傳父組件,事件觸發 $emit->@方法="父組件的方法"
-
平級交互 eventBus 但是不用 -vuex
-
父組件調用子類的方法 ref=>this.$ref.xxx.子類方法
-
slot 插槽 (設置一些空閑的位置等等使用)
父親傳遞給兒子數據
-
先在兒子組件上綁定一個屬性名,然後賦值給這個屬性 :m="msg",
-
兒子接受父親傳遞的數據,用props接收傳遞的屬性名字,例如 props:{m:{type:Array}}
-
// 父親到兒子,預設組件是獨立的,相互不能引用數據,可以通過屬性方式傳遞給兒子 let vm=new Vue({ el:"#app", //根實例上的data都是對象,組件中的都是函數 data:{ money:100 }, //父級傳遞給子集數據通過綁定屬性,如果傳遞多個可以數組中寫多個 template:'<div><child :m="money" o="美女"></child></div>', components:{ child:{ //子集接收給父級給的數據,通過props屬性接收 props:['m','o'], computed:{ b(){ //這裡的this指向子集child //父親的數據兒子不能更改 錯誤寫法 this.o="醜呀" return "大大"+this.o; } }, template:"<div>兒子 {{m}} {{b}}</div>" } } })
-
兒子通過自定義事件方法中給父親發射自己的數據
-
先在兒子組件實例中created中發射一個數據
-
例如 created(){//傳遞自己的數據
this.$emit('childs',this.msg);
}
-
-
在兒子組件上要綁定這個自定義事件方法,然後裡面賦值父親接收的函數
-
例如兒子組件 <child @childs="父親接收的函數"></child>
-
-
最後父親接收的函數很簡單,參數就是兒子傳遞的數據
-
例如父親接收的函數 fn(data){//這裡面的data就是兒子發射給父親的參數}
-
//實例化一個Vue函數 let vm=new Vue({ //child 是兒子 觸發了自己的一個方法,綁定了父親的一個函數方法 template:'<div><child @childs="say"></child></div>', //方法掛載 methods:{ //父親的一個方法 say(data){ console.log(data); } }, //定義一個兒子組件 components:{ //兒子名字 child:{ //事件和數據初始化之後 created(){ //兒子發射一個方法 傳遞自己的數據 this.$emit('childs',this.msg); }, template:'<div>子</div>', data(){ return { msg:"我餓了" } }, } }, }).$mount("#app"); //手動將vue掛載在#app標簽上
-
父親和兒子實現雙向數據綁定
父親傳遞給兒子數據,兒子觸發一個父親方法,將最新的值傳遞給父親,父親更改後,屬性會重新傳遞兒子,兒子會刷新
-
父親先在兒子組件上通過綁定一個屬性,然後給這個屬性賦值,給兒子傳遞數據
-
例如<child :m="msg"></child>
-
-
兒子接收父親的傳遞的數據props
-
props:{m:{type=Array}}
-
-
兒子拿到數據後,要修改數據,(兒子無法把父親傳遞的參數重新賦值)
-
然後兒子重新發射一個自定義事件方法,後面跟要修改的值
-
this.$emit("ee",1000);
-
-
此時兒子組件上要綁定發射的自定義方法,賦值父親的接收的函數fn
-
<child :m="msg" @ee="fn"></child>
-
-
父親接收函數,參數就是兒子發射過來的數據
-
fn(data){//此時把兒子發射過來的數據data,重新賦值給第一次傳遞過去的msgreturn this.msg=data;}
-
-
這樣就成功了實現父與子之間的數據雙向綁定
-
let vm = new Vue({ el:'#app', //通過在兒子組件上綁定一個屬性向兒子傳遞數據 // @ee="fn" 接收兒子傳遞過來數據,ee是兒子那邊自定義的事件方法,必須綁定在兒子組件上 template:'<div>父親+{{money}}<child :m="money" @ee="fn"></child></div>', data:{ money:100 }, methods:{ fn(data){ //父親接收兒子的數據函數 return this.money=data; } }, components:{ child:{ //接收父親傳遞過來的屬性值 props:{m:{}}, template:'<div>{{m}}<button @click="more"></button></div>', methods:{ more(){ //向父親發射一個自定義方法,並傳遞過去自己的值 this.$emit('ee',1000) } } } } })
-
父親先通過在兒子身上綁定一個屬性,向兒子傳遞數據
-
這時候,屬性後面我們跟一個sync修飾符
-
例如 <child :m.sync="msg"></child>
-
-
這時候,兒子要通過props接受父親傳遞的參數
-
props:{
m:{
type:Array //規定是數據類型
}}
-
-
兒子接受到數據,發現不滿意,發射一個自定義事件方法給父親
-
this.$emit('update:m',1000);
-
-
此時我們發現父親的數據m自動更改了,變成1000
-
-
let vm = new Vue({ el:'#app', template:'<div>父{{msg}}<child :a.sync="msg"/></div>', data:{ msg:'美女' }, components:{ child:{ props:['a'], //<comp :foo="bar" @update:foo="val => bar = val"></comp> template:'<div>child {{a}} <button @click="change">換</button></div>', methods:{ change(){ //固定的寫法 //2.3.0版本以後才會用 //用了sync,下麵必須用update this.$emit('update:a','醜女'); } } } } })
第一步先定義兒子有一個fn方法
methods:{fn(){ console.log("王阿姨好漂亮"); }}
第二步在兒子身上標記一個表示ref
<child ref="msg"></child>
第三步父親在視圖載入完成後,調用兒子的fn方法
mounted(){this.$refs.msg.fn();}
this.$refs.msg 調用兒子身上的msg表示,這時候this.$refs.msg指向的就是兒子的實例
實例.fn() 這就調用到了兒子的fn方法
-
// ref如果寫在dom上,表示獲取dom,如果寫在組件上,表示當前組件的實例 let vm=new Vue({ el:"#app", template:'<child ref="c"></child>', //一定要放在mounted下麵,因為mounted方法表示數據和視圖渲染完成, mounted(){ //當前的ref指向的是child組件的實例,通過實例調用下麵的fn方法 this.$refs.c.fn(); }, components:{ child:{ template:'<div>child</div>', methods:{ fn(){ alert("王阿姨好漂亮") } } } } })
兄弟組件之間的數據通訊(就是平級組件之間的數據通訊)
-
兄弟組件之間數據互通,要藉助第三個vue實例
-
eventBus使用起來不好管理,命名衝突,而且複雜,一般不用
-
我們通常叫這個實例叫eventBus
-
let eventBus=new Vue;
-
-
將兄弟發射的自定義事件方法,掛載到eventBus實例上
-
eventBus.$emit('aa',''c');
-
-
然後通過$on方法,將兄弟發射的自定義事件方法綁定裡面去
-
後面的回調函數一定要是箭頭函數,不改變實例的this,方便賦值
-
例如 eventBus.$on('aa',(data)=>{console.log(data)
let eventBus=new Vue; //eventBus使用起來不好管理,命名衝突,而且複雜,一般不用 let C={ template:'<div>{{val}}<button @click="ss">變C</button></div>', data(){ return { val:"C" } }, methods:{ ss(){ eventBus.$emit('bb','C'); } }, created(){ // eventBus.$on('aa',(data)=>{ this.val=data; }) } }; let D={ template:'<div>{{val}}<button @click="ee">變D</button></div>', data(){ return { val:"D" } }, created(){ // eventBus.$on("bb",(data)=>{ this.val=data; }) }, methods:{ ee(){ // eventBus.$emit('aa','D'); } } } let vm = new Vue({ el:'#app', //1,找共同父級,時間交互,非常複雜,不採用 template:'<div><C></C><D></D></div>', data:{ }, components:{ C, D } })
slot 可以將不同的標簽分開發送到指定的節點中
slot 有一個name屬性
slot上的name屬性,有一個預設值default
沒有指定slot名字的都叫default 會塞到name=default的組件內
<div id="app"> <hello> 123 <ul slot="bottom"> <li>我很帥</li> </ul> <ul slot="top"> <li>你醜</li> </ul> 456 </hello> </div> <template id="hello"> <div> <!--slot是vue提供的內置插件,具名slot 在寫內容時第一預留出來slot插口,如果沒有使用則使用預設內容,沒有指定slot名字的都叫default 會塞到name=default的組件內--> <slot name="default">nihao </slot> <slot name="top">這是上</slot> <slot name="bottom">這是下</slot> </div> </template> <script> let vm = new Vue({ el:'#app', components:{ hello:{ template:'#hello' } } }) </script>
-
transition有一個name屬性
-
假設我們name="fade"
-
-
transition動畫組件對應三個css樣式
-
進入開始 .fade-enter 的樣式
-
開始過渡階段 .fade-enter-active
-
出去終點 .fade-leave-active
-
這三個樣式裡面,我們可以任意寫樣式
-
-
-