Vue组件
组件化是Vue.js中的重要思想
它提供了一种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。
任何的应用都会被抽象成一颗组件树。
注册组件
<body>
<div id="app">
<!--3、使用组件-->
<my-cpn></my-cpn>
</div>
</body>
<script>
//1、创建组件构造器
const myComponent = Vue.extend({
template:`
<div>
<h2>组件标题</h2>
<p>组件的一个段落</p>
</div>
`
});
//2、注册组件,定义组件标签名称
Vue.component('my-cpn',myComponent)
var app = new Vue({
el: '#app',
data: {
}
})
</script>
如下图:
1.Vue.extend():调用Vue.extend()创建的是一个组件构造器。
通常在创建组件构造器时,传入template代表我们自定义组件的模板。
该模板就是在使用到组件的地方,要显示的HTML代码。
2.Vue.component(): 调用Vue.component()是将刚才的组件构造器注册为一个组件,并且给它起一个组件的标签名称。
所以需要传递两个参数:1、注册组件的标签名 2、组件构造器
3.组件必须挂载在某个Vue实例下,否则它不会生效。
全局组件和局部组件
全局组件
<body>
<div id="app">
<!--3、使用组件-->
<my-cpn></my-cpn>
</div>
<div id="app1">
<!--3、使用组件-->
<my-cpn></my-cpn>
</div>
</body>
<script>
//1、创建组件构造器
const myComponent = Vue.extend({
template:`
<div>
<h2>组件标题</h2>
<p>组件的一个段落</p>
</div>
`
});
//2、注册组件,定义组件标签名称(注册全局组件)
Vue.component('my-cpn',myComponent)
var app = new Vue({
el: '#app',
data: {
}
})
var app1 = new Vue({
el: '#app1',
data: {
}
})
</script>
如下图:
局部组件
<body>
<div id="app">
<!--3、使用组件-->
<p>Vue实例app</p>
<my-cpn></my-cpn>
</div>
<div id="app1">
<!--3、使用组件-->
<p>Vue实例app1</p>
<my-cpn></my-cpn>
</div>
</body>
<script>
//1、创建组件构造器
const myComponent = Vue.extend({
template:`
<div>
<h2>组件标题</h2>
<p>组件的一个段落</p>
</div>
`
});
var app = new Vue({
el: '#app',
//组件局部注册
components: {
'my-cpn':myComponent
},
data: {
}
})
var app1 = new Vue({
el: '#app1',
data: {
}
})
</script>
父组件和子组件
</body>
<script>
//1、创建组件构造器
const childComponent = Vue.extend({
template:`
<div>
<h2>child组件标题</h2>
<p>组件的一个段落</p>
</div>
`
});
//1、创建组件构造器
const myComponent = Vue.extend({
template:`
<div>
<h2>组件标题</h2>
<p>组件的一个段落</p>
<child-cpn/>
</div>
`,
components:{
//子组件
'child-cpn':childComponent
}
});
var app = new Vue({
el: '#app',
//组件局部注册
components: {
// 父组件
'my-cpn':myComponent
},
data: {
}
})
</script>
如下图:
注册组件语法糖
<body>
<div id="app">
<p>Vue实例app</p>
<my-cpn></my-cpn>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
components: {
'my-cpn': {
template: '<div>组件my-cpn</div>'
},
'child-cpn': {
template: '<div>组件child-cpn</div>'
}
},
data: {}
})
</script>
模板分离写法
使用 template标签
</body>
<template id="myComponent">
<div>
<p>myComponent组件</p>
</div>
</template>
<script>
var app = new Vue({
el: '#app',
components: {
'my-cpn': {
template: '#myComponent'
}
},
data: {}
})
</script>
组件数据存放
</body>
<template id="myComponent">
<div>
<p>myComponent组件</p>
{{message}}
{{count}}
<button @click="add">add</button>
</div>
</template>
<script>
var app = new Vue({
el: '#app',
components: {
'my-cpn': {
template: '#myComponent',
data() {
return {
message : '组件数据message',
count : 0
}
},
methods : {
add(){
this.count ++
}
}
}
}
})
</script>
如下图:
子父组件通信
如何进行父子组件间的通信呢?
Vue官方提到1、通过props向子组件传递数据2、通过事件向父组件发送消息
父组件向子组件传递数据–props用法
props的值有两种方式
方式一:字符串数组,数组中的字符串就是传递时的名称。
方式二:对象,对象可以设置传递时的类型,也可以设置默认值等。
字符串数组
<body>
<div id="app">
<p>Vue实例app</p>
<!--动态绑定属性-->
<my-cpn :message="message" :name="name" :age="age"></my-cpn>
</div>
</body>
<template id="myComponent">
<div>
<p>myComponent组件</p>
{{message}} --{{name}}--{{age}}
</div>
</template>
<script>
var app = new Vue({
el: '#app',
data: {
message : 'hello world',
name : 'zhangsan',
age : 11
},
components: {
'my-cpn': {
template: '#myComponent',
props:['message','name','age']
}
}
})
</script>
如下图:
对象
对props进行类型等验证时,就需要对象写法
</body>
<template id="myComponent">
<div>
<p>myComponent组件</p>
{{message}} --{{name}}--{{age}}
</div>
</template>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'hello world',
name: 'zhangsan',
age: 11
},
components: {
'my-cpn': {
template: '#myComponent',
props: {
message: {
type: String,
default: 'message'
},
name: {
type: String,
default: 'zhangsan'
},
age: {
type: Number,
default: 10
}
}
}
}
})
</script>
子组件向父组件传值
通过自定义事件来完成该操作
e
m
i
t
用法:
v
m
.
emit用法: vm.
emit用法:vm.emit( event, arg ) //触发当前实例上的事件 arg为参数
</body>
<template id="myComponent">
<div>
<button @click="add">+</button>
<button @click="del">-</button>
</div>
</template>
<script>
var app = new Vue({
el: '#app',
data: {
total: 0
},
methods: {
getTotal(count){
this.total = count
}
},
components: {
'my-cpn': {
template: '#myComponent',
data(){
return {
count : 0
}
},
methods :{
add(){
this.count ++
this.$emit('add',this.count)
},
del(){
this.count --
this.$emit('del',this.count)
}
}
}
}
})
</script>
如下图:
父子组件访问
$refs
<body>
<div id="app">
<p>Vue实例app</p>
{{message}}
<button @click="getMessage">点击获取子组件message</button>
<my-cpn ref="myComponent"></my-cpn>
</div>
</body>
<template id="myComponent" >
<div>
<p>myComponent组件</p>
{{message}}
</div>
</template>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'hello world'
},
methods: {
getMessage(){
this.message = this.$refs.myComponent.message
}
},
components: {
'my-cpn': {
template: '#myComponent',
data(){
return {
message:'hello abc'
}
}
}
}
})
</script>
如下图:
$children
<body>
<div id="app">
<my-cpn></my-cpn>
</div>
</body>
<template id="myComponent" >
<div>
<p>myComponent组件</p>
{{message}}
<button @click="change">获取子组件message</button>
<child-cpn></child-cpn>
</div>
</template>
<template id="childComponent" >
<div>
<p>childComponent</p>
{{message}}
</div>
</template>
<script>
var app = new Vue({
el: '#app',
components: {
'my-cpn': {
template: '#myComponent',
data(){
return {
message:'parent'
}
},
methods: {
change(){
this.message = this.$children[0].message
}
},
components: {
'child-cpn' :{
template: '#childComponent',
data(){
return {
message:'child'
}
}
}
}
},
}
})
</script>
如下图:
子组件访问父组件
$parent
<body>
<div id="app">
<my-cpn></my-cpn>
</div>
</body>
<template id="myComponent" >
<div>
<p>myComponent组件</p>
{{message}}
<child-cpn></child-cpn>
</div>
</template>
<template id="childComponent" >
<div>
<p>childComponent</p>
{{message}}
<button @click="change">获取父组件message</button>
</div>
</template>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'hello world'
},
methods: {
getMessage(){
this.message = this.$refs.myComponent.message
}
},
components: {
'my-cpn': {
template: '#myComponent',
data(){
return {
message:'parent'
}
},
components: {
'child-cpn' :{
template: '#childComponent',
data(){
return {
message:'child'
}
},
methods: {
change(){
this.message = this.$parent.message
}
}
}
}
},
}
})
</script>
如下图: