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>
效果截图:
通过上面的例子,我们可以总结出全局组件的使用步骤:
- 使用vue.component()注册组件,需要提供2个参数:组件的标签名和组件构造器。
- vue.component()内部会调用组件构造器,创建一个组件实例。
- 将组建挂载到某个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>
效果截图:
上面代码中有两个注意事项:
- 组件模板的内容,可以写在一对反引号中(``),这样就可以不使用字符串拼接的形式了。
- 一个组件的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