Vue组件

132 阅读4分钟

Vue组件

初识Vue组件

在vue中,组件是最重要的组合部分,官方中定义组件为可复用的vue实例,分为全局组件和局部组件,接下来通过实例来分别演示两种不同的组件。

全局组件

全局组件可以在任意Vue示例下使用。

样例代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="app">
		    <mycomponent></mycomponent>
		</div>
		
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<script>
		    Vue.component('mycomponent', {
		        template: '<h1>这是全局组件</h1>'
		    });
		
		    var vm = new Vue({
		        el: '#app',
		    });
		</script>
	</body>
</html>

效果截图:
在这里插入图片描述

通过上面的例子,我们可以总结出全局组件的使用步骤:

  1. 使用vue.component()注册组件,需要提供2个参数:组件的标签名和组件构造器。
  2. vue.component()内部会调用组件构造器,创建一个组件实例。
  3. 将组建挂载到某个vue实例下。

注意:一个组件的template部分,必须要包裹在一个根容器中。

因为组件是可复用的vue实例,所以它们也能有data、computed、watch、methods以及生命周期钩子等。

样例代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="app">
		    <mycomponent></mycomponent>
		</div>
		
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<script>
		    Vue.component('mycomponent', {
		        template: `<div>
		                        <h3>我是全局组件</h3>
		                         <button @click="add">加</button>
								 {{num}}
		                   </div>`,
		        data(){
		            return {
		                num:1
		            }
		        },
		        methods:{
		            add(){
		                this.num++;
		            }
		        }
		    });
		
		    var vm = new Vue({
		        el: '#app',
		    });
		</script>
	</body>
</html>

效果截图:
在这里插入图片描述

上面代码中有两个注意事项:

  1. 组件模板的内容,可以写在一对反引号中(``),这样就可以不使用字符串拼接的形式了。
  2. 一个组件的data选项必须是一个函数,该函数返回一个对象。

局部组件

如果不需要全局注册,或者是让组件使用在其它组件内,可以用选项对象的components属性实现局部注册。 因此我们可以将上面的全局组件改为局部组件。

样例代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="app">
		    <mycomponent></mycomponent>
		</div>
		
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<script>
		    let obj = {
		        template: `<div>
		                       <h3>我是局部组件</h3>
		                        <button @click="add">加</button>
								{{num}}
		                   </div>`,
		        data(){
		            return {
		                num:1
		            }
		        },
		        methods:{
		            add(){
		                this.num++;
		            }
		        }
		    };
		
		    var vm = new Vue({
		        el: '#app',
		        components:{    //声明局部组件
		            mycomponent:obj
		        }
		    });
		</script>
	</body>
</html>

效果截图:
在这里插入图片描述

组件模板

如果组件中的template内容过多,那么可以使用组件模板来声明template中的内容。

样例代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="app">
		    <mycomponent></mycomponent>
		</div>
		
		<!-- 组件模板 -->
		<template id="mytemplate">
		    <div>
		        <h3>我是局部组件</h3>
		         <button @click="add"></button>
				 {{num}}
		    </div>
		</template>
		
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<script>
		    let obj = {
		        template: '#mytemplate',      //使用选择器应用组件模板
		        data() {
		            return {
		                num: 1
		            }
		        },
		        methods: {
		            add() {
		                this.num++;
		            }
		        }
		    };
		
		    var vm = new Vue({
		        el: '#app',
		        components: { //声明局部组件
		            mycomponent: obj //组件名:组件实例
		        }
		    });
		</script>

	</body>
</html>

效果截图:
在这里插入图片描述

父子组件

当我们继续在组件中写组件,形成组件嵌套的时候,就是我们所说的父子组件了。
样例代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="app">
		    <mycomponent></mycomponent>
		</div>
		
		<template id="mytemplate">
		    <div>
		        <h3>我是父组件</h3>
		        <!-- 在父组件中使用子组件 -->
		        <subcomponents></subcomponents>
		    </div>
		</template>
		
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<script>
		    let obj = {
		        template: '#mytemplate',
		        data() {
		            return {}
		        },
		        components:{          //声明子组件
		            subcomponents:{
		                template:`<div>我是子组件</div>`
		            }
		        }
		    };
		
		    var vm = new Vue({
		        el: '#app',
		        components: { //声明局部组件
		            mycomponent: obj //组件名:组件实例
		        }
		    });
		</script>
	</body>
