微信小程序之自定义组件开发

1、前言

从小程序基础库版本 1.6.3 开始,小程序支持简洁的组件化编程。所有自定义组件相关特性都需要基础库版本 1.6.3 或更高。开发者可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。自定义组件在使用时与基础组件非常相似。

官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/

2、自定义组件之组件的创建与引用

2.1 创建
步骤:

  1. 在项目的根目录中右键,创建components–>test文件夹
  2. 在新建的components–>test文件夹上右键,点击“新建Component”
  3. 键入组件的名称之后回车,会自动生成组件多对应的四个文件:.js,.json,.wxml,.wxss

建议:为了保证目录结构清晰,建议把不同的组件存放到单独的目录中,如下图所示
在这里插入图片描述
2.2 引用

1)局部引用

  • 在页面的.json配置文件中引用自定义组件的方式称为“局部引用”
  • 在页面的.json文件的usingComponents节点下声明组件的标签名与组件的页面路径

.json

//在页面的.json文件中,引入自定义的组件并定义引用时的标签名
{
  "usingComponents": {
    //自定义组件的标签名字为my-test1
    "my-test1":"/components/test1/test1"
  },

.wxml

//在页面的.wxml文件中使用刚刚自定义组件的标签名来引用自定义组件
<my-test1>使用自定义组件1</my-test1>

2)全局引用

  • 在app.json全局配置文件中引用组件称为“全局引用”
  • 声明与使用与局部引用同理,只是声明是在app.json文件的usingComponents节点下
  • 作用域是全局的每一个页面

3)应用场景
主要根据组件的使用频率和范围来选择合适的引用方式

  • 如果某组件在多个页面中经常使用,则最好将其进行“全局引用”
  • 如果某个页面只在某个特定的页面中使用,则最好是将其进行“局部引用”

2.3 组件与页面的区别

大家会发现自定义组件和页面是不是非常相似,同样都是拥有四个文件 .js .json .wxml .wxss

但是组件与页面的.js与.json文件有着明显的区别:

  • 组件的.json文件中需要声明“components”:true属性,而页面不需要
  • 组件的.js文件中调用的是Components()函数,而页面调用的是Page()函数
  • 组件的事件处理函数需要写在methods节点中,而页面则要在与data数据节点平级声明即可

3、自定义组件之组件的样式隔离

3.1样式隔离特性
在默认的情况下,自定义组件的样式只对当前的组件生效,而不会去影响到组件之外的UI结构
如下图:

  • A的样式不会影响C的样式
  • A的样式不会影响小程序页面的样式
  • 小程序页面的样式不会影响A和C的样式
    在这里插入图片描述
    特性的好处:
  • 防止外界的样式影响自定义组件内部的样式,造成样式污染
  • 也能防止组件样式破坏外检的样式,双向的

注意点:

  • app.wxss中的全局样式对自定义组件默认是无效的
  • 只有使用class样式选择器才会有样式隔离的效果,id选择器、属性选择器、标签选择器不受样式隔离的影响

所以在自定义组件和引用自定义组件的页面中最好使用class样式选择器,不要使用id,属性,标签选择器从而避免造成不必要的麻烦!

3.2 修改隔离选项

默认情况下,自定义组件的样式隔离特性可以有效防止内外样式互相干扰的问题。但是在某些情况下我们又需要在外界能够控制自定义组件的内部样式,此时就可以通过修改styleIsolation属性来修改自定义组件样式隔离选项,从而达到控制内部组件样式的目的。
有两种方法:

  • 第一种:在自定义组件的.js文件中新增如下配置
//.js文件中
Component({
     options:{
          //表示启用样式隔离
          styleIsolation:'isolated'
    }
})
  • 第二种:在自定义组件的.json文件中新增如下配置
//.json文件中
{
   "styleIsolation":"isolated"
}

styleIsolation的可选值:

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

使用后两者时,请务必注意组件间样式的相互影响。

