【前端小程序】第九章 自定义组件

类似vue或者react中的自定义组件

  1. ⼩程序允许我们使⽤⾃定义组件的⽅式来构建⻚⾯。

1. 创建⾃定义组件

类似于页面,一个自定义组件由 wxss json wxml js 4个文件组成

  1. 可以在微信开发者⼯具中快速创建组件的⽂件结构,首先创建一个 component 文件夹用于存放自定义组件。
使用微信开发者工具快速创建组件目录结构
创建完成之后的文件结构

2. 声明组件

  1. ⾸先需要在组件的json⽂件中进⾏⾃定义组件声明;
{
  "component": true,
  "usingComponents": { // 可以使用其他组件}
}
  1. 新建一个页面使用自定义组件 ;


    自定义新的页面
  2. 在新建的页面的 json 中使用自定义组件 :

{
    "usingComponents": {
        "Tabs": "../../component/Tabs/Tabs"
    }
}
  1. wxml文件中使用引入的自定义组件:
<Tabs>
</Tabs>

3. 自定义组件-Tabs样式优化

  1. wxml代码:

<!-- 
    1. 自定义组件 - 优化组件样式
 -->

 <view class="tabs">
    <view class="title">
       <view wx:for="{{tabs}}" wx:key="{{item.id}}"  class="title-item {{item.isActive ? 'active':''}}">
        {{item.name}}
       </view>      
    </view>
    <view class="content">内容</view>
</view>
  1. 需要将tabs菜单的数据进行抽取到数组中进行遍历展示:
   // component/Tabs/Tabs.js
Component({
    /**
     * 组件的属性列表
     */
    properties: {

    },

    /**
     * 组件的初始数据
     */
    data: {

        tabs: [{
                id: 0,
                name: '首页',
                isActive: true
            },
            {
                id: 1,
                name: '原创',
                isActive: false
            },
            {
                id: 2,
                name: '分类',
                isActive: false
            },
            {
                id: 3,
                name: '关于',
                isActive: false
            },
        ]
    },

    /**
     * 组件的方法列表
     */
    methods: {

    }
})
  1. 编写样式文件 :
.title {
    display: flex;
    padding: 10rpx 0;
}

.title-item {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
}

.active {
    color: red;
    border-bottom: 5rpx solid #f00;
}

4. 实现tabs激活选中

  1. 需要为view绑定一个单击事件,并传递当前点击的item的索引 。
    <!-- 
    1. 自定义组件 - 优化组件样式
 -->

 <view class="tabs">
    <view class="title">
       <view 
         wx:for="{{tabs}}" 
         wx:key="{{item.id}}"  
         class="title-item {{item.isActive ? 'active':''}}"
         bindtap="handleItemTap"
         data-index="{{index}}">
         {{item.name}}
       </view>      
    </view>
    <view class="content">内容</view>
</view>
绑定一个点击事件,并传递当前点击的 item项的索引
  1. 处理单击事件:
     /**
     * 组件的方法列表
     */
    methods: {
        handleItemTap(e) {
            // 进行解构赋值 下面这句相当于 this.index = e.currentTarget.dataset.index
            const { index } = e.currentTarget.dataset;
            // 解构是对复杂类型进行解构的时候复制一份变量引用而已
            // 最严谨的做法就是重新拷贝一份数组再对这个数组的备份进行处理
            // 不要直接this.data.属性
            let { tabs } = this.data;
            // 下面是最严谨的写法
            // let tabs = JSON.parse(JSON.stringify(this.data.tabs));
            tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false);
            this.setData({
                tabs
            })
        }
    }
需要在methods内完成方法的编写
  1. 注意单击事件中的解构赋值:
          // 进行解构赋值 下面这句相当于 this.index = e.currentTarget.dataset.index
            const { index } = e.currentTarget.dataset;
            // 解构是对复杂类型进行解构的时候复制一份变量引用而已
            // 最严谨的做法就是重新拷贝一份数组再对这个数组的备份进行处理
            // 不要直接this.data.属性
            let { tabs } = this.data;
            // 下面是最严谨的写法
            // let tabs = JSON.parse(JSON.stringify(this.data.tabs));

5. 父组件向子组件传递数据

  1. 在父组件引用子组件的page中的标签上传递一个数据: 里面的属性名称任意,符合命名规范
 <Tabs parent="父亲"></Tabs>
  1. 在子组件的 properties 中接收父组件传递的值:
接收父组件传递的值
  1. 此时便可以在子组件的标签中直接使用该属性。

  2. 将上面的tabs数组通过父传子的方式,从父组件将数据传递到子组件:

在data域中定义一个tabs数组
父组件传递tabs数组
子组件接收父组件数据
  1. 但是以上的写法是有问题的 : 因为子组件中修改了tabs的数据,但是父组件中的数据并未实现修改:
父组件中的tabs未实现修改
  1. 实现父组件中数据的修改需要使用到子组件向父组件传递数据的方式。

6. 子组件向父组件传递数据

  1. 在父组件中定义一个父组件的自定义事件 : bindItemChange
父组件自定义事件(我使用bindItemChange这种方式好像不被支持)
查阅官方文档之后采用 bind:自定义事件名称的方式可以
  1. 子组件向父组件通过事件的方式传递数据 :
methods: {
        handleItemTap(e) {
            // 进行解构赋值 下面这句相当于 this.index = e.currentTarget.dataset.index
            const { index } = e.currentTarget.dataset;
            // 点击tabs触发事件的时候需要传递数据给父组件  this.triggerEvent("父组件自定义事件的名称",要传递的参数)
            // 子组件通过事件的方式向父组件传递数据 参数需要传递一个对象
            this.triggerEvent("itemChange", { index });
        }
    }
  1. 父组件接收子组件通过事件传递的数据 :
 handleItemChange(e) {
        // 解构
        const { index } = e.detail;
        let { tabs } = this.data;
        tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false)
        this.setData({
            // 这里 tabs 等价于 this.tabs = tabs
            tabs
        })
    }

7. slot 插槽(占位符)标签

  1. 在自定义组件中使用 slot标签进行占位 :
在自定义组件中使用slot进行占位
  1. 在父组件中定义需要显示的内容 :
根据isActive属性判断显示内容

8. 组件的其他属性

定义段 类型 是否必填 描述
properties ObjectMap 组件的对外属性,是属性名到属性设置的映射表,参⻅下⽂
data Object 组件的内部数据,和 properties⼀同⽤于组件的模板渲染
observers Object 组件数据字段监听器,⽤于监听 propertiesdata 的变化,参⻅数据监听器
methods Object 组件的⽅法,包括事件响应函数和任意的⾃定义⽅法,关于事件响应函数的使⽤,参⻅组件事件
created Function 组件⽣命周期函数,在组件实例刚刚被创建时执⾏,注意此时不能调⽤ setDatasetData ,参⻅组件⽣命周期
attached Function 组件⽣命周期函数,在组件实例进⼊⻚⾯节点树时执⾏,参⻅组件⽣命周期
ready Function 组件⽣命周期函数,在组件布局完成后执⾏,参⻅组件⽣命周期
moved Function 组件⽣命周期函数,在组件实例被移动到节点树另⼀个位置时执⾏,参⻅组件⽣命周期
detached Function 组件⽣命周期函数,在组件实例被从⻚⾯节点树移除时执⾏,参⻅组件⽣命周期
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352