微信小程序-自定义组件


注:详情使用方法见官方文档:微信开放文档/开发-自定义组件
小程序基础组件见文章- 微信小程序开发-各组件


开发者常见的自定义组件有两种:
1、公共组件: 将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;
2、页面组件: 将复杂的页面拆分成多个低耦合的模块,有助于代码维护。

自定义组件在使用时与基础组件非常相似。

一、自定义组件-创建、注册、使用组件

1、创建自定义组件:
  • 如果是公共组件,建议放在项目根目录的 components 文件夹中
  • 如果是页面组件,建议放在对应页面的目录下

建议: 一个组件一个文件夹

自定义组件创建完成后,还不能使用,需要进行注册

2、注册自定义组件:
  • 如果是公共组件,需要全局注册: 在 app.json 文件中配置 usingComponents 进行注册,注册后可以在任意页面使用
  • 如果是页面组件,需要局部注册: 在 .json 文件中配置 usingComponents 进行注册,注册后只能在当前页面使用

在 usingComponents 中进行组件注册时,需要提供自定义组件的组件名和自定义组件文件路径

3、使用自定义组件:

将组件注册注册好以后,直接将 自定义组件的组件名 当成 组件标签名 使用即可
在这里插入图片描述

二、自定义组件的数据、方法和属性 properties

自定义组件的数据以及方法需要在组件.js文件中的 Component 方法中进行定义。
Component 构造器可用于定义组件,调用 Component 构造器时可以指定组件的属性、数据、方法等
1、data: 定义组件的内部需要使用的数据
2、methods: 在组件中事件处理程序需要写到 methods 中
3、properties: 是指组件的对外属性,主要是用来接收组件使用者传递给组件内部的数据,和 data 一同用于组件的模板渲染

app.json 文件代码示例:

"usingComponents": {
    "custom-checkbox": "./components/custom-checkbox/custom-checkbox"
  }

page.wxml 文件代码示例:

<!-- 
  label:文本显示的内容
  position:控制文本显示的位置
 -->
<custom-checkbox label="我已阅读并同意 用户协议 和 隐私协议" position="right" />
<view></view>
<custom-checkbox label="匿名提交" position="left" />

custom-checkbox.wxml 文件代码示例:

<view class="custom-checkbox-container">
  <view class="custom-checkbox-box {{ position === 'right' ? 'right' : 'left'}}" >
    <checkbox class="custom-checkbox" checked="{{ isChecked }}" bind:tap="updateChecked"/>
  <view>
    <text>{{ label }}</text>
  </view>
  </view>
</view>

custom-checkbox.js 文件代码示例:

Component({
  /**
   * 组件的属性列表:是指组件的对外属性,主要是用来接收组件使用者传递给组件内部的数据与属性
   */
  properties: {
    // 如果需要传递的是属性,有两种方式:简写和全写
    // 简写:
    // label: String
    // 全写:
    label: {
      // type 组件使用者传递的数据类型,是必填项
      // 数据类型:String、Number、Boolean、Object、Array
      // 也可以设置为 null,表示不限制类型
      type: String,
      // value 属性值为默认值
      value: ""
    },
    position: {
      type: String,
      value: "right"
    }
  },
  /**
   * 组件的初始数据:定义组件的内部需要使用的数据
   */
  data: {
    isChecked: false
  },
  /**
   * 组件的方法列表:在组件中事件处理程序需要写到 methods 中可以
   */
  methods: {
    // 更新复选框的状态
    updateChecked() {
      this.setData({
        isChecked: !this.data.isChecked,
        // 在 JS 中可以访问和获取 properties 中的数据,但一般情况下不建议修改,因为会造成数据流的混乱
        // label: '在组件内部也可以修改 properties 中的数据'
      })
      console.log(this.properties.label)
    }
  }
})

custom-checkbox.scss 文件代码示例:

.custom-checkbox-container {
  display: inline-block;
}
.custom-checkbox-box {
  display: flex;
  align-items: center;
}
.custom-checkbox-box.left {
  flex-direction: row-reverse;
}
.custom-checkbox-box.right {
  flex-direction: row;
}
.custom-checkbox {
  margin-left: 10rpx;
}

