30no2's Blog.

vue.js笔记三

字数统计: 2.3k阅读时长: 13 min
2021/05/21 Share

1、组件化开发

1.1、注册组件的基本步骤

  • 创建组件构造器
  • 组测组件
  • 使用组件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="app">
<m-cpn></m-cpn>
<m-cpn></m-cpn>
</div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
// 创建组件构造器对象
const cpnC = Vue.extend({
template:`
<div>
<h2>modi nobis omnis </h2>
<p>Lorem ipsum dolor sit amet!</p>
<p>Lorem ipsum dolor sit amet!</p>
<p>Lorem ipsum dolor sit amet!</p>
</div>
`
});
// 注册主键
Vue.component('m-cpn',cpnC)
</script>

说明:组件必须定义在某个vue实例下,否则不生效

1.2、全局组件和局部组件

当用Vue.component()注册主键的时候,组件的注册是全局的。意味着可以在任意的vue下使用

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
<div id="app1">
<my-cpn></my-cpn>
</div>
<div id="app2">
<my-cpn></my-cpn>
</div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const cpn = Vue.extend({
template:`
<div>
<h2>Lorem ipsum dolor sit amet</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus, architecto dolorum eaque est hic ipsam,
laudantium magni modi mollitia quibusdam reiciendis repudiandae saepe sapiente totam, velit veritatis voluptate?
Alias, hic.</p>
</div>
`
})
Vue.component('my-cpn',cpn)
let app1 = new Vue({
el:'#app1',
});
let app2 = new Vue({
el:'#app2'
})
</script>

如果挂载在某个实例中,则这就是一个局部组件

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
<div id="app1">
<my-cnf></my-cnf>
</div>
<div id="app2">
<!-- 不起作用-->
<my-cnf></my-cnf>
</div>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
let cnf = Vue.extend({
template:`
<div>
<h2>Lorem ipsum dolor sit amet</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus, architecto dolorum eaque est hic ipsam,
laudantium magni modi mollitia quibusdam reiciendis repudiandae saepe sapiente totam, velit veritatis voluptate?
Alias, hic.</p>
</div>
`
})
const app1 = new Vue({
el:'#app1',
components:{
'my-cnf':cnf
}
});
const app2 = new Vue({
el:'#app2',
})
</script>

1.3、父组件和子组件

一个组件中,定义另一个组件

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
<div id="app">
<parent-cpn></parent-cpn>
</div>

<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
let childCpn = Vue.extend({
template:`
<div>
<h2>Lorem ipsum dolor sit amet</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus, architecto dolorum eaque est hic ipsam,
laudantium magni modi mollitia quibusdam reiciendis repudiandae saepe sapiente totam, velit veritatis voluptate?
Alias, hic.</p>
</div>
`
})

let parentCpn = Vue.extend({
template:`
<div>
<h1>Lorem ipsum dolor sit amet</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus, architecto dolorum eaque est hic ipsam,
laudantium magni modi mollitia quibusdam reiciendis repudiandae saepe sapiente totam, velit veritatis voluptate?
Alias, hic.</p>
<child-cpn></child-cpn>
</div>
`,
components:{
'child-cpn':childCpn
}
})
Vue.component('parent-cpn',parentCpn)
const app = new Vue({
el:'#app',
data:{
message:"hello vue"
}
});
</script>

1.4、注册主键语法糖

简单写法中省去了Vue.extend()的步骤

可以直接用一个对象来代替

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
<div id="app">
<parent-cpn></parent-cpn>
</div>

<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
Vue.component('parent-cpn',{
template:`
<div>
<h1>Lorem ipsum dolor sit amet</h1>
<p>Lorem ipsum dolor sit amet</p>
<child-cpn></child-cpn>
</div>
`,
components:{
'child-cpn': {
template:`
<div>
<h2>Lorem ipsum dolor sit amet</h2>
<p>Lorem ipsum </p>
</div>
`
}
}
})
const app = new Vue({
el:'#app',
data:{
message:"hello vue"
}
});
</script>

1.5、模板的分离

  • 组件中数据存放问题:需要用函数返回,而不是数组。因为为了调用组件时每次调用都是一个新的组件,并且组件中相互不影响,则需要用函数表示。
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
<div id="app">
<parent-cpn></parent-cpn>
</div>
<script type="text/x-template" id="myCpn">
<div>
<h1> Lorem ipsum dolor sit amet1</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<child-cpn></child-cpn>
</div>
</script>

<template id="myCpn2">
<div>
<h2> Lorem ipsum dolor sit amet</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit1.</p>
</div>
</template>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"hello vue"
},
components: {
'parent-cpn':{
template: `#myCpn`,
components: {
'child-cpn':{
template: '#myCpn2'
}
}
}
}
});
</script>

1.6、组件不能直接访问Vue的实例

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
<div id="app">
<parent-cpn></parent-cpn>
</div>
<script type="text/x-template" id="myCpn">
<div>
<h1> {{title}}</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<child-cpn></child-cpn>
</div>
</script>

