avatar

Vue-2-组件化

Vue组件化思想

  • 组件化事Vue.js中的重要思想

    • 它提供了-种抽象,让我们可以开发出一个个独立可复用的小组件来构造我们的应用。

    • 任何的应用都会被抽象成一颗组件树。

  • 组件化思想的应用

    • 有了组件化的思想,我们在之后的开发中就要充分的利用它。
    • 尽可能的将页面拆分成一个个小的、 可复用的组件。
    • 这样让我们的代码更加方便组织和管理,并且扩展性也更强。

实现

注册组件的基本步骤

小示例

  • 组件的使用分成三个步骤
    • 创建组件构造器
    • 注册组件
    • 使用组件

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="app">{{message}}
<!--3、使用组件-->
<my-cpn></my-cpn>
<my-cpn></my-cpn>
<my-cpn></my-cpn>
</div>


</body>

<script src="../js/vue.js"></script>
<script>
// 1、创建组件构造器对象
const cpnc = Vue.extend({
template: `<div>
<h2>Hello world</h2>
<p>内容</p>
</div>`
})

// 2、注册组件
Vue.component('my-cpn', cpnc)

const app = new Vue({
el: '#app',
data: {
message: '你好!!!'
}
})
</script>

全局组件和局部组件

父租件和子组件

注册组件语法糖

模板分离写法

组件访问Vue实例数据

  • 组件对象也有一个data属性(也可以有methods等属性,下面我们有用到)
  • 只是这个data属性必须是一个函数
  • 而且这个函数返回一个对象,对象内部保存着数据

组件中的data为什么是函数

父子之间的通信

  • 子组件是不能引用父组件或者Vue实例的数据的。在开发中,往往一些数据确实需要从 上层传递到下层

    • 比如在一 个页面中,我们从服务器请求到了很多的数据。
    • 其中一部分数据,并非是我们整个页面的大组件来展示的,而是需要下面的子组件进行展示。
    • 这个时候,并不会让子组件再次发送-个网络请求 ,而是直接让大组件(父组件)将数据传递给小组件(子组件)。
  • 如何进行父子组件间的通信呢? Vue官方提到

    • 通过props(properties)向子组件传递数据

    • 通过事件向父组件发送消息

在下面的代码中, 我直接将Vue实例当做父组件,并且其中包含子组件来简化代码

props 基本用法

  • 在组件中,使用选项props来声明需要从父级接收到的数据。
  • props的值有两种方式:
    • 方式一 :字符串数组,数组中的字符串就是传递时的名称。
    • 方式二:对象,对象可以设置传递时的类型,也可以设置默认值等。
数组形式

props数据验证

  • 除了数组之外,我们也可以使用对象,当需要对props进行类型等验证时,就需要对象写法了。
  • 验证都支持哪些数据类型呢?
    • String
    • Number
    • Array
    • Object
    • Data
    • Function
    • Symbol
  • 当我们有自定义构造函数时,验证也支持自定义的类型

驼峰命名格式

一般我们都是以驼峰的形式来为属性命名,当是 vue 不支持这种方式,如果想要支持那就必须更改 v-bind 名字的格式

1
2
3
<div id="app">
<cpn :c-info="info" :child-my-message="message"></cpn>
</div>

‘ - ’ 后面代表大写 解析出来的就是 childMyMessage 其他的不变

子级向父级传递

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
<body>

<!--父组件模板-->
<div id="app">
<cpn @itemclick="cpnClick"></cpn>
</div>
</body>

<!--子组件模板-->
<template id="cpn">
<div>
<button v-for="item in categories" @click="btnClick(item)">{{item.name}}</button>
</div>
</template>

<script src="../js/vue.js"></script>
<script>

// 1、 子组件
const cpn = {
template: '#cpn',
data() {
return {
categories: [
{id: 'aaa', name: '热门推荐'},
{id: 'bbb', name: '手机数码'},
{id: 'ccc', name: '家用家电'},
{id: 'ddd', name: '电脑办公'}
]
}
},
methods: {
btnClick(item) {
alert('你点击了:' + item.name + ' 发送给父组件,请求数据')
// 发送事件
this.$emit('itemclick',item)
}
}
}

// 2、 父组件
const app = new Vue({
el: '#app',
data: {
message: '你好!!!'
},
components: {
cpn
},
methods: {
cpnClick(item) {
console.log('父组件接收到子组件的消息',item)
}
}
})
</script>

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

插槽 slot

为什么使用

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
<body>
<div id="app">
<cpn><span>哈哈哈</span></cpn>
<cpn>
<span>2222</span>
<div>
<button>按钮2</button>
</div>
</cpn>
<cpn></cpn>
</div>
</body>

<template id="cpn">
<div>
<h2>我是组件</h2>
<p>我我是组件的p标签</p>
<slot>
<button>按钮</button>
</slot>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好!!!'
},
components: {
cpn: {
template: '#cpn'
}
}
})
</script>

具名插槽

定义插槽时可以为它指定一个name

当使用插槽得时候就可以根据 slot=”插槽名” 的方式指定使用的是哪一个插槽

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
<body>
<div id="app">
<cpn><span slot="center">标题</span></cpn>
<cpn><span slot="left">导航</span></cpn>
</div>
</body>

<template id="cpn">
<div>
<slot name="left">左边</slot>
<slot name="center">中间</slot>
<slot name="right">右边</slot>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好!!!'
},
components: {
cpn: {
template: '#cpn'
}
}
})
</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
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<cpn></cpn>
</div>
</body>

<template id="cpn">
<div>
<h2>我是子组件</h2>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好!!!'
},
components: {
cpn: {
template: '#cpn'
}
}
})
</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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<body>
<div id="app">
<cpn></cpn>
<cpn>
<!--目的是获取组件中得pLanguages-->
<template v-slot="slot">
<span v-for="item in slot.data">{{item}} **</span>
</template>
</cpn>

<cpn>
<!--目的是获取组件中得pLanguages-->
<template v-slot="slot">
<span>{{slot.data.join(' - ')}}</span>
</template>
</cpn>
</div>
</body>

<template id="cpn">
<div>
<slot :data="pLanguages">
<ul>
<li v-for="item in pLanguages">{{item}} --</li>
</ul>
</slot>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
const app = new Vue({
el: '#app',
data: {
message: '你好!!!'
},
components: {
cpn: {
template: '#cpn',
data() {
return {
pLanguages: ['java', 'php', 'c++', 'C#', 'go']
}
}
}
}
})
</script>
文章作者:
文章链接: https://huohuohuohuohuohuo.github.io/2020/02/27/Vue-2-组件化/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
打赏
  • 微信
    微信
  • 支付寶
    支付寶

评论