Skip to main content

可复用组件开发

详讲如何开发可复用组件。

组件系统概念

组件系统是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。 因此几乎任意类型的应用界面都可以看成一个组件树。 Component Tree

组件基础

可复用组件开发案例

【案例下载】

1. 开发规范

image-20220329085809201

2. 统一资源路径

业务构件和导出的构件代码工程的share目录基本一致。

image-20220325134319239

3. 基本示例

这里有一个 Vue 组件的示例:

image-20220329110510535

参考代码:

<template>
<button @click="count++">You clicked me {{ count }} times.</button>
</template>

<script>
import vdk from 'v3-vdk';

export default {
props: {},
data: function(){
return {
count: 0
};
},
methods:{

}
};
</script>

<style scoped lang="less"></style>

组件是可复用的 Vue 实例,且带有一个名字:在这个例子中是 <button-counter>

我们可以在一个 Vue 根实例中,引入组件,并进行注册,即可以把这个组件作为自定义元素来使用:

image-20220330102430135

4. 组件的复用

你可以将组件进行任意次数的复用:

image-20220329154840600

注意:data 必须是一个函数

当我们定义这个 <button-counter> 组件时,你可能会发现它的 data 并不是像这样直接提供一个对象:

data: {
count: 0
}

取而代之的是,一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:

data: function () {
return {
count: 0
}
}

如果 Vue 没有这条规则,点击一个按钮就可能会像如下代码一样影响到其它所有实例

image-20220329100419114

增加样式:

image-20220330103608267

5. 向子组件传递数据

5.1 传递简单数据

早些时候,我们提到了创建一个博文组件(BlogPost.vue)的事情。问题是如果你不能向这个组件传递某一篇博文的标题(title)或内容之类的我们想展示的数据的话,它是没有办法使用的。这也正是 prop 的由来。

Prop 是你可以在组件上注册的一些自定义attribute。当一个值传递给一个 props attribute 的时候,它就变成了那个组件实例的一个 property。为了给博文组件(BlogPost.vue)传递一个标题,我们可以用一个 props 选项将其包含在该组件可接受的 prop 列表中:

image-20220330084847328

参考代码:

<template>
<!-- 2. 显示自定义属性title -->
<h3>{{ title }}</h3>
</template>

<script>
import vdk from 'v3-vdk';
export default {
props: ['title'], //1.在组件上通过props注册的自定义属性title,接收父组件传给当前子组件的数据。
data: function(){
return {};
},
methods:{

}
};
</script>

<style scoped lang="less"></style>

一个组件默认可以拥有任意数量的 prop,任何值都可以传递给任何 prop。在上述模板中,你会发现我们能够在组件实例中访问这个值,就像访问 data 中的值一样。

一个 prop 被注册之后,你就可以像这样把数据作为一个自定义 attribute 传递进来:

image-20220330085859026

参考代码:

<template>
<div>
<!-- 3.使用组件 -->
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>

<blog-post title="传递给当前组件props中对应的title属性"></blog-post>
<blog-post title="你可以传入任何数据"></blog-post>
<blog-post title="你可以扩展多个属性"></blog-post>

</div>
</template>
<script>
import vdk from 'v3-vdk';
import entities from './entities.js';
//1.引入组件
import ButtonCounter from '@share/ButtonCounter'
import BlogPost from '@share/BlogPost'
export default {
//2.注册组件
components:{
'button-counter':ButtonCounter,
'blog-post':BlogPost
},
props: entities,
data: function(){
return {};
},
methods:{

}
};
</script>
<style scoped lang="less" src="./theme.less"></style>

props中也可以设置自定义属性的数据类型(type)必填项(required) 以及默认值(default)等。

props: {
//源数据
dataSource:{
type:Array,
required:true
},
//xAxisData值字段
xAxisDataField:{
type:String,
required:true
},
//xAxisShowName值字段
xAxisShowNameField:{
type: Boolean,
default: true
},
// y轴的名称
colorData: {
type:Array,
default: ['#178BFA', '#1FC39F']
},
},

5.2 传递数组数据

然而在一个典型的应用中,你可能在 data 里有一个博文的数组:

image-20220330091656386

并想要为每篇博文渲染一个组件:

<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:title="post.title"
></blog-post>

如上所示,你会发现我们可以使用 v-bind 来动态传递 prop。这在你一开始不清楚要渲染的具体内容,比如从一个 API 获取博文列表的时候,是非常有用的。

到目前为止,关于 prop 你需要了解的大概就这些了,如果你阅读完本页内容并掌握了它的内容,我们会推荐你再回来把 prop 读完。

5.3 传递实体数据

在网页窗体创建实体:

image-20220330092140090

可以批量生成测试数据然后同步到实体数据,进行部署测试:

image-20220330093401290

遍历实体,并传递实体中数据:

image-20220330092645117

部署后预览:

image-20220330094527989