三、自定义组件的 slot-插槽

在使用基础组件时,可以在组件中间写子节点,从而将子节点的内容展示到页面中,自定义组件也可接收子节点。
只不过在自定义组件模板中,需要定义 <slot />节点,用于承载组件中间的子节点

默认情况下,一个组件的 wxml 中只能有一个 slot (默认卡槽)。需要使用多 slot 时,可以在组件 js 中声明启用。
同时需要给 slot 添加 name 属性,以不同的 name 来区分不同的 slot(具名卡槽)。
然后给子节点内容添加 slot 属性,属性值是对应 slot 的 name 名称,从而将内容插入到对应的 slot 中。
在这里插入图片描述
app.json 文件代码示例:

"usingComponents": {
   "custom01": "./components/custom01/custom01"
  }

page.wxml 文件代码示例:

<custom01>
<!-- 默认情况下,自定义组件的子节点不会展示,如果内容需要展示,需要在组件模板中定义 slot 节点 -->
  <text slot="slot-top">我需要显示到顶部-具名卡槽</text> 
  我是子节点内容--默认卡槽
  <text slot="slot-bottom">我需要显示到底部-具名卡槽</text>
</custom01>

custom01.wxml 文件代码示例:

<!-- slot 就是用来接收子节点内容 -->
<!-- slot 只是一个占位符,子节点内容会将 slot 替换  -->
<view>
  <!-- 具名卡槽 -->
  <slot name="slot-top" />
  <!-- 默认卡槽 -->
  <view><slot /></view>
  <!-- 具名卡槽 -->
  <slot name="slot-bottom" />
</view>

custom01.js 文件代码示例:

Component({
  options:{
    // 启用多slot支持
    multipleSlots: true
  }
})

四、自定义组件的样式以及注意事项