如果这个 Component 构造器用于构造页面 ,则默认值为 shared ,且还有以下几个额外的样式隔离选项可用:

  • page-isolated 表示在这个页面禁用 app.wxss ,同时,页面的 wxss 不会影响到其他自定义组件;
  • page-apply-shared 表示在这个页面禁用 app.wxss ,同时,页面 wxss 样式不会影响到其他自定义组件,但设为 shared 的自定义组件会影响到页面;
  • page-shared 表示在这个页面禁用 app.wxss ,同时,页面 wxss 样式会影响到其他设为 apply-shared 或shared 的自定义组件,也会受到设为 shared 的自定义组件的影响。

4、自定义组件之组件的三大节点属性

4.1 data数据节点
在小程序组件中,用于组件模板渲染的私有数据需要定义到.js文件的data节点中

// components/test1/test1.js
Component({
  /**
   * 组件的初始数据
   */
  data: {
    count:0
  },
})

4.2 methods方法节点

在小程序组件中,事件处理函数和自定义的方法需要定义到.js文件的methods节点中

// components/test1/test1.js
//点击按钮使count加1,并且控制其最大值为属性中的max值
Component({
   /**
   * 组件的初始数据
   */
  data: {
    count:0
  },
  /**
   * 组件的属性列表
   */
  properties: {
    //方法一:完整方式
     max:{
      type:Number,//参数类型
      value:0     //参数的默认值
     }
  },
  /**
   * 组件的方法列表
   */
  methods: {
    // 点击事件的处理函数
    addCount(){
      if(this.data.count>=this.properties.max)return 
      this.setData({
        count:this.data.count+1
      })
      this._showCount()
    },
    // 自定义的方法建议以下划线开头以示区分
    _showCount(){
      // 打印消息框 
      wx.showToast({
        title: 'count值为:'+this.data.count,
        icon:"none"
      })
    },
  }
})

4.3 properties属性节点
在小程序组件中,properties是组件的对外属性,用来接收外界传递到组件中的数据

// components/test/test1.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    //方法一:完整方式
     max:{
      type:Number,//参数类型
      value:0     //参数的默认值
     }
    //方法二:简化方式
    max:Number
  },
})

然后在页面结构中可以在标签内直接传值

<my-test1 max="10"></my-test1>

4.4 data和properties的区别
在小程序组件中,properties属性和data数据的用法相同,在本质上没有任何区别,properties里面的值与data一样可以用于页面渲染,也可以使用setData()方法为properties属性中的值进行重新赋值,但有以下两点区别:

  • data更加倾向于存储组件的私有数据(内部数据)
  • properties更加倾向于存储外界传递到组件中的数据(外部数据、通信)

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

5.1 监听数据的变化
数据监听器,用于监听和响应任何属性与数据字段的变化,从而执行特定的操作。
基本语法格式:

Component({
 
      observer:{
          '字段A,字段B':function(字段A的新值,字段B的新值){
                  // do something
            }
      }
})

示例代码:
test1.wxml

<!--components/test1/test1.wxml-->
<view>{{n1}}+{{n2}}={{sum}}</view>
<button bindtap="addN1" type="primary">n1+1</button>
<button bindtap="addN2" type="primary">n2+1</button>

test1.js

// components/test1/test1.js
Component({
    /**
     * 组件的属性列表
     */
    properties: {
 
    },
 
    /**
     * 组件的初始数据
     */
    data: {
        n1:0,
        n2:0,
        sum:0
 
    },
 
    /**
     * 组件的方法列表
     */
    methods: {
        //n1+1
        addN1(){
            this.setData({
                n1:this.data.n1+1
            })
        },
        //n2+1
        addN2(){
            this.setData({
                n2:this.data.n2+1
            })
        }
    },
    //数据监听器。监听n1,n2的变化,自动计算sum
    observers:{
        'n1,n2':function(newN1,newN2){
            this.setData({
                sum:newN1+newN2
            })
        }
    }
})

app.json声明自定义组件

