5.21

1.组件化基本使用:

(1)创建组件构造器对象:

1
2
3
4
5
6
7
8
const cpnC = Vue.extend({
//template:组件自定义的模板。
template: "<div>\n" +
" <h2>我是标题</h2>\n" +
" <p>我是内容1</p>\n" +
" <p>我是内容2</p>\n" +
" </div>"
})

(2)注册组件

1
Vue.component('my-cpn',cpnC)

(3)实例化Vue

1
2
3
4
5
6
const app = new Vue({
el:'#app',
data:{

}
})

2.模板的分离写法:

  • script标签

    1
    2
    3
    4
    5
    <script type="text/x-template" id="cpn">
    <div>
    <h2>我是标题</h2>
    </div>
    </script>
    1
    2
    3
    4
    //直接注册全局组件,创建构造器的过程有上面替代,利用script的方法
    Vue.component('my-cpn',{
    template:"#cpn"
    })
  • template标签

    1
    2
    3
    4
    5
    <template id="cpn">
    <div>
    <h2>我也是标题</h2>
    </div>
    </template>
    1
    2
    3
    4
    //直接注册全局组件,创建构造器的过程有上面替代,利用template的方法
    Vue.component('my-cpn',{
    template:"#cpn"
    })

3.组件不能访问Vue实例中的data:

组件有自己的data

4.组件中data必须是函数:

1
2
3
4
5
6
7
8
Vue.component("cpn",{
template:'#cpn',
data(){
return {
counter:0
}
}
})

data函数返回值是一个对象,每次实例化一个组件,这个组件就会返回一个独立的对象,各个组件互不影响

1
2
3
4
//如果data只是简单的是一个值或者一个对象的话
data:{
message:'name'
}

对该组件的修改会影响到其他组件,这肯定不行啊。

所以data不是函数的话会直接报错,就不给你这个机会。

5.父子传参

  • 首先要在父组件上面定义要传递的参数,比如本例的message(定义在data里面)
  • 子组件定义,利用<template>模板将子组件进行定义,在props属性中,定义用于==接收父组件参数==的==子组件参数==
  • 在components中,将子组件的名称写上去,说明关系,这个组件是父组件的子组件
  • 此时,在子组件中,就可以使用父组件中的参数了(data中的内容)
  • 使用的时候需要在子组件的实例中,声明子组件参数与父组件参数的对应关系:cmessage='message'必须要添加v-bind:指令进行绑定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<cpn :cmovies="movies" :cmessage="message"></cpn>
</div>
<template id="cpn">
<div>
<!-- 子元素中有父元素的值,这就是父传子-->
<p>{{cmovies}}</p>
<h2>{{cmessage}}</h2>
</div>
</template>
<script src="vue.js"></script>
<script>
const cpn = {
template: "#cpn",
props: ['cmovies', 'cmessage'],
data() {
return {}
}
}
const app = new Vue({
el: '#app',
data: {
message: '你好',
movies: ['海王', '海贼王']
},
components: {
cpn
}
})
</script>
</body>
</html>

props:的几种写法:

1
2
//数组
props:['cmovies','cmessage']
1
2
3
4
5
6
7
8
9
10
11
//对象
props:{
//1.类型限制:
cmovies:Array,
cmessage:String,
//2.提供默认值:
vmessage:{
type:String,
default:'aaaa',
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//带有默认值的对象
props:{
type:object,
default(){
return {message:'hello'}
}
}
//自定义验证函数
props:{
validator(value){
return ['success','warning','danger'].indexOf(value) !== -1
}

}
1
2
3
4
5
6
7
8
9
10
//自定义类型
person(firstName,lastName)=>{
this.firstName = firstName
this.lastName = lastName
}
Vue.component('blog-post',{
porps:{
author:Person
}
})

6.子传父

  • 子传父一般是传递一个事件,然后由父组件向服务器进行请求

  • 首先子组件定义一个点击@click事件,并向事件传递一个对象参数,事件的名称是btnclick

  • 接着在子组件中的methods方法中,对btnclick方法进行定义this.$emit('itemclick', item),他利用this.$emit发送一个事件,事件名称叫itemclick

  • 然后父组件中对事件进行监听,@intemclick='cpnclick'当监听到itemclick事件时,调用cpnclick函数。

  • 接着在父组件中对cpnclick方法进行定义,因为在监听的时候填的@itemclick='cpnclick'中并没有填参数,所以传递过来的是默认参数==我写的自定义事件传过来的值==

    此处再引申一下,如果是button标签中的btnclick事件不填参数的话默认传过去的参数是event事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 父组件-->
<div id="app">
<cpn @itemclick="cpnclick"></cpn>
</div>
<!--子组件模板-->
<template id="cpn">
<div>
<button v-for="item in categories" @click="btnclick(item)">{{item.name}}</button>
</div>
</template>
<script src="vue.js"></script>
<script>
// 子组件
const cpn = {
template: '#cpn',
data() {
return {
categories: [
{id: 'aa', name: '热门推荐'},
{id: 'bb', name: '手机数码'},
{id: 'cc', name: '家用电器'},
{id: 'dd', name: '电脑办公'},

]
}
},
methods: {
btnclick(item) {
this.$emit('itemclick', item)
}
}
}
// 父组件
const app = new Vue({
el: '#app',
data: {
messsage: '你好'

},
components: {
cpn
},
methods: {
cpnclick(item) {
console.log('cpnclick', item);
}
}
})
</script>
</body>
</html>

7.用户输入:

input监听用户输入的事件:@input,其默认传入的值是event,获取用户输入的内容:envent.target.value

8.访问子组件:

通过$refs,具体用法就是在子组件中添加refs='aaa'属性

$refs是对象类型,默认是一个空的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>

<body>
<div id="app">
<cpn></cpn>
<cpn ref="aaa"></cpn>
<cpn ref="bbb"></cpn>
<button @click="btnClick">按钮</button>

</div>
<template id="cpn">
<div>我是子组件</div>
</template>
<script src="../Vue/vue.js"></script>
<script>
const cpn = {
template: '#cpn',
data() {
return {

}
},
methods: {
showMessage() {
console.log("showMessage");
}
},

}
const app = new Vue({
el: '#app',
data: {

},
components: {
cpn
},
methods: {
btnClick() {
console.log(this.$refs.aaa);
this.$refs.aaa.showMessage();
}
}
})

</script>
</body>

</html>

如上例所写,在父组件中,可以通过this.$refs.aaa找到子组件中refaaa