组件对应 wxss 文件的样式,只对组件wxml内的节点生效。编写组件样式时,需要注意以下几点:

  • 不建议在 app.wxss 或 page.wxss 中使用了标签(view)选择器或一些其他特殊选择器来直接指定样式,这些选择器会影响到页面和全部组件,通常不推荐此做法
  • 组件和引用组件的页面不能使用id选择器(#a)、属性选择器([a])和标签名选择器,请改用class选择器。
  • 组件和引用组件的页面中使用后代选择器(.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用。
  • 子元素选择器(.a>.b)只能用于 view 组件与其子节点之间,用于其他组件可能导致非预期的情况。
  • 继承样式,如 font 、 color ,会从组件外继承到组件内。
  • 除继承样式外, app.wxss 中的样式、组件所在页面的的样式对自定义组件无效(除非更改组件样式隔离选项)。

custom02.wxss 文件代码示例:

// 第一个注意事项:在自定义组件的 wxss 文件中不能使用id选择器(#a)、属性选择器([a])和标签名选择器,请改用 class 选择器
// 可以使用 class 选择器
// .content {
//   color: rgb(136, 224, 224);
// }
// 不能使用标签名选择器,否则打印台会有警告
// text{
//   color: plum;
// }
// 不能使用id选择器(#a)
// #content {
//   color: pink;
// }
// 不能使用属性选择器([a])
// [id = content]{
//   color: lightcoral;
// }

// 第二个注意事项:子元素选择器(.a>.b)只能用于 view 组件与其子节点之间,用于其他组件可能导致非预期的情况
// .content > .label {
//   color: peachpuff;
// }

custom02.wxml 文件代码示例:

<text id="content" class="content son">
 <text class="label">给自定义组件设置样式</text>
</text>

app.json 文件代码示例:

"usingComponents": {
   "custom02": "./components/custom02/custom02"
  }

page.wxss 文件代码示例:

page {
  padding: 10rpx;
  box-sizing: border-box;
}
// 第三个注意事项:继承样式,如 font 、 color ,会从组件外继承到组件内。
// .custom {
//   color: orange;
//   font-size: 30rpx;
// }
// 第四个注意事项:除继承样式外, app.wxss 中的样式、组件所在页面的的样式对自定义组件无效
// .label {
//   color: lightgreen;
// }
// 第五个注意事项-官方不推荐做法:不建议在 app.wxss 或 page.wxss 中使用标签选择器直接使用样式、
// 如果在 app.wxss 中设置样式,会影响项目中全部的相同组件
// 如果在 page.wxss 中设置样式,会影响当前页面所有的相同组件
// text {
//   color: lightpink;
// }

// 第六个注意事项:组件和引用组件的页面中使用后代选择器(.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用
.parent .son.test {
  color: orange;
}

page.wxml 文件代码示例:

<custom02 />
<view class="custom">
 <custom02 />
</view>
<text>我是父级页面中的结构</text>
<view class="custom parent">
 <view>
  <custom02 />
  <view class="son test">我是父级页面中的结构</view>
 </view>
</view>

五、自定义组件的组件样式隔离

默认情况下,自定义组件的样式只受到自定义组件 wxss 的影响。但有时我们需要组件使用者的样式可以影响到组件,这时就需要指定特殊的样式隔离选项 styleIsolation 。它支持以下取值:

  • isolated 表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值);
  • apply-shared 表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面;
  • shared 表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了 apply-shared 或 shared 的自定义组件。(这个选项在插件中不可用。)

custom-checkbox.scss 文件代码示例:

/*
  复选框组件是公共组件,以后需要在多个页面或多个项目中使用,所以需要给复选框准备、设置一些默认样式
  若在其他页面或其他项目中使用时,发现样式不符合产品要求,可以对默认样式进行修改
 */
/*
  1、需要给复选框设置默认样式:
    需要先找到小程序给复选框提供的类名,通过小程序提供的类名进行修改才可以
    需要打开小程序开发文档,找到复选框文档,审查元素,进行查找
    在自定义组件中,不能直接修改复选框样式,若需要修改,需要设置 styleIsolation 才可以
    shared:修改其他页面、组件使用者的样式、以及使用了 apply-shared 或 shared 的自定义组件,这并不是我们想要的需求
    需求是只影响当前组件:可以添加命名空间
 */
//  复选框未选中的默认样式
.custom-checkbox .wx-checkbox-input {
  width: 24rpx !important;
  height: 24rpx !important;
  border-radius: 50% !important;
  border: 1px solid orange !important;
  margin-top: -3rpx;
}
// 复选框选中时的默认样式
.custom-checkbox .wx-checkbox-input-checked {
  background-color: orange;
}
//  复选框选中时 ✔️ 样式
.custom-checkbox .wx-checkbox-input.wx-checkbox-input-checked:before {
  font-size: 22rpx;
  color: white;
}
.custom-checkbox-container {
  display: inline-block;
}
.custom-checkbox-box {
  display: flex;
  align-items: center;
}
.custom-checkbox-box.left {
  flex-direction: row-reverse;
}
.custom-checkbox-box.right {
  flex-direction: row;
}
.custom-checkbox {
  margin-left: 10rpx;
}
.content{
  font-size: 24rpx;
}

custom-checkbox.wxml 文件代码示例:

<!-- <text>我是全局-自定义组件</text> -->
<view class="custom-checkbox-container">
  <view class="custom-checkbox-box {{ position === 'right' ? 'right' : 'left'}}" >
    <checkbox class="custom-checkbox" checked="{{ isChecked }}" bind:tap="updateChecked"/>
  <view class="content">
  <!-- 如果用户传递了 label 属性,就展示 label;否则展示子节点内容 -->
    <text wx:if="{{ label !== '' }}">{{ label }}</text>
    <slot wx:else="" />
  </view>
  </view>
</view>

custom-checkbox.js 文件示例:

Component({
  options: {
    styleIsolation: "shared"
  },
  /**
   * 组件的属性列表:是指组件的对外属性,主要是用来接收组件使用者传递给组件内部的数据与属性
   */
  properties: {
    // 如果需要传递的是属性,有两种方式:简写和全写
    // 简写:
    // label: String
    // 全写:
    label: {
      // type 组件使用者传递的数据类型,是必填项
      // 数据类型:String、Number、Boolean、Object、Array
      // 也可以设置为 null,表示不限制类型
      type: String,
      // value 属性值为默认值
      value: ""
    },
    position: {
      type: String,
      value: "right"
    }
  },
  /**
   * 组件的初始数据:定义组件的内部需要使用的数据
   */
  data: {
    isChecked: false
  },
  /**
   * 组件的方法列表:在组件中事件处理程序需要写到 methods 中可以
   */
  methods: {
    // 更新复选框的状态
    updateChecked() {
      this.setData({
        isChecked: !this.data.isChecked,
        // 在 JS 中可以访问和获取 properties 中的数据,但一般情况下不建议修改,因为会造成数据流的混乱
        // label: '在组件内部也可以修改 properties 中的数据'
      })
      console.log(this.properties.label)
    }
  }
})

app.json 文件代码示例:

"usingComponents": {
    "custom-checkbox": "./components/custom-checkbox/custom-checkbox"
  }

page.scss 文件代码示例:

/*
  2、组件使用者也可以修改复选框样式:
 */
 //  复选框未选中的默认样式
.custom .custom-checkbox .wx-checkbox-input {
  border: 1px solid green !important;
}
// 复选框选中时的默认样式
.custom .custom-checkbox .wx-checkbox-input-checked {
  background-color: green !important;
}

page.wxml 文件代码示例:

<view class="custom">
  <custom-checkbox position="left" >
    匿名提交
  </custom-checkbox>
</view>

六、自定义组件的数据监听器

数据监听器主要用于监听和响应任何属性和数据的变化,当数据发生变化时会触发对应的回调函数,从而方便开发者进行业务处理
在组件中如果需要进行数据监听,需要使用 observers 字段
custom04.js文件代码示例:

Component({

  /**
   * 组件的属性列表
   */
  properties: {
    label: {
      type: String,
      value: '测试'
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    num: 10,
    count: 100,
    obj: { name: 'Tom', age: 10},
    arr: [1, 2, 3]
  },
  // 用来监听数据属性是否发生变化
  observers: {
    // 一、监听一个数据
    // key: 需要监听的数据
    // value: 就是一个回调函数,形参:最新的数据
    num: function (newNum) {
      // 对 data 中的数据进行监听,若数据没有发生改变,监听器不会执行
      console.log(newNum)
    },
    count: function (newcount) {
      console.log(newcount)
    },
    // 二、同时监听多个数据
    'num, count': function (newNum, newCount) {
      console.log(newNum, newCount)
    },
    // 三、支持监听属性的变化
    'obj.name': function (newName) {
      console.log(newName)
    },
    'arr[1]': function (newItem) {
      console.log(newItem)
    },
    // 四、监听一个对象的所有属性的变化,使用通配符
    'obj.**': function (newObj) {
      console.log(newObj)
    },
    // 五、只要组件使用者进行传递了数据,这时候在监听器中就能获取传递的数据,也就是说,监听器立即执行了
    label: function (newLabel) {
      console.log(newLabel)
    }

  },
  /**
   * 组件的方法列表
   */
  methods: {
    // 更新数据
    updateData () {
      this.setData({
        num: this.data.num + 1,
        count: this.data.count - 1,
        'obj.name': 'jerry',
        'arr[1]': 666,
        label: '最新的标题'
      })
    }
  }
})

custom04.wxml 文件代码示例:

<view>{{ num }}</view>
<view>{{ count }}</view>
<view>{{ obj.name }}</view>
<view>{{ arr[1] }}</view>
<view>{{ label }}</view>
<button type="warn" plain bind:tap="updateData">更新数据</button>

app.json 文件代码示例:

"usingComponents": {
   "custom04": "./components/custom04/custom04"
  }

page.wxml 文件代码示例:

<custom04 label='标题' />

七、自定义组件的组件通信

1、父组件向子组件传递数据,需要两个步骤:

  • 1.1、在父组件 WXML 中使用数据绑定的方式向子组件传递动态数据
  • 1.2、子组件内部使用 properties 接收父组件传递的数据即可

2、子组件若向父组件传递数据,可以通过小程序提供的事件系统实现,可以传递任意数据,需要两个步骤:

  • 2.1、自定义组件内部使用 triggerEvent 方法发射一个自定义事件,同时可以携带数据
  • 2.2、自定义组件标签上通过 bind 方法监听发射的事件,同时绑定事件处理函数,在事件处理函数中通过事件对象获取传递的数据

3、父组件可以通过 this.selectComponent 方法,获取子组件实例对象,这样就可以直接访问子组件的任意数据与方法,this.selectComponent 方法在调用时需要传入一个匹配选择器 selector
page.wxml 文件代码示例:

<!-- 1、自定义组件的数据通信-父往子传值 -->
 <custom-checkbox position="right" checked="{{ isChecked }}">
  我已阅读并同意 用户协议 和 隐私协议 - 222
</custom-checkbox>
<!-- 2、自定义组件的数据通信-子往父传值 -->
<view>{{ num }}</view>
<!-- 需要自定义组件标签上通过 bind 方法绑定自定义事件,同时绑定事件处理函数 -->
<custom-checkbox 
 label="我已阅读并同意 用户协议 和 隐私协议"
 position="right" 
 checked="{{ isChecked }}"
 bind:changechecked="getChecked"
 >  
</custom-checkbox>
<!-- 3、自定义组件的数据通信-获取组件实例 -->
<button type="primary" plain bind:tap="getChild">获取子组件实例对象</button> 
<custom-checkbox 
 label="我已阅读并同意 用户协议 和 隐私协议"
 position="right" 
 checked="{{ isChecked }}"
 class="child"
 id="child"
 >  
</custom-checkbox>

page.js 文件代码示例:

Page({
  // 获取子组件的实例对象
  getChild() {
    // this.selectComponent 方法获取子组件实例对象,获取到实例对象以后,就能获取到子组件所有的数据,也能调用子组件的方法
    // .child 也可以写成 #child
    const res = this.selectComponent('.child')
    console.log(res)
  },
  // 获取子组件传递给父组件的数据
  getChecked(event) {
    console.log(event.detail)
    if (event.detail){
      console.log("提交")
    } else {
      console.log("请同意协议!")
    }
  },
    /**
   * 页面的初始数据
   */
  data:{
    isChecked: true,
    num: ''
  }
}

custom-checkbox.js 文件代码示例:

Component({
  /**
   * 组件的属性列表:是指组件的对外属性,主要是用来接收组件使用者传递给组件内部的数据与属性
   */
  properties: {
    // 如果需要传递的是属性,有两种方式:简写和全写
    // 简写:
    // label: String
    // 全写:
    label: {
      // type 组件使用者传递的数据类型,是必填项
      // 数据类型:String、Number、Boolean、Object、Array
      // 也可以设置为 null,表示不限制类型
      type: String,
      // value 属性值为默认值
      value: ""
    },
    position: {
      type: String,
      value: "right"
    },
    // 复选框组件公共组件,需要在多个组件多个页面使用,但有的地方希望默认是选中的效果,有的地方希望默认是未选中的效果,怎么处理呢?
    // 首先让复选框默认未选中效果,若需要默认选中效果,这时候传递属性(checked=true) 到复选框
    checked: {
      type: Boolean,
      value: false
    }
  },
  /**
   * 组件的初始数据:定义组件的内部需要使用的数据
   */
  data: {
    isChecked: false
  },
  observers: {
    // 如果需要将 properties 中的数据赋值给 data,可以使用 observers 进行处理
    checked: function(newChecked) {
      console.log(newChecked)
      this.setData({
        isChecked: newChecked
      })
    }
  },
  /**
   * 组件的方法列表:在组件中事件处理程序需要写到 methods 中可以
   */
  methods: {
    // 更新复选框的状态
    updateChecked() {
      this.setData({
        checked: !this.data.checked,
        // 在 JS 中可以访问和获取 properties 中的数据,但一般情况下不建议修改,因为会造成数据流的混乱
        // label: '在组件内部也可以修改 properties 中的数据'
      })
      console.log(this.data.isChecked)
      // 目前复选框组件的状态是存储在复选框组件内部的、存储在自定义组件内部的,但在实际开发中,组件使用者、父组件有时候也需要获取到复选框内部的状态,怎么办?
      // 这时候,自定义组件需要发射一个自定义事件,如果组件使用者或父组件需要使用数据,绑定自定义事件获取即可
      this.triggerEvent('changechecked', this.data.isChecked)
    }
  }
})

八、自定义组件的生命周期

见文章:微信小程序-生命周期

九、自定义组件拓展-使用 component 构造页面

component 方法用于创建自定义组件,小程序页面也可视为自定义组件,因此页面也可以使用 component 方法进行创建,从而实现复杂的页面逻辑开发

  • 小程序页面也可以使用 component 方法进行构造,注意事项:
    • 1、要求 .json 文件必须包含 usingComponents 字段
    • 2、里面的配置项需要和 Component中的配置项保持一致
    • 3、页面中 Page 方法有一些事件监听方法、钩子函数,这些方法函数必*放在方法 methods 对象中
    • 4、组件的属性 properties也可以接收页面的参数,在 onLoad 钩子*数中可以通过 this.data 获取
  • 为什么需要使用 component 方法进行构造页面?
    • component 方法功能比 page 方法强大很多,可以实现更复杂的页面逻辑

detail.js 文件代码示例:

Component({
  /**
   * 小程序页面也可以使用 component 方法进行构造
   * 注意事项:
   * 1、要求 .json 文件必须包含 usingComponents 字段
   * 2、里面的配置项需要和 Component中的配置项保持一致
   * 3、页面中 Page 方法有一些事件监听方法、钩子函数,这些方法函数必*放在方法 methods 对象中
   * 4、组件的属性 properties也可以接收页面的参数,在 onLoad 钩子*数中可以通过 this.data 获取
   * 为什么需要使用 component 方法进行构造页面?
   * component 方法功能比 page 方法强大很多,可以实现更复杂的页面逻辑
   */
  /**
   * 组件的属性列表
   */
  properties: {
    id: String,
    title: String
  },

  /**
   * 组件的初始数据
   */
  data: {
    name: "tom"
  },

  /**
   * 组件的方法列表
   */
  methods: {
    // 更新 name
    updateName() {
      this.setData({
        name: "jerry"
      })
    },
    onLoad (options) {
      console.log('页面加载')
      console.log(options)
      console.log(this.data.id)
      console.log(this.data.title)
      console.log(this.properties.id)
    }

  }
})

detail.wxml 文件代码示例:

<view>{{ name }}</view>
<button type="warn" plain bind:tap="updateName">更新 name</button>

page.wxml 文件代码示例:

//自定义组件拓展-使用 component 构造页面
<navigator url="/pages/detail/detail?id=10&title=测试">跳转到详情页面</navigator>

十、自定义组件拓展-组件复用机制 behaviors

小程序的 behaviors 方法是一种代码复用方式,可将一些通用的逻辑和方法提取出来,然后在多个组件中复用,从而减少代码冗余,提高代码的可维护性。
如果需要 behavior 复用代码,需要使用 Behavior 方法,每个 behavior 可包含一组属性、数据、生命周期函数和方法。
组件引用它时,它的属性、数据和方法被合并到组件中,生命周期函数也会在对应时机被调用。
在以后开发中使用 behaviors 进行代码复用时,组件和 behaviors 可能存在相同的字段:

  • 如果有同名的属性或方法,采用“就近原则”,组件会覆盖 behavior 中的属性或方法
  • 如果有同名的数据字段且都是对象类型,会进行对象合并,其余情况会采用“就近原则”进行数据覆盖
  • 生命周期函数和 observers 不会相互覆盖,会在对应触发时机逐个调用,也就是都会被执行

在自定义组件文件夹中创建 behavior.js 文件,代码示例:

const behavior = Behavior({
   /**
 - 组件的属性列表
   */
  properties: {
    label: {
      type: String,
      value:'我已同意该协议'
    }
  },

  /**
 - 组件的初始数据
   */
  data: {
    name: "Lida",
    obj: {
      name: "Mike"
    }
  },

  /**
 - 组件的方法列表
   */
  methods: {
    updateName () {
      this.setData({
        name: "jerry"
      })
      console.log("我是 behavior 内部的方法")
    }
  },
  lifetimes: {
    attached() {
      console.log("我是 behavior 内部的生命周期函数")
    }
  }
})
export default behavior

custom07.js 文件代码示例:

// components/custom07/custom07.js
import behavior from './behavior'
Component({
  behaviors: [behavior],
  /**
 - 组件的属性列表
   */
  // 如果存在相同的 properties,就近原则,使用组件内部的数据
  properties: {
    label: {
      type: String,
      value:'匿名提交'
    }
  },

  /**
 - 组件的初始数据
   */
  // 如果存在相同的 data,若 data 是对象类型,属性会进行合并,如果不是对象类型,就近原则,使用组件内部的数据
  data: {
    name: "组件中的 name",
    obj: {
      name: "组件中的 obj name",
      age: 100
    }
  },

  /**
 - 组件的方法列表
   */
  // 如果存在相同的方法,就近原则,使用组件内部的方法
  methods: {
    updateName () {
      console.log("我是组件内部的方法")
    }
  },
  // 如果存在相同的生命周期函数,生命周期函数都会被触发
  lifetimes: {
    attached() {
      console.log("我是组件内部的生命周期函数")
    }
  }
})

custom07.wxml 文件代码示例:

<!--components/custom07/custom07.wxml-->
<view>{{ label }}</view>
<view>{{ name }}</view>
<view>{{ obj.name }}-{{obj.age}}</view>
<button type="primary" plain bind:tap="updateName">更新数据</button>

page.wxml 文件代码示例:

<custom07 />

app.json 文件代码示例:

"usingComponents": {
   "custom07": "./components/custom07/custom07"
  }

十一、自定义组件拓展-外部样式类

默认情况下,组件与组件使用者之间若存在相同的类型不会相互影响,组件使用者若想修改组件的样式,就需要解除样式隔离,但解除样式隔离后,在极端情况下,会产生样式冲突、CSS嵌套太深等问题,从而给开发带来一定的麻烦。
外部样式类:在使用组件时,组件使用者可以给组件传入CSS 类名,通过传入的类名修改组件的样式。
如果需要使用外部样式类修改组件的样式,在 Component 中需要用 externalClasses 定义若干个外部样式类。
外部样式类使用步骤:

  • 在 Component 中用 externalClasses 定义若干个外部样式类
  • 自定义组件标签通过 属性绑定 的方式提供一个样式类,属性是 externalClasses 定义的元素,属性值是传递的类名
  • 将接收到的样式类用于自定义组件内部
    注意事项:
    在同一节点,若存在外部样式类和普通样式类时,两个类的优先级是未定义的,因此需要添加 !important 以保证外部样式类的优先级

custom08.js 文件代码示例:

// components/custom08/custom08.js
Component({
  // 组件接受的外部样式类
  externalClasses: ['external-class']
  })

custom08.scss 文件代码示例:

.box {
  color: aqua;
}

custom08.wxml 文件代码示例:

<!-- 
  在同一节点,若存在外部样式类和普通样式类
  两个类的优先级是未定义的 
  建议:在使用外部样式类时,样式需要通过 !important 添加权重
 -->
<view class="external-class box">通过外部样式类修改组件样式</view>

app.json 文件代码示例:

{
  "usingComponents": {
    "custom08": "./components/custom08/custom08"
  }
}

page.scss 文件代码示例:

.my-class{
  color: orange !important;
}

page.wxml 文件代码示例:

<!-- 
  属性是 externalClass 里面定义的元素
  属性值必须是一个类名
 -->
<custom08 external-class="my-class" />
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值