"usingComponents": {
        "my-test1":"/components/test1/test1"
    }

在home.wxml上渲染

<!--pages/home/home.wxml-->
<my-test1></my-test1>

实现效果
当任意按下n1+1或者n2+1按钮时,导致n1,n2数值的变化从而被数据监听器捕捉到,然后在事件监听器处理函数内部对sum用新值进行自动计算赋值
在这里插入图片描述
5.2 监听对象属性的变化
数据监听器支持监听对象中单个或者多个属性的变化,基本语法如下:

Component({
      observer:{
          '对象.属性A,对象.属性B':function(属性A的新值,属性B的新值){
                  // do something
            }
      }
})

如果某个对象中需要被监听的属性太多,为了方便,则可以使用通配符 ** 来监听对象中所有属性的变化,基本语法如下:

Component({
      observer:{
          '对象.**':function(obj){
                  this.setData({
                      某数据字段:`${obj.对象属性1},${obj.对象属性2}......`
                  })
                 
            }
      }
})

6、自定义组件之组件的纯数据字段

纯数据字段指的是那些完全不用于页面渲染的data字段
纯数据字段可以提升页面更新的性能

应用场景:

  • 某些data中的字段不会展示在界面上
  • 也不会传递给其它组件
  • 仅在当前组件的内部进行使用

使用规则:
在Component构造器的options节点中,指定pureDataPattern为一个正则表达式,字段名符合这个正则表达式的字段将成为纯数据字段,示例代码如下:

Component({
   options:{
    //这里示例指定所有以 _ 开头的数据字段为纯数据字段
    pureDataPattern:/^_/
   },
   data:{
      a:true,//普通字段
      _b:true,//将被设置为纯数据字段
   }
})

7、自定义组件之组件的生命周期及其函数

7.1 组件主要生命周期

  • 组件实例被创建 – created
  • 组件完全初始化完毕 – attached
  • 组件进入页面节点树
  • 组件离开页面节点树 – detached
    在这里插入图片描述

7.2 定义生命周期函数
在小程序组件中,生命周期函数的定义有新旧两种方式

  • 第一种,直接定义在Component构造器内与data节点平级的第一级参数中
  • 第二种,可以在lifetimes字段内进行声明(推荐,其优先级最高,且专门放生命周期函数)

自定义组件.js文件:

//定义组件生命周期函数的两种方式
Component({
     //推荐用法
     lifetimes:{
         attached(){ },
         detached(){ },
      }
     //旧的定义方式,与data节点平级
      attached(){ },
      detached(){ },
})

注:如果同时存在两种新旧定义方式,那么旧的定义方式将会被覆盖掉

8、自定义组件之组件的插槽

在自定义组件的wxml结构中,可以提供一个节点(插槽),用于填充组件使用者提供的wxml结构,起到占位的作用
在这里插入图片描述
8.1 单个插槽的使用
在小程序中,默认每个自定义的组件只能允许使用一个进行占位,这种个数上的限制就叫做单个插槽

<!-- 组件的封装者 -->
<view>
     <view>这是组件的内部节点</view>
     <!-- 下面对于不确定的内容可以使用<slot>插槽进行占位,后续由组件使用者进行填充 -->
     <slot></slot>
</view>
 
<!-- 组件的使用者 -->
<component-tag-name>
    <!-- 下面的内容将被放置到组件封装者定义插槽<slot>的位置 -->
    <view>这是插入到组件slot中内容</view>
</component-tag-name>

8.2 多个插槽的使用
1)启动多个插槽
小程序的自定义组件默认支持一个插槽的使用,如果需要使用多个插槽,就可以在组件.js文件中通过如下方式进行配置从而启用多个插槽的功能

Component({
   options:{
     multipleSlots:true//启用多个插槽
   },
   properities:{/* ... */},
   methods:{/* ... */}
})

定义与使用