</html>

效果截图:
在这里插入图片描述

组件之间的通信

组件与组件之间是可以互相通信的。包括父子组件之间、兄弟组件之间等等,都可以互相通信。 下面只讨论父子组件之间通信问题。

子组件获取父组件数据

在vue中,组件实例的作用域是孤立的,默认情况下,父子组件的数据是不能共享的,也就是说,子组件是不能直接访问父组件的数据的。为此,vue给我们提供了一个数据传递的选项prop,用来将父组件的数据传递给子组件。具体使用如下:
样例代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>


    </head>
    <body>
        <div id="app">
            <sub-component msg="牛哄哄的柯南"></sub-component>

            <sub-component msg="Keafmd"></sub-component>

        </div>


        <template id="btncounter">
            <div>
                hello {{msg}}
            </div>
        </template>

        <script>
            //子组件
            let subComponent = {

                template: '#btncounter',
                props: ['msg'],
                data() {
                    return {}
                },
                methods: {
                    counter() {
                        this.num++;
                    }
                }
            }



            var vm = new Vue({
                el: '#app',
                data: {
                    msg: 'parent'
                },
                components: {
                    subComponent
                }
            });
        </script>

    </body>
</html>

效果截图:
在这里插入图片描述

上面实例中,子组件获取父组件传递的数据的步骤为:
1. 在子组件标签中,声明 msg 属性,属性值即为父组件向子组件传递的值。
2. 在子组件中,使用props选项,声明接收父组件向子组件传递值的载体,即 ‘msg’ 。
3. 子组件中就可以使用 msg 获取父组件向子组件传递的值了。

也可以使用 v-bind 绑定子组件标签属性,这样就可以将父组件data数据传递个子组件了。

父组件获取子组件数据

和上面不一样的是,父组件想要获取子组件的数据时,需要子组件通过emit主动将自己的数据发送给父组件。

样例代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>


	</head>
	<body>
		<div id="app">

			<sub-component msg="牛哄哄的柯南" @getnum="getNum"></sub-component>

			<sub-component msg="Keafmd" @getnum="getNum2"></sub-component>


			第一个的数据{{firstNum}} <br />
			第二个的数据{{secondNum}}




		</div>


		<template id="btncounter">
			<div>
				hello {{msg}}

				<button @click="counter">{{num}}</button>


			</div>
		</template>

		<script>
			//子组件
			let subComponent = {

				template: '#btncounter',
				props: ['msg'],
				data() {
					return {
						num: 1
					}
				},
				methods: {
					counter() {
						this.num++;
						this.$emit('getnum', this.num)
					}
				}
			}



			var vm = new Vue({
				el: '#app',
				data: {
					firstNum: 0,
					secondNum: 0,
					msg: 'parent'
				},
				components: {
					subComponent
				},
				methods: {
					getNum(num) {
						this.firstNum = num;
						// alert('事件被调用'+num)
					},
					getNum2(num) {
						this.secondNum = num;
						// alert('事件被调用'+num)
					}
				}
			});
		</script>

	</body>
</html>

效果截图:
在这里插入图片描述

首先,我们需要在子组件中触发一个主动发送数据的事件,上面的例子中是一个点击事件send;其次,在点击事件中使用emit方法,这个emit接收两个参数:传递数据的事件和需要传递的数据,这个传递数据的事件也是自定义的;然后在父组件中引用子组件,并在引用的子组件中使用on监听上一步传递数据的事件,上面的例子中是childmsg;最后在父组件中使用这个事件,这个事件带有一个参数,就是从子组件发送过来的数据。

看完如果对你有帮助,感谢点赞支持!
如果你是电脑端的话,看到右下角的 “一键三连” 了吗,没错点它[哈哈]

在这里插入图片描述
加油!

共同努力!

Keafmd