>[success] # 组件开发
1. 从`v1.6.3`开始, 小程序开始支持自定义组件开发, 也让我们更加方便的在程序中使用组件化
>[info] ## 创建组件
1. 自定义组件由 **json wxml wxss js** 4个文件组成。
2. 先需要在 `json `文件中进行自定义组件声明(将`component` 字段设为 `true `可这一组文件设为自定义组件)
3. 在`wxml`中编写属于我们组件自己的模板
4. 在`wxss`中编写属于我们组件自己的相关样式
5. 在`js`文件中, 可以定义数据或组件内部的相关逻辑
6. 页面引用自定义组件需要在`对应页面.json` 文件的`usingComponents` 字段配置,`key `为组件名,`value`为地址
~~~
{
"usingComponents": {
"section-info": "/components/section-info/section-info",
"test-style": "/components/test-style/test-style",
"tab-control": "/components/tab-control/tab-control"
}
}
~~~
7. 全局在`app.json`的`usingComponents`声明某个组件,那么**所有页面和组件可以直接使用该组**
8. **自定义组件也是可以引用自定义组件的**,引用方法类似于页面引用自定义组件的方式(使用`usingComponents `字段)
9. 自定义组件和页面所在项目根目录名 不能以 **wx-** 为前缀,否则会报错
>[danger] ##### 组件案例
* 在组件的json文件声明`component `字段 为true
![](https://img.kancloud.cn/d8/c0/d8c0db3a5b414d3c3d643a37a4f93a1c_682x250.png)
* 像编写页面一样编写组件
![](https://img.kancloud.cn/d3/a7/d3a7fa076a690295994c0817d6969b4f_603x246.png)
* 如果只是指定页面用在指定页面的`index.json` `usingComponents` 编写组件导入
![](https://img.kancloud.cn/e8/da/e8da039e7d21693f599330857cb9cc7d_794x368.png)
* 导入后就可以直接在对应页面使用
![](https://img.kancloud.cn/35/bd/35bd074b4fc344ca79ac98a5ca28899e_613x313.png)
>[info] ## 组件的样式
1. 组件内的class样式,只对组件wxml内的节点生效, 对于引用组件的Page页面不生效
2. 组件内不能使用**id选择器、属性选择器、标签选择器**,就正常使用class 选择器就好
>[danger] ##### 组件和页面样式影响
1. 外部使用`class`的样式,只对外部`wxml`的`class`生效,对组件内是不生效的
2. 外部使用了`id`选择器、**··**
3. 外部使用了**标签选择器,会对组件内产生影响**
4. 通过设置`Component`对象中,可以传入一个`options`属性个`styleIsolation`(隔离)属性
* `isolated `表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(默认取值)
* `apply-shared` 表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面;
* `shared `表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置 了
![](https://img.kancloud.cn/29/aa/29aa997540d0b5bed776ca47777131bb_711x512.png)
>[info] ## 组件的通信
1. 很多情况下,组件内展示的内容(数据、样式、标签),并不是在组件内写死的,而且可以由使用者来决定
![](https://img.kancloud.cn/1d/5e/1d5eae4b40cb8b06e9561dc4bd47a1de_954x336.png)
~~~js
Component({
options: {
styleIsolation: "shared"
},
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})
~~~
>[danger] ##### 向组件传递数据 - properties
1. 通过**从外部传递数据给我们的组件**,使用`properties`属性
2. 通过type 设置类型支持类型,String、Number、Boolean、Object、Array、null(不限制类型)
3. 可以通过`value`设置默认值
![](https://img.kancloud.cn/73/5b/735bb45a680523c8700509083cacadb0_634x474.png)
![](https://img.kancloud.cn/07/3e/073e7655d2ba2163148d288d629383ab_644x396.png)
* 页面展示
![](https://img.kancloud.cn/38/72/38722226705b6b1a0d56cc43974ef463_417x94.png)
>[danger] ##### 向组件传递样式 - externalClasses
1. 有时候,我们不希望将样式在组件内固定不变,而是外部可以决定样式
2. 在`Component`对象中,定义`externalClasses`属性
![](https://img.kancloud.cn/84/33/84333d9774229545703fd9437e6f5799_358x150.png)
3. 在组件内的`wxml`中使用`externalClasses`属性中的class
![](https://img.kancloud.cn/b3/48/b3488112c7bb31b96704a0cf9fb5f5cc_737x125.png)
4. 在页面中传入对应的`class`,并且给这个`class`设置样式
![](https://img.kancloud.cn/47/06/47060073a9a4ca1ef2dae349406b247d_282x56.png)
>[danger] ##### 组件向外传递事件 – 自定义事件
1. 在组件的 js 文件的method 属性中定义方法
2. 将方法传递触发父组件 和 vue 类似但不同是从 `emit `变成`triggerEvent`
3. 父组件绑定暴露出的方法 和 vue 类似但不同从 `on` 变成了`bind:`
4. 接受传参过来值使用`event.detail`
![](https://img.kancloud.cn/e1/97/e197db511becb60c7decd8c8d3258174_863x310.png)
![](https://img.kancloud.cn/16/8d/168d7c43e7adacbf1a10728ff5e98204_962x325.png)
![](https://img.kancloud.cn/e8/53/e853d46fac68a0791dc9ec2089a1d494_1092x498.png)
![](https://img.kancloud.cn/b0/61/b0615bbc548fa0b42b6c234a297a5bb2_922x331.png)
>[info] ## 综合案例
>[danger] ##### 组件 部分
* 定义组件
~~~
{
"component": true,
"usingComponents": {}
}
~~~
~~~
// componets/tab/tab.js
Component({
/**
* 组件的属性列表
*/
properties: {
titles:{
type:Array,
value:[]
}
},
/**
* 组件的初始数据
*/
data: {
currentIndex:0
},
/**
* 组件的方法列表
*/
methods: {
onItemTap(event){
const {index} = event.currentTarget.dataset
this.setData({currentIndex:index})
// 将值暴露出去
this.triggerEvent('changeIndex',index)
}
}
})
~~~
~~~html
<!--componets/tab/tab.wxml-->
<view class="tab">
<block wx:for="{{titles}}" wx:key="item">
<view class="tab-item" bindtap="onItemTap" data-index="{{index}}">
<text class="tab-item-text {{ index==currentIndex? 'active':''}}">{{item}}</text>
</view>
</block>
</view>
~~~
~~~
.tab{
display: flex;
line-height: 32px;
height: 32px;
}
.tab-item{
flex: 1;
text-align: center;
}
.tab-item-text{
padding: 5px;
}
.tab-item-text.active{
border-bottom: 2px solid yellowgreen;
}
~~~
>[danger] ###### 使用
~~~
Page({
/**
* 页面的初始数据
*/
data: {
titles:["数学","语文","英语","物理"],
},
changeIndex(event){
console.log("区域title发生了点击", event.detail);
}
})
~~~
~~~html
<tabs titles="{{titles}}" bind:changeIndex="changeIndex"></tabs>
~~~
* 注册
~~~
{
"usingComponents": {
"tabs":"/componets/tab/tab"
}
}
~~~
- 小程序了解
- webview 是什么
- Native App、Web App、Hybrid App
- 小程序架构模型
- 小程序配置文件
- app.js -- App函数
- 页面.js -- page
- 生命周期????
- 小程序 -- 页面wxml
- 小程序 -- WXS
- 小程序 -- 事件
- 小程序 -- 样式wxss
- 小程序 -- 组件开发
- 小程序 -- 组件插槽
- 小程序 -- 组件的生命周期
- 组件总结
- 小程序 -- 混入
- 小程序基本组件
- text -- 文本
- view -- 视图容器
- button -- 按钮
- image -- 图片
- scroll-view -- 滚动容器
- input -- 双向绑定
- 通用属性
- 小程序常用Api
- 微信网络请求
- 微信小程序弹窗
- 微信小程序分享
- 获取设备信息 / 获取位置信息
- Storage存储
- 页面跳转
- 小程序登录