<!-- 页面模板,即组件的封装者 -->
<view>
     <!-- 这是name为slot1的第一个插槽 -->
     <slot name="slot1"></slot>
     <view>~~~~~~~分隔线~~~~~~~~~</view>
      <!-- 这是name为slot2的第二个插槽 -->
      <slot name="slot2"></slot>
</view>
 
<!-- 引用组件的页面模板,即组件的使用者 -->
<component-tag-name>
   <view slot="slot1">这是插入到名字为slot1插槽里面的内容</view>
   <view slot="slot2">这是插入到名字为slot2插槽里面的内容</view>
</component-tag-name>

9、组件间通信与事件

9.1 组件间通信

组件间的基本通信方式有以下几种。

  • WXML 数据绑定:用于父组件向子组件的指定属性设置数据,仅能设置 JSON 兼容数据(自基础库版本 2.0.9开始,还可以在数据中包含函数)。具体在 组件模板和样式 章节中介绍。
  • 事件:用于子组件向父组件传递数据,可以传递任意数据。
  • 如果以上两种方式不足以满足需要,父组件还可以通过 this.selectComponent方法获取子组件实例对象,这样就可以直接访问组件的任意数据和方法

9.2 监听事件
事件系统是组件间通信的主要方式之一。自定义组件可以触发任意的事件,引用组件的页面可以监听这些事件。关于事件的基本概念和用法,参见 事件 。

监听自定义组件事件的方法与监听基础组件事件的方法完全一致:

<!-- 当自定义组件触发“myevent”事件时,调用“onMyEvent”方法 -->
<component-tag-name bindmyevent="onMyEvent" />
<!-- 或者可以写成 -->
<component-tag-name bind:myevent="onMyEvent" />
Page({
  onMyEvent: function(e){
    e.detail // 自定义组件触发事件时提供的detail对象
  }
})

9.3 触发事件
自定义组件触发事件时,需要使用 triggerEvent 方法,指定事件名、detail对象和事件选项:

<!-- 在自定义组件中 -->
<button bindtap="onTap">点击这个按钮将触发“myevent”事件</button>
Component({
  properties: {},
  methods: {
    onTap: function(){
      var myEventDetail = {} // detail对象,提供给事件监听函数
      var myEventOption = {} // 触发事件的选项
      this.triggerEvent('myevent', myEventDetail, myEventOption)
    }
  }
})

触发事件的选项包括:
在这里插入图片描述
9.4 获取组件实例

可在父组件里调用 this.selectComponent ,获取子组件的实例对象。
调用时需要传入一个匹配选择器 selector,如:this.selectComponent(“.my-component”)。

// 父组件
Page({
  data: {},
  getChildComponent: function () {
    const child = this.selectComponent('.my-component');
    console.log(child)
  }
})

在上例中,父组件将会获取 class 为 my-component 的子组件实例对象,即子组件的 this 。

注 :默认情况下,小程序与插件之间、不同插件之间的组件将无法通过 selectComponent 得到组件实例(将返回 null)。如果想让一个组件在上述条件下依然能被 selectComponent 返回,可以自定义其返回结果(见下)

// 自定义组件 my-component 内部
Component({
  behaviors: ['wx://component-export'],
  export() {
    return { myField: 'myValue' }
  }
})
<!-- 使用自定义组件时 -->
<my-component id="the-id" />
// 父组件调用
const child = this.selectComponent('#the-id') //  { myField: 'myValue' }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/119025.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

泛微OA_lang2sql 任意文件上传漏洞复现

简介 泛微OA E-mobile系统 lang2sql接口存在任意文件上传漏洞&#xff0c;由于后端源码中没有对文件没有校验&#xff0c;导致任意文件上传。攻击者可利用该参数构造恶意数据包进行上传漏洞攻击。 漏洞复现 FOFA语法&#xff1a; title"移动管理平台-企业管理" 页…

【Mybatis】3 的操作类型对象