<template id="myCpn2">
<div>
<h2> Lorem ipsum dolor sit amet</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit1.</p>
</div>
</template>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"hello vue"
},
components: {
'parent-cpn':{
data(){
return {
title:'hhh'
}
},
template: `#myCpn`,
components: {
'child-cpn':{
template: '#myCpn2'
}
}
}
}
});
</script>

1.7、组件通信——父组件向子组件发消息

  • 在组件中,使用选项props来声明需要从父级接收到的数据
  • props的值有两种方式
    • 方式一:字符串数组,数组中的字符串就是传递时的名称
    • 方式二:对象,对象可以设置传递时的类型,也可以设置默认值等。
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
<div id="app">
<h1>{{ message }}</h1>
<parent v-bind:cmovie="movie" v-bind:cmessage = "message"></parent>
</div>

<!--注意。模板要放在根组件中-->
<template id="parent">
<div>
<h2>{{title}}</h2>
<p>{{cmessage}}</p>
<p>
<ul>
<li v-for="item in cmovie">{{item}}</li>
</ul></p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. At autem, consequuntur cumque earum est ex incidunt iusto, magni pariatur provident rerum sequi temporibus veritatis. Commodi ea itaque iure placeat voluptas!</p>
</div>
</template>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"这是一个测试",
movie:['mov1','mov2','mov3']
},
components:{
'parent': {
// props:['cmovie'], //第一种写法
// props:{
// cmovie:Array, //第二种写法,对传递的数据进行验证
// cmessage:'aaaaa'
// },
//
props:{ //第二种写法,可以增加增加类型和默认值
cmovie:{
type:Array,
default:['aaaa']
},
cmessage:{
type:String,
default: 'sss'
}
},
template:`#parent`,
data(){
return {
title:'标题2'
}
}
}
}
});
</script>

1.8、组件通信——子组件向父组件传递数据

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
<div id="app">
<div>{{ message }}</div>
<!--通过子组件item-click的监听,用父组件中cpnclick进行操作-->
<cpn v-on:item-click="cpnclick"></cpn>
</div>
<template id="cpn">
<div>
<button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button>
</div>
</template>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
//子组件
const cpn = {
template: '#cpn',
data(){
return {
categories:[
{id:1,name:'n1'},
{id:2,name:'n2'},
{id:3,name:'n3'},
{id:4,name:'n4'},
]
}
},
methods:{
btnClick(item){
// console.log(item);
// 通过@emit()事件发送数据到父组件
this.$emit('item-click',item)
}
}
}
const app = new Vue({
el:'#app',
data:{
message:"hello vue"
},
components:{
cpn
},
methods:{
cpnclick(item){
console.log(item);
}
}
});
</script>

1.9、父子组件的访问方式:$children

  • 父组件访问子组件:使用$children 或者$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
    <div id="app">
    <div>{{ message }}</div>
    <button @click="btnClick">按钮</button>
    <cpn ref="aaa"></cpn>
    </div>

    <template id="cpn">
    <div>
    <div>我是子组件</div>

    </div>
    </template>
    <!--导入vue.js-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
    <script>
    const app = new Vue({
    el:'#app',
    data:{
    message:"hello vue"
    },
    methods:{
    btnClick(item) {
    //1 $child
    console.log(this.$children);
    this.$children[0].showMessage();
    console.log(this.$children[0].name);
    //2 定义ref
    this.$refs.aaa.showMessage()
    console.log(this.$refs.aaa.name);
    }
    },
    components:{
    cpn:{
    template:`#cpn`,

    data(){
    return {
    name:'我是子组件name'
    }
    },
    methods:{
    showMessage(){
    console.log('showMessage');
    }
    }
    }
    }
    });
    </script>
  • 子组件访问父组件:使用$parent

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
<div id="app">
<cpn></cpn>
</div>

<template id="cpn">
<div>
<div>我是子组件</div>
<button @click="btnClick">按钮</button>
<ccpn></ccpn>
</div>
</template>

<template id="ccpn">
<button @click="btnClick2">按钮2</button>
</template>
<!--导入vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
const app = new Vue({
el:'#app',
data:{
message:"hello vue"
},
components:{
cpn:{
template:`#cpn`,
data(){
return {
'name':'eee'
}
},
methods:{
btnClick(){
// 1访问父组件
console.log(this.$parent);
console.log(this.$parent.message);
}
},
components: {
ccpn:{
template: `#ccpn`,
methods: {
btnClick2(){
this.$parent.btnClick()
console.log(this.$parent.name)
console.log(this.$root.message)
}
}
}
}
}
}
});
</script>
CATALOG
  1. 1. 1、组件化开发
    1. 1.1. 1.1、注册组件的基本步骤
    2. 1.2. 1.2、全局组件和局部组件
    3. 1.3. 1.3、父组件和子组件
    4. 1.4. 1.4、注册主键语法糖
    5. 1.5. 1.5、模板的分离
    6. 1.6. 1.6、组件不能直接访问Vue的实例
    7. 1.7. 1.7、组件通信——父组件向子组件发消息
    8. 1.8. 1.8、组件通信——子组件向父组件传递数据
    9. 1.9. 1.9、父子组件的访问方式:$children