看到好文章,我就控制不住我自己啊
https://blog.youkuaiyun.com/qq408896436/article/details/79250605
组件是什么?
组件其实就是一片html代码
组件有什么用?
封装可重用的代码,类似我们以前把index.html的后缀改为index.shtml,然后使用#include引入页面
一个简单的例子
- <div id='app'>
- <!--3、使用组件-->
- <aaa></aaa>
- </div>
- <script src='../js/vue.js'></script>
- <script>
- //1、定义组件
- var AAA = Vue.extend({
- template : '<h3>h3标签</h3>'
- });
- //2、注册组件
- Vue.component('aaa', AAA);
- var vm = new Vue({
- el : '#app'
- });
- </script>
组件使用步骤 :
1、定义组件 :Vue.extend
2、注册组件 :Vue.component该函数的第一个参数是组件的名字,第二个参数是组件对象
3、使用组件 :<aaa></aaa>
组件中的“data”与“methods”
组件里也可以像我们平常使用vue那样,使用data和methods来修改template里的数据或者给template中的标签添加事件。基本上,组件与我们平常使用vue的方式很类似。下面是在组件上添加data与methods的一个例子 :
- <div id='app'>
- <aaa></aaa>
- </div>
- <script src='../js/vue.js'></script>
- <script>
- var AAA = Vue.extend({
- template : '<h3 @click="say">{{msg}}</h3>',
- data(){
- return {
- msg : 'h3标签'
- }
- },
- methods : {
- say : function(){
- alert('你点击了我呀!');
- }
- },
- created : function(){
- console.log('实例已经创建')
- },
- beforeCompile : function(){
- console.log('编译之前');
- },
- compiled : function(){
- console.log('编译之后');
- },
- ready : function(){
- console.log('插入数据到文档中');
- }
- });
- Vue.component('aaa', AAA);
- var vm = new Vue({
- el : '#app'
- });
- </script>
需要注意的是上面的data和我们平常使用的data有些不一样。组件中的data必须以函数的形式并且需要return一个json。
而且Vue.extend返回的其实是一个Vue对象,类似我们平常
- var vm = new Vue({
- 'el' : '#app'
- });
组件的另一种写法(简写)
Vue.extend这个步骤其实可以被省略。直接调用Vue.component即可完成一个组件的编写。如 :
- Vue.component('组件名字',{
- 'template' : 'xxxxx',
- data(){
- return {
- xxx : xxxx
- }
- },
- methods : {
- xxx : function(){
- }
- }
- });
或者
- var json = {
- template : 'xxxxx',
- data(){
- return {
- xxx : xxxx
- }
- },
- methods : {
- xxx : function(){
- }
- }
- }
- Vue.component('组件名字', json);
局部组件
我们上面说的都是全局组件,组件还有一种是局部的。定义局部组件和定义全局的类似,只要把定义组件的步骤放在我们的new Vue里面即可。
语法 :
- components :{
- '组件1' : {
- 'template' : 'xxx',
- data(){
- return {
- xxx : 'xxx'
- }
- },
- methods : {
- xxx : function(){
- }
- }
- },
- '组件2' : {
- 'template' : 'xxx',
- data(){
- return {
- xxx : 'xxx'
- }
- },
- methods : {
- xxx : function(){
- }
- }
- }
- }
或者
- var json1 = {
- template : 'xxxx'
- }
- var json2 = {
- template : 'xxxx'
- }
- components :{
- '组件1' : json1,
- '组件2' : json2
- }
例子:
- <div id='app'>
- <aaa></aaa>
- <bbb></bbb>
- </div>
- <div id='bpp'>
- <!--调用app里的局部组件-->
- <aaa></aaa>
- <bbb></bbb>
- </div>
- <script src='../js/vue.js'></script>
- <script>
- var app = new Vue({
- el : '#app',
- components : {
- 'aaa' : {
- template : '<h3 @click="say">{{msg}}</h3>',
- data(){
- return {
- msg : 'h3标签'
- }
- },
- methods : {
- say : function(){
- alert('你点击了h3!')
- }
- }
- },
- 'bbb' : {
- template : '<h4 @click="say">{{msg}}</h4>',
- data(){
- return {
- msg : 'h4标签'
- }
- },
- methods : {
- say : function(){
- alert('你点击了h4!')
- }
- }
- }
- }
- });
- var bpp = new Vue({
- el : '#bpp'
- });
- </script>
需要注意的是,components后面是有s的,因为里面可以放很多个组件。以及局部组件只有app里面的能用,bpp用的话就直接报错了。
把template写在外面
或许你已经发现了,template : '<h3>h3标签</h3>'这句语句的弊端。如果标签内容很多,都用字符串的形式编写html代码,那还不累死。解决方法是使用template标签,把组件写在外面。如 :
- <div id='app'>
- <aaa></aaa>
- </div>
- <template id='zujian-1'>
- <h3>我是h3</h3>
- </template>
- <script src='../js/vue.js'></script>
- <script>
- var app = new Vue({
- el : '#app',
- components : {
- 'aaa' : {
- template : '#zujian-1'
- }
- }
- });
- </script>
component里面对应template的ID即可。
子组件
组件里面还可以嵌套组件。实现子组件,只需要记住以下两点即可:
1、子组件必须写在父组件的template中
2、子组件必须要在父组件内部注册
例子:
- <div id='app'>
- <aaa></aaa>
- </div>
- <template id='aaa-template'>
- <h2>我是aaa组件的内容</h2>
- <bbb></bbb> //子组件必须写在父组件的template中
- </template>
- <template id='bbb-template'>
- <h3>我是bbb组件的内容</h3>
- </template>
- <script src='../js/vue.js'></script>
- <script>
- var app = new Vue({
- el : '#app',
- components :
- {
- 'aaa' :
- {
- template : '#aaa-template',
- components : //子组件必须要在父组件内部注册
- {
- 'bbb' :
- {
- template : '#bbb-template'
- }
- }
- }
- }
- });
- </script>
父组件与子组件的数据传递
默认情况下,父组件与子组件的数据是互相不能访问的。但可以通过一些方法来获取。
父组件获取子组件数据
步骤 :
1、子组件发送广播。(发送广播通过$emit方法,该方法接受两个参数 :第一个参数是 :广播的事件名
第二个参数是 :要发送给父组件的数据)
2、子组件接受广播。(通过v-on绑定子组件的广播事件然后接收数据)
3、父组件调用第2步的事件在修改值
例子 :
- <div id='app'>
- <parent></parent>
- </div>
- <script src='vue.js'></script>
- <script>
- new Vue({
- el : '#app',
- components :
- {
- 'parent' : {
- //第2步
- template : '<h2>{{msg}}</h2><br/><child @send="get"></child>',
- data(){
- return {
- msg : ''
- }
- } ,
- methods : {
- //第3步
- get : function(msg){
- this.msg = msg;
- }
- },
- components :{
- 'child' :{
- template : '<h2>{{msg}}</h2>',
- data(){
- return{
- msg : '我是子组件数据'
- }
- },
- ready : function(){
- //第1步
- this.$emit('send', this.msg);
- }
- }
- }
- }
- }
- });
- </script>
子组件获取父组件数据
1、在子组件中使用v-bind绑定要获取的父组件数据。如 :<bbb :xxx=’父组件数据’></bbb>
2、在子组件内部使用props
3、使用数据
例子 :
- <div id='app'>
- <parent></parent>
- </div>
- <script src='vue.js'></script>
- <script>
- new Vue({
- el : '#app',
- components :
- {
- 'parent' : {
- //第1步
- template : '<h2>{{msg}}</h2><br/><child :fmsg="msg"></child>',
- data(){
- return{
- msg : '我是父组件数据'
- }
- },
- components :{
- 'child' :{
- //第2步
- props :['fmsg'],
- //第3步
- template : '<h2>{{fmsg}}</h2>'
- }
- }
- }
- }
- });
- </script>
子组件修改父组件的值(vue2.0版本中是不允许这样修改的,这里了解下就好)
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- </head>
- <body>
- <div id='app'>
- <parent></parent>
- </div>
- <script src='vue.js'></script>
- <script>
- new Vue({
- el : '#app',
- components :
- {
- 'parent' : {
- template : '<div><h2>{{msg}}</h2><br/><child :fmsg.sync="msg"></child></div>',
- data(){
- return{
- msg : '我是父组件数据'
- }
- },
- components :{
- 'child' :{
- props :['fmsg'],
- template : '<div><h2>{{fmsg}}</h2><button @click="change">点击我修改父组件数据</button></div>',
- methods : {
- change : function(){
- this.fmsg = 0;
- }
- }
- }
- }
- }
- }
- });
- </script>
- </body>
- </html>
使用$emit和$on互相发送数据
父组件和子组件传递数据除了上面说的那2种方法外,还可以使用$emit和$on来发送数据。发送的一方使用$emit,接受的一方使用$on即可。(推荐使用这种方法,简单好管理)
例子
子组件发送数据给父组件
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id='app'>
- <parent></parent>
- </div>
- <script src='vue.js'></script>
- <script>
- var Event = new Vue();
- new Vue({
- el : '#app',
- components :
- {
- 'parent' : {
- template : '<div><h2>{{msg}}</h2><br/><child></child></div>',
- data(){
- return{
- msg : '空'
- }
- },
- ready : function(){
- console.log('父mounted');
- Event.$on('msg', function(msg){
- this.msg = msg;
- }.bind(this));
- },
- components :{
- 'child' :{
- template : '<div><h2>{{msg}}</h2></div>',
- data(){
- return{
- msg : '我是子组件数据'
- }
- },
- ready : function(){
- setTimeout(function(){
- console.log('子mounted');
- Event.$emit('msg', this.msg);
- }.bind(this),10)
- },
- }
- }
- }
- }
- });
- </script>
- </body>
- </html>
父组件发送数据给子组件
- <!doctype html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title></title>
- </head>
- <body>
- <div id='app'>
- <parent></parent>
- </div>
- <script src='vue.js'></script>
- <script>
- var Event = new Vue();
- new Vue({
- el : '#app',
- components :
- {
- 'parent' : {
- template : '<div><h2>{{msg}}</h2><br/><child></child></div>',
- data(){
- return{
- msg : '我是父组件数据'
- }
- },
- ready : function(){
- console.log('父mounted');
- Event.$emit('msg', this.msg);
- },
- components :{
- 'child' :{
- template : '<div><h2>{{msg}}</h2></div>',
- data(){
- return{
- msg : '空'
- }
- },
- ready : function(){
- console.log('子mounted');
- Event.$on('msg', function(msg){
- this.msg = msg;
- }.bind(this));
- },
- }
- }
- }
- }
- });
- </script>
- </body>
- </html>
提示 :传递数据的时候,发送的一方不管是父还是子,一定要先$on了在$emit(先注册事件,在发送)才管用。所以我们在子组件发送数据给父组件 这个例子里,子组件用了setTimeout才$emit,因为vue会先去编译子组件。不用setTimeout的话就会先执行$emit了
总结
1、组件有全局组件与局部组件,全局组件在任何地方都能用,局部组件只有在绑定的el的div内才能使用。
2、定义全局组件有2种方式,一种是Vue.extend +Vue.component,另外一种是直接使用Vue.component
3、定义局部组件,只要定义在new Vue({}) 的内部即可, 且components这个单词后面是有s的
4、组件中也可以有data和methods,需要注意的是在组件内部定义data必须以函数的形式定义,并且需要返回一个json
5、定义组件时,template可以写在外面。只要给template定义一个id,注册组件的时候,引用这个id即可。如 :
- <template id='aaa'></template>
- new Vue({
- el : '#app',
- components: {
- 'aaa' : {
- template:'#aaa'
- }
- }
- });
6、组件之间是可以嵌套的,嵌套组件时记住两点 :
1)子组件必须写在父组件的template中
2)子组件必须要在父组件内部注册
7、父获取子数据:通过$emit和v-on
8、子获取父数据:通过props和v-bind
9、$emit和$on也可以实现父/子组件的数据发送,需要注意的是一定要先on了才emit