前言知识汇总 上篇文章中我们已经详细介绍了Mybatis的存储类对象。我们上篇提到了&#xff1a; Mapper.xml当中的SQL标签都被解析成了一个一个的MappedStatement对象。那么我们当中的SQL是基于什么形式进行封装的呢&#xff1f; 我们要知道&#xff0c;Java当中一切皆对象。M…

人人都会的 Blazor —— 1.3 项目结构

项目结构 使用 Visual Studio 2022 创建 Blazor 项目。 在搜索框中输入【blazor】关键字,将列出以下已经存在的项目模板: Blazor Server App:基于 Blazor Server 托管模型的项目,并建立一些示例代码和组件;Blazor WebAssembly App:基于 Blazor WebAssembly 托管模型的项…

优维低代码实践:打包发布

导语 优维低代码技术专栏&#xff0c;是一个全新的、技术为主的专栏&#xff0c;由优维技术委员会成员执笔&#xff0c;基于优维7年低代码技术研发及运维成果&#xff0c;主要介绍低代码相关的技术原理及架构逻辑&#xff0c;目的是给广大运维人提供一个技术交流与学习的平台。…

uniapp使用vue3和ts开发小程序自定义tab栏,实现自定义凸出tabbar效果

要实现自定义的tabbar效果&#xff0c;可以使用自定义tab覆盖主tab来实现&#xff0c;当程序启动或者从后台显示在前台时隐藏自带的tab来实现。自定义一个tab组件&#xff0c;然后在里面实现自定义的逻辑。 组件中所使用的组件api可以看&#xff1a;Tabbar 底部导航栏 | uView…

【今天放个大招,带你手把手搭建 Jenkins 的分布式构建】

UI 自动化测试代码写完了以后&#xff0c;会放到 Jenkins 这样的持续集成工具上去构建。 如果 Jenkins 平台是搭建在服务器上&#xff0c;会面临 2 个问题&#xff1a; 第一个问题是 UI 自动化测试需要渲染界面&#xff0c;需要消耗大量的 CPU 和内存资源&#xff0c;如果服务器…

海康Visionmaster-全局脚本:通过全局脚本获取通讯输 入的参数并赋值给全局变量

全局脚本根据外部通讯输入的数值赋值给全局变量&#xff0c;实现输入与全局变量之间的数值绑定。&#xff08;一般应用于定位、标定等需要外界物理值的场景)。 第一步&#xff0c;在 vm 通讯管理中设置好通讯设备&#xff0c;连接 第二步&#xff0c;根据通讯设备、接收的信息…

如何对非线性【SVM】进行三维可视化

首先导入相应的模块&#xff0c; from sklearn.datasets import make_blobs from sklearn.svm import SVC import matplotlib.pyplot as plt import numpy as np 我们使用make_circles()函数创建散点图&#xff0c;并将散点图中的点的横纵坐标赋值给x,y&#xff0c;其中x是特…

Git中的 fork, clone,branch

一、是什么 fork fork&#xff0c;英语翻译过来就是叉子&#xff0c;动词形式则是分叉&#xff0c;如下图&#xff0c;从左到右&#xff0c;一条直线变成多条直线 转到git仓库中&#xff0c;fork则可以代表分叉、克隆 出一个&#xff08;仓库的&#xff09;新拷贝 包含了原来…

奔驰E Coupe 升级鼠标按键 操作简单 完美结合

人机交互系统正是汽车智能化发展的产物&#xff0c;它实现了人与车之间的互联。不知道大家有没有发现&#xff0c;在很多奔驰车的中央扶手箱前&#xff0c;有一块类似于“鼠标”的操作区&#xff0c;它并不是我们常见的换挡杆&#xff0c;而是奔驰研发的独立影音控制系统COMAND…

(11_06)函数计算 FC 3.0 发布,全面降价,最高幅度达93%,阶梯计费越用越便宜

作为国内最早布局 Serverless 的云厂商之一&#xff0c;阿里云在 2017 年推出函数计算 FC&#xff0c;开发者只需编写代码并上传&#xff0c;函数计算就会自动准备好相应的计算资源&#xff0c;大幅简化开发运维过程。阿里云函数计算持续在 Serverless GPU 方面投入研发&#x…

