組件(Component)是Vue.js最核心的功能。
組件與Vue類似需要注冊之后才可以使用。
注冊有全局注冊和局部注冊兩種方式。全局注冊后在任何Vue實例中都可以使用。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <my-component></my-component> <!--組件當作一個新的標簽來使用--> </div> <script> // 全局組件 // 注冊 Vue.component ('my-component',{ template: '<div>組件測試001</div>' //template的DOM結構必須被一個元素包裹着,否則無法顯示 }); var app = new Vue({ el: "#app", }) </script> </body> </html>
需要注意的是:template的DOM結構必須被一個元素包含,否則無法渲染。
在Vue實例中,使用components選項可以局部注冊組件,注冊后的組件只有在該實例作用域下有效。
同時組件中也可以使用components選項來注冊組件。
除了template選項外,組件中還可以像Vue實例那樣使用其它選項,比如data、computed、methods等
在使用data的時候,必須是以函數的形式,將數據return出來。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <my-component></my-component> </div> <script> Vue.component('my-component',{ template: '<div>{{ message }}</div>', data: function () { return { message: '組件中可以使用data、computed、methods等,但是使用data時,data必須是函數,然后將數據return出去' } } }); var app = new Vue({ el: "#app", }) </script> </body> </html>
如果return出的對象引用了外部的一個對象,那么這個對象就是共享的,任何一處修改都會同步。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.min.js"></script> </head> <body> <div id="app"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div> <script> var data = { counter: 0 }; // data屬於全局變量,如果改變了所有組件都會跟着一起改變 Vue.component('my-component',{ template: '<button @click="counter++">{{ counter }}</button>', data: function () { return data; // 在組件中不自定義data,直接引用data.counter那么就是常量,永遠為0,這屬於兩個不同的作用域 } }); var app = new Vue({ el: "#app", //為啥不能將data定義到app這個對象里面來,因為感覺有點多此一舉 }); </script> </body> </html>
效果:
有一個修改所有的之都會與之修改。
正確的做法如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div> <script> Vue.component('my-component',{ template: '<button @click="counter++">{{ counter }}</button>', data: function () { return { counter: 0 }; //每個組件都有一個自己的域 } }); var app = new Vue({ el: "#app", }) </script> </body> </html>
效果:
還有一點需要注意的是:
Vue組件的模板在某些情況下會受到HTML元素的限制,比如table標簽內只允許出現tr、td、th
可以使用特殊的is屬性來進行掛載。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <!--<div id="app">--> <!--<table>--> <!--<my-component></my-component>--> <!--</table>--> <!--</div>--> <!--<div id="app"><div>組件測試001</div><table></table></div>--> <!--其實並沒有渲染進去--> <div id="app"> <table is="my-component"></table> </div> <!--<div id="app"><div>組件測試001</div></div>--> <!--tbody在渲染時會替換組件的內容--> <!--常見的限制性元素:<ul> <ol> <select>--> <script> Vue.component ('my-component',{ template: '<div>組件測試001</div>' }); var app = new Vue({ el: "#app", }) </script> </body> </html>