简介
组件(Component)是 Vue.js 最强大的功能之一。它可以扩展 HTML 元素,封装可重用的代码。
组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树:
定义方法
在定义了组件后,需要将它在Vue范围内调用才能生效
全局组件
全局组件顾名思义可以在所有的vue范围内使用
Vue.component(tagName, options)
tagName:自定义组件名称
options:是一个对象,里面是组件中的配置选项(如template,data)
<div id="app">
<login></login>
</div>
<template id='tem1'>
<div>
<input type="button" value="点我" @click='add'>
<input type="button" value="show" @click='flag=!flag'>
<p v-show='flag'>{{msg}}</p>
</div>
</template>
<script>
Vue.component('login',{
template:'#tem1',
data() {
return {
msg:1,
flag:true
}
},
methods: {
add(){
this.msg++
}
},
})
new Vue({
el:'#app'
})
</script>
这里要注意在组件中定义data的数据,需要使用一个函数将你设置的数据返回出来,并且返回的必须是一个对象。
私有组件
私有组件只能在父模板中使用
components:{
'组件名称':{
.......
组件中的配置选项
}
}
<div id="app">
<test>
</div>
<div id="app1">
<test></test>
</div>
<script>
var vm = new Vue({
el:'#app',
components:{
test:{
template:`<h1>我是test中的内容</h1>`
}
}
})
var vm = new Vue({
el:'#app1'
})
</script>
可以看到局部组件只能在其父组件中调用
组件切换
在实际的项目制作中,不可能将组件全部显示在页面中,一般通过点击来调用相应的组件。通过以下方法来切换组件:
<div id="app">
<input type="button" value="login" @click="type='test1'">
<input type="button" value="register" @click="type='test2'">
<component :is="type"></component>
</div>
<script>
new Vue({
el:'#app',
data:{
type:'test1'
},
components:{
test1:{
template:'<h1>面朝大海</h1>'
},
test2:{
template:'<h1>春暖花开</h1>'
}
}
})
组件间的数据传递
Vue 的组件作用域都是孤立的,不允许在组件的模板内直接引用另一组件的数据。必须使用特定的方法才能实现组件之间的数据传递。
父子组件
在component组件的定义中,可以实现嵌套,即在一个component组件中再次定义一个component,这两个组件即为父子组件
子组件调用父组件
调用数据
子组件访问 父组件的数据:
通过在子组件身上绑定一个属性(自定义),将父组件的数据赋值给这个属性;
然后在在子组件内容 需要重新 通过props属性定义一下这个自定义的属性.
最后才可以在子组件中实现调用
<div id="app">
<!-- 在子组件上绑定一个自定义属性,属性值为要引用的数据 -->
<test :parentmsg='msg'></test>
</div>
<template id='tem'>
<div>
<p>{{parentmsg}}</p>
</div>
</template>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'我是父组件中的数据'
},
components:{
test:{
template:'#tem',
// 通过props属性重新定义该自定义属性,注意props要以数组形式
props:['parentmsg']
}
}
})
</script>
调用方法
子组件访问父组件中的方法:
通过在子组件身上绑定事件(自定义),将父组件中的方法赋值给这个自定义的事件,
然后在子组件内部通过 this.$emit(‘自定义的事件名称’) 从而就可以调用父组件中的方法
<div id="app">
<test @fun='add' :parentnum='num'></test>
</div>
<template id='tem'>
<div>
<input type="button" value="+1" @click='childadd'>
<p>{{parentnum}}</p>
</div>
</template>
<script>
new Vue({
el:'#app',
data:{
num:1
},
methods: {
add(){
console.log(this.num);
this.num+=1
}
},
components:{
test:{
template:'#tem',
props:['parentnum'],
methods: {
childadd(){
this.$emit('fun')
}
},
}
}
})
</script>
注意:如果传递的方法是改变数据的,比如(this.num++),那这个this指向的一直都是父组件中的数据,即使你在子组件中设置了同名的数据,在子组件中调用该方法,子组件中的数据也不会随方法而改变,改变的只会是父组件中的数据
子组件向父组件传递数据
传递数据
子组件向父组件传值:需要向在子组件中调用父组件中的方法,再通过this.$emit(‘自定义方法名’,要传递的数据)。再在父组件被调用的方法中添加data形参,data中的数据就是子组件传递过来的数据。再在该方法中将data数据写入父组件的data中。就可以在父组件中调用子组件中的数据
<div id="app">
<p>{{result.name}}</p>
<test @fun='parent'></test>
</div>
<script>
var test = {
template:`<input type="button" value="点我" @click='btn'>`,
data:function(){
return {
sonmsg:{
name:'小头儿子',
age:9
}
}
},
methods: {
btn(){
this.$emit('fun',this.sonmsg)
},
},
}
var vm = new Vue({
el:'#app',
data:{
result:''
},
methods:{
parent(data){
this.result=data
console.log(data);
},
},
components:{
test
}
})
</script>
注意:子组件向父组件传值,是在子组件调用父组件方法过程中的,因此想要完成子向父传值,需要在子组件中调用方法。
refs
1、ref 加在普通的元素上,用this.$refs(ref值),获取到的是dom元素
2、ref 加在子组件上,用this.$ refs(ref值)获取到的是组件实例,可以使用组件的所有方法。在使用方法的时候直接this.$refs.(ref值).方法()就可以使用了。
<div id="app">
<input type="button" value="获取" @click='get'>
<p>{{getmsg}}</p>
//给元素添加ref标签,值是自定义的
<p ref='ref1'>我是p标签</p>
<test ref='ref2'></test>
</div>
<script>
Vue.component('test',{
template:'<h1>我是子组件</h1>',
data() {
return {
msg:{
name:'子组件',
type:'component'
}
}
},
methods: {
log(){
console.log('我是子组件的方法');
}
},
})
new Vue({
el:'#app',
data:{
getmsg:''
},
methods:{
get(){
this.getmsg=[
this.$refs.ref1.innerText,
this.$refs.ref2.msg.name,
this.$refs.ref2.msg.type
]
this.$refs.ref2.log()
console.log(this.getmsg);
}
}
})
</script>