数据结构与算法(Java版) | 排序算法的介绍与分类

各位朋友&#xff0c;现在我们即将要进入数据结构与算法&#xff08;Java版&#xff09;这一系列教程中的排序算法这一章节内容的学习中了&#xff0c;所以还请大家系好安全带&#xff0c;跟随我准备出发吧&#xff01; 相信诸位应该都知道排序算法有很多种吧&#xff01;就算没…

iPortal如何灵活设置用户名及密码的安全规则

作者&#xff1a;yx 目录 前言 一、配置文件介绍 1、<passwordRules>节点 注意事项&#xff1a; 2、<usernameRules>节点 二、应用实例 1、配置文件设置 2、验证扩展结果 三、结果展示 前言 SuperMap iPortal提供了扩展账户信息合规度校验规则的能力&#…

太坑了,降低 代码可读性的 12 个技巧

工作六七年以来&#xff0c;接手过无数个烂摊子&#xff0c;屎山雕花、开关编程已经成为常态。 下面细数一下 降低代码可读性&#xff0c;增加维护难度的 12 个编码“技巧”。 假设一个叫”二狗“ 的程序员&#xff0c;喜欢做以下事情。 1. 二狗积极拆分微服务&#xff0c;一个…

二.831(KMP)字符串详解

ne[3]枚举2次 ne[4],枚举3次 ne[5],枚举4次]b在后面了,就一个b就不可能在前面了]b舍弃 ne[6],枚举i-1次]一眼看最长相等前后缀,就是aab,aab ne[7],aaba,aaba ne[8],枚举i-1次]aabaa,aabaa 同理 怎么快速看呢!我想把b给夹起来]把中间夹的数越多就多 其实 加的有规律,最…

多级缓存之JVM进程缓存

1.什么是多级缓存 传统的缓存策略一般是请求到达Tomcat后&#xff0c;先查询Redis&#xff0c;如果未命中则查询数据库&#xff0c;如图&#xff1a; 存在下面的问题&#xff1a; 请求要经过Tomcat处理&#xff0c;Tomcat的性能成为整个系统的瓶颈 Redis缓存失效时&#xff0…

【基础IO⑨】:重定向实现原理 “Linux下一切皆文件“

【基础IO⑨】&#xff1a;重定向原理 与 "Linux下一切皆文件" 一.重定向1.实现原理2.输出重定向3.输入重定向4.补充&#xff1a;简易shell中实现重定向 二."Linux下一切皆文件"1.虚拟文件系统(VFS) 一.重定向 我们首先关闭2号文件描述符&#xff0c;然后再…

antv/x6 自定义html节点并且支持动态更新节点内容

antv/x6 自定义html节点 效果图定义一个连接桩公共方法注册图形节点创建html节点动态更新节点内容 效果图 定义一个连接桩公共方法 const ports {groups: {top: {position: top,attrs: {circle: {r: 4,magnet: true,stroke: #cf1322,strokeWidth: 1,fill: #fff,style: {visib…

虚拟机Linux-Centos系统网络配置常用命令+Docker 的常用命令

目录 1、虚拟机Linux-Centos系统网络配置常用命令2、Docker 的常用命令2.1 安装docker步骤命令2.2 在docker容器中安装和运行mysql 2、dockerfile关键字区别(ADD/COPY,CMD/ENTRYPOINT) 1、虚拟机Linux-Centos系统网络配置常用命令 进入网络配置文件目录 cd /etc/sysconfig/ne…

监控actuator配置以及踩坑记录

以前这个监控都是领导去加&#xff0c;我顶多去修改一些时间参数&#xff0c;让我自己加还是头一次 正经踩了不少坑啊 1.依赖引入 先说配置过程 不对 先说我们项目结构 我们有一个common项目&#xff0c;作为一个公共项目。各种项目公用的依赖&#xff0c;都配置在common中…