[微信小程序] 入门笔记2-自定义一个显示组件

news2024/11/26 0:57:05

[微信小程序] 入门笔记2-自定义一个显示组件

0. 准备工程

  • 新建一个工程,删除清空app的内容和其余文件夹.然后自己新建pagescomponents创建1个空组件和1个空页面.

在这里插入图片描述

  • 设定 view 组件的默认样式,使其自动居中靠上,符合习惯.在app.wxss内定义,作用做个工程.
/**app.wxss**/
/* 所有 view 容器, 默认, 从左到右从上到下, 完完全全居中对齐 */
view {
  /* 弹性盒子布局 */
  display: flex;
  /* 决定主轴的方向 即项目的排列方向: 主轴为水平方向,起点在左端 */
  flex-direction: row;
  /* 定义项目是否换行以及如何换行: 换行,第一行在上方 */
  flex-wrap: wrap;
  /* 定义项目在主轴上的对齐方式: 居中 */
  justify-content: center;
  /* 定义项目在竖直方向上对齐方式: 交叉轴的中点对齐 */
  align-items: center;
  /* 定义多根轴线的对齐方式: 与交叉轴的中点对齐 */
  align-content: center;
}

在这里插入图片描述

1.调用组件

  • page1.json文件中导入组件.

在这里插入图片描述

  • page1.wxml中调用组件.

在这里插入图片描述

  • 将内容放在view内,自动居中对齐,上一步修改view样式起的作用.如果之后需要修改特定的view样式,再加个类名限定即可.

在这里插入图片描述

2.设定组件内容和属性

  • 组件脚本js的所有内容都需要写在component({...})内, 然后属性需要写在其中的properties:{}内. 值得注意的是,属性的定义必须标明类型!!!采样以下固定的形式,必须包含typevalue2个内容.算是定义了一个对象,然后数据存在该对象的value属性内容.
  properties: {
  	temp: {
			type: String,
			value: '666',
		},
  },
  • 主要是定义一些样式, 还有需要显示的数据数组.
  /**
   * 组件的属性列表
   */
  properties: {
    /* 字体大小 rpx */
    css_font_size: {
      type: String,
      value: "30",
    },
    /* 单个数据框高度 vh */
    css_item_height: {
      type: String,
      value: "5",
    },
    /* 名称框的占比宽度 rpx */
    css_name_width: {
      type: String,
      value: "150",
    },
    /* 冒号的占比宽度 rpx */
    css_colon_width: {
      type: String,
      value: "40",
    },
    /* 数据的占比宽度 rpx */
    css_val_width: {
      type: String,
      value: "80",
    },
    /* 数据数组, 3个元素分别: 名称, 内容, 是否输入 */
    data_array: {
      type: Array,
      value: [{
        str_name: '只输出',
        str_data: '0',
        isOutputOnly: true,
      }, {
        str_name: '可输入',
        str_data: '0',
        isOutputOnly: false,
      }, ],
    },
  },
  • 然后在.wxml文件内放置内容,wxml内的{{}}可以直接访问到js脚本内的属性properties和数据data内容!!!data内数据定义就无需非要指定类型.但是只有属性properties能接收外部传入值,所以一般data是处理内部数据使用.
  • 循环列表渲染,wx:for就不过多解释了.
<view class="showData-container" style="font-size:{{css_font_size}}rpx;">  
  <view class="showData-item" wx:for="{{data_array}}" wx:key="index"> 
    <view style="height:{{css_item_height}}vh;width:{{css_name_width}}rpx;" >{{item.str_name}}</view> 
    <view style="height:{{css_item_height}}vh;width:{{css_colon_width}}rpx;">{{":"}}</view> 
    <view style="height:{{css_item_height}}vh;width:{{css_val_width}}rpx;">{{item.str_data}}</view>   
  </view>  
</view>
  • 然后打开可视化功能,可以单独调试组件的内容.然后结合调试器.轻松调试.可以看到组件实际渲染效果,rpx单位会被自动转换成px单位.更改屏幕大小可以发现等比例相对变化.

在这里插入图片描述

3.传入数组

  • 在页面page.js创建数组;
    /* 数据显示数组 */
    data_array: [{
      str_name: '读取',
      str_data: '5.89',
      isOutputOnly: true,
    }, {
      str_name: '写入',
      str_data: '0.985',
      isOutputOnly: false,
    }, ],

在这里插入图片描述

  • page1.wxml内传入数组,同时可以修改一下样式,看看效果.不写的话就算保持组件内设定的默认值.

在这里插入图片描述

4.动态修改数组

  • 在页面内修改了数组data_array,是可以同步影响到组件内的显示的.
  • 添加一个按钮,用于修改数据,可以在可视化界面内快速添加.长按拖拽, 或是先选择view,然后双击添加.
  • 添加之后,拖拽组件可以修改位子,ide会自动 添加绝对位置的样式属性.不推荐这样设置.

在这里插入图片描述

  • 为按钮添加属性bind:tap指定点击时的回调函数.
  <button bind:tap="button0_tap">按钮</button>

4.5.bind

  • 这是重中之重的要点!!! 第一次接触小程序,看到这个用法属实头蒙.
  • 许多功能回调,或是特殊语法,都使用了bind前缀命名.在旧版语法中是没有冒号:做分隔的.新版中支持使用冒号:分隔,使得可读性提高.看例程时可能看到有些又冒号,有些没用,不要困惑,其实指的是同一个意思.
  • 然后bind:tap不是按钮的专属属性,是所有组件都可以添加的一个属性,意义是在点击时调用指定函数.所以将按钮改为viewtext,是一样的效果.
  <text bind:tap="button0_tap">pages/page1/page1.wxml\n</text>
  • 然后在脚本page1.js内定义回调函数.
  /* 按钮回调,修改显示数组 */
  button0_tap(e) { // button0_tap: (e) => { // 错误的,这样函数内的 this 可能就没有了
    console.log(e); // 定义看看传入的对象是什么, 可以在调试窗口查看
    console.log(this); // 定义在调试仓库查看, 如果使用箭头函数, 这里打印为未定义
    let temp_array = this.data.data_array; // 数据不能直接修改,先取出来,实际上对象是引用而非拷贝,所以只是换个短一点的名字
    temp_array[0].str_data = Number((Number(temp_array[0].str_data) + 0.5).toFixed(3)) // 修改数据
    temp_array[1].str_data = Number((Number(temp_array[1].str_data) - 0.5).toFixed(3))
    temp_array.push(temp_array[0]); // 添加
    temp_array.push(temp_array[1]); // 
    this.setData({ // 直接修改 this.data 不会起效果,需要使用 setData 修改
      data_array: temp_array,
    })
  },
  • 注意,数据中使用了字符串的形式,因为使用数字num形式在表示浮点数时会出现无尽小数的情况.为了避免这一问题,我直接采用字符串的形式.
  • 注意,不可以使用箭头函数定义,因为想要访问this内容,可以使用console打印出来看看,可以详细查看对象内容.而不是控制台那种几个简单的字符.还能定位打印的位置,点击定位会跳转到sourcespage1.js?[sm]文件窗口,这是一个调试界面,你可以在界面进行卡断点,单步调试,查看变量等操作.非常方便.也可以使用快捷键Ctrl+P查找指定的.js?[sm]文件进行断点调试.

在这里插入图片描述
在这里插入图片描述

  • 通过点击组件调用回调函数,修改了数组内容,自定义组件内的数据也同步变化了.也就是达到了从页面传入动态数据到组件了.组件的样式属性也可以类似的操作.

5.传出数据

  • 为组件添加input组件,允许写入内容.替换原本的纯文本显示.注意到,回调函数使用bind:blur指定,改属性代表失去焦点时调用.disabled代表是否禁用.如果只输出显示数据就禁用.value指定当前值,该数值也会传入回调函数中.另外还需要更多数据一同被传入回调函数,需要自己定义,使用data-名字="{{数据}}",的形式.
    <view style="height:{{css_item_height}}vh;width:{{css_val_width}}rpx;">
      <input disabled="{{item.isOutputOnly}}" value="{{item.str_data}}" data-index="{{index}}"  data-name="{{item.str_name}}" bind:blur="input0_blur" />
    </view>   
  • 然后在脚本component1.js中添加回调函数;记得组件的方法,需要写在methods:{...}内.
  • 注意,value存放在e.detail中,这是自带的返回数据,而自定义的数据indexname是存放在e.currentTarget.dataset中,切记区分.最后通过this.triggerEvent,将数据传给指定的回调函数.
  • 注意,不要使用箭头函数,不然this会丢失,无法指定回调函数.可以使用input0_blur: function (e) {的形式.
  /**
   * 组件的方法列表
   */
  methods: {
    /* 输入回调函数 */
    input0_blur(e) { // input0_blur: function (e) { // input0_blur: (e) => {        
      console.log(e); // 定义看看传入的对象是什么, 可以在调试窗口查看
      console.log(this); // 定义在调试仓库查看, 如果使用箭头函数, 这里打印为未定义
      const value = e.detail.value; // input 只传入了这一个值
      const index = e.currentTarget.dataset.index; // 这2个是扩展的值
      const name = e.currentTarget.dataset.str_name; // 这2个是扩展的值

      this.triggerEvent('input1_blur', { // 调用外部回调函数, 指定函数名,与传出去的数据包
        value,
        index,
        name,
      });

    },
  }
  • 这时点击模拟窗口,就可以看到效果.打印的e能看到数据存放的位置.eEvent的缩写.可以以此代表该函数是回调函数,提高代码阅读性.

在这里插入图片描述

  • 修改page1.wxml,添加指定的回调函数.注意,使用了bind关键字,另外,我故意使用不同的函数名,代表他们之间的引用关系.
  <component1
    css_font_size="30"
    css_name_width="100"
    css_val_width="80"
    css_item_height="5"
    bind:input1_blur="input2_blur"
    data_array="{{data_array}}"> </component1>
  • page1.js中添加回调函数;注意到,这次3个变量数据value,index,name.都在e.detail内,因为人为指定了3个.
  • 注意, 我使用了索引的方式查找数据,其实应该用键名的方式查找,但是并不能像字典那样直接定位,所以还是选择方便快捷的索引定位.姑且加了保护措施,确定键名符合才进行.
  /* 接收数据回调 */
  input2_blur(e) {
    console.log(e); // 定义看看传入的对象是什么, 可以在调试窗口查看
    console.log(this); // 定义在调试仓库查看, 如果使用箭头函数, 这里打印为未定义
    let temp_array = this.data.data_array; // 数据不能直接修改,先取出来,实际上对象是引用而非拷贝,所以只是换个短一点的名字
    const value = e.detail.value; // input 只传入了这一个值
    const index = e.detail.index; // 这2个是扩展的值
    const name = e.detail.name; // 这2个是扩展的值
    if (name == temp_array[index].str_name) // 保护措施, 使用索引寻找定位, 判断是否定位正确
      temp_array[index].str_data = value; // 符合就将数据修改了

    temp_array[0].str_data = temp_array[1].str_data; // 这里做点修改,体现在界面上方便才看
    this.setData({ // 直接修改 this.data 不会起效果,需要使用 setData 修改
      data_array: temp_array,
    })
  },
  • 现在就可以模拟调试看看效果,我就不再截图了.
  • 现在可能还有个问题,每写一个这种组件,如果要接收其返回的数据,都要定义一个回调函数.好像用qt时也差不多,就这样吧 .

6.组件样式

  • 最后一步是修改样式, 白底黑字太难看.没有框框也没有边界感,而且无法区分输入和输出的样式.
  • 对于输入框,添加了样式判断,在{{}}中使用经典的三目运算符,选择不同字符串,也就是不同样式名.也可以使用wx:if判断使用不同组件达到同样效果;
<!--components/component1/component1.wxml-->
<!-- 删去,有错误,修正后的放下面 -->
  • 样式具体建议去看看美化网站提供的例子 https://uiverse.io
  • 值得说明的是,虽然我在开始的app.wxss指定了view组件的默认样式,但是我在自定义组件内又重新设定一遍,为了方便移植.
/* components/component1/component1.wxss */
/* 删去,有错误,修正后的放下面 */
  • 至此算是基本具备一个基础组件的使用.

7.样式警告

  • 我发现上面的写法会给出一个样式警告,如下.因此还是修改app.wxss的全局组件名样式,修改为类名样式(或直接删去).然后全部页面和组件都使用类名样式.

Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors.
组件wxs中不允许使用某些选择器,包括标记名选择器、ID选择器和属性选择器。

  • 组件布局修改如下. 每个view都指定了类名样式. 同时使用组合类名样式
<!--components/component1/component1.wxml-->

<view class="showData-container" style="font-size:{{css_font_size}}rpx;">  
  <view class="showData-container showData-item" wx:for="{{data_array}}" wx:key="index"> 
    <view class="showData-container" style="height:{{css_item_height}}vh;width:{{css_name_width}}rpx;" >{{item.str_name}}</view> 
    <view class="showData-container" style="height:{{css_item_height}}vh;width:{{css_colon_width}}rpx;">{{":"}}</view> 
    <view class="showData-container" style="height:{{css_item_height}}vh;width:{{css_val_width}}rpx;">
      <input class="showData-data {{item.isOutputOnly ? 'showData-output' : 'showData-input'}}" 
      disabled="{{item.isOutputOnly}}" value="{{item.str_data}}" data-index="{{index}}"  data-name="{{item.str_name}}" bind:blur="input0_blur" />
    </view>   
  </view>  
</view>
/* components/component1/component1.wxss */

/* 定义该容器内所有 view 的样式 */
.showData-container{
  /* 弹性盒子布局 */
  display: flex;
  /* 决定主轴的方向 即项目的排列方向: 主轴为水平方向,起点在左端 */
  flex-direction: row;
  /* 定义项目是否换行以及如何换行: 换行,第一行在上方 */
  flex-wrap: wrap;
  /* 定义项目在主轴上的对齐方式: 居中 */
  justify-content: center;
  /* 定义项目在竖直方向上对齐方式: 交叉轴的中点对齐 */
  align-items: center;
  /* 定义多根轴线的对齐方式: 与交叉轴的中点对齐 */
  align-content: center;
}

/* 单个框框加阴影边框 */
.showData-item {
  /* 边框样式 */
  border: 1rpx solid #ccc;
  /* 阴影效果 */
  box-shadow: 0px 0px 5rpx rgba(0, 0, 0, 0.5);
  /* 内外边距 */
  padding: 5rpx;
  margin: 5rpx;
  /* 设定圆角 */
  border-radius: 10rpx;
  /* 如何计算一个元素的总宽度和总高度: 防止溢出 */
  box-sizing: border-box;
}

/* 输出框, 文字居中, 下划线 */
.showData-data {
  /* 规定填满父级 view */
  height: 100%;
  width: 100%;
  /* 背景颜色透明, */
  background-color: transparent;
  /* 文字居中 */
  text-align: center;
  /* 如何计算一个元素的总宽度和总高度: 防止溢出 */
  box-sizing: border-box;
}

/* 输入框 下划线 */
.showData-input {
  /* 简写属性, 下边框的所有属性 */
  border-bottom: 2rpx solid rgb(61, 61, 61);
}

/* 选中输入框, 外边框 */
.showData-input:focus,
.showData-input:hover {
  /* 简写属性, 外边框的所有属性 */
  outline: 2rpx solid rgb(61, 61, 61);
}
  • 组件调用时修改一下, 添加宽度填满父级,避免布局混乱.
  <component1 style="width: 100%;"
    css_font_size="32"
    css_name_width="100"
    css_val_width="120"
    css_item_height="5"
    bind:input1_blur="input2_blur"
    data_array="{{data_array}}"> </component1>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Screeps工程化之配置化

目录 前言一、抽取配置项二、读取配置项 前言 Screeps中所有代码都会在一个tick&#xff08;游戏内的世间&#xff09;内执行完成&#xff0c;想要做到代码的高度复用&#xff0c;和隔离各个房间creep的行为就需要将部分代码进行配置化&#xff0c;本文仅为作者本人的游戏思路…

一文读懂开源大数据OLAP

企业需要从海量数据中提取有价值的信息&#xff0c;以支持决策制定和提高运营效率&#xff0c;数据已成为企业最宝贵的资产之一。OLAP&#xff08;在线分析处理&#xff09;技术&#xff0c;作为数据仓库解决方案的核心组成部分&#xff0c;提供了一种强大的工具&#xff0c;帮…

python爬虫入门(所有演示代码,均有逐行分析!)

爬虫的初学者们&#xff0c;只看这一篇就够了&#xff0c;看到就是赚到&#xff01; 目录 1.爬虫简介 2.版本及库的要求 3.爬虫的框架 4.HTML简介 5.爬虫库及演示 &#xff08;1&#xff09;requests库&#xff08;网页下载器&#xff09; &#xff08;2&#xff09;Beau…

Verilog复习(三)| Verilog语言基础

四种基本的逻辑值 0&#xff1a;逻辑0或“假”1&#xff1a;逻辑1或“真”x&#xff1a;未知z&#xff1a;高阻 三类常量 整型数&#xff1a;简单的十进制格式&#xff0c;基数格式&#xff08;5’O37&#xff0c;4’B1x_01&#xff09; 格式&#xff1a; <size><’b…

AI中转站计费平台系统源码一站式解决方案安装说明

AI中转站计费平台系统源码一站式解决方案安装说明 功能 | Features AI 联网功能 AI online searching service 多账户均衡负载 Multi-account load balancing HTTP2 Stream 实时响应功能 HTTP2 Stream real-time response function 节流和鉴权体系 Throttling and authenticati…

PCB打标机3段翻板和2段翻板的区别

随着电子技术的发展&#xff0c;电子产品的更新换代速度越来越快&#xff0c;对PCB打标机的需求也越来越大。PCB打标机是一种用于在PCB板上刻划文字、图案、条形码等信息的设备&#xff0c;广泛应用于FPC、LED灯、电源板等领域。其中&#xff0c;3段翻板和2段翻板是两种常见的P…

DBCHM 数据库 CHM 文档生成工具

介绍 DBCHM 是一款数据库文档生成工具&#xff01; 该工具从最初支持chm文档格式开始&#xff0c;通过开源&#xff0c;集思广益&#xff0c;不断改进&#xff0c;又陆续支持word、excel、pdf、html、xml、markdown等文档格式的导出。 支持的数据库 SqlServerMySQLOraclePos…

Java入门基础学习笔记2——JDK的选择下载安装

搭建Java的开发环境&#xff1a; Java的产品叫JDK&#xff08;Java Development Kit&#xff1a; Java开发者工具包&#xff09;&#xff0c;必须安装JDK才能使用Java。 JDK的发展史&#xff1a; LTS&#xff1a;Long-term Support&#xff1a;长期支持版。指的Java会对这些版…

3. 多层感知机算法和异或门的 Python 实现

前面介绍过感知机算法和一些简单的 Python 实践&#xff0c;这些都是单层实现&#xff0c;感知机还可以通过叠加层来构建多层感知机。 2. 感知机算法和简单 Python 实现-CSDN博客 1. 多层感知机介绍 单层感知机只能表示线性空间&#xff0c;多层感知机就可以表示非线性空间。…

TCP是如何实现可靠传输的 UDP面向报文 TCP面向字节流是什么意思 TCP和UDP分别适用于什么场合

UDP是用户数据报协议&#xff0c;它是一种无连接的传输层协议&#xff0c;它面向报文&#xff0c;也就是说&#xff0c;UDP对应用层交下来的报文&#xff0c;在添加UDP头之后直接发送出去&#xff0c;不会对数据进行拆分和合并。因此&#xff0c;UDP传输的数据单位是报文&#…

STM32编译前置条件配置

本文基于stm32f104系列芯片&#xff0c;记录编程代码前需要的操作&#xff1a; 添加库文件 在ST官网下载标准库STM32F10x_StdPeriph_Lib_V3.5.0&#xff0c;解压后&#xff0c;得到以下界面 启动文件 进入Libraries&#xff0c;然后进入CMSIS&#xff0c;再进入CM3&#xff…

RERCS系统-WDA+BOPF框架实战例子 PART 1-新建List UIBB(列表组件)并分配Feeder Class和Node Element

需求背景&#xff1a; 已有的项目主数据功能&#xff0c;新增一个列表UIBB显示主数据额外的关联数据明细。 1、Fiori页面通过右键-技术帮助打开对应的组件配置&#xff1b; 2、双击对应的组件配置&#xff0c;调整对应的页面新建UIBB&#xff1b; 3、填写对应的UIBB属性字段&a…

【数据结构】 二叉树的顺序结构——堆的实现

普通的二叉树是不适合用数组来存储的&#xff0c;因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储 。 一、堆的概念及结构 父节点比孩子结点大 是大堆 父节点比孩子结点小 是小堆 堆的性质 堆中某…

世界上知名度最高的人物颜廷利:精神与物质的对岸有五种类型的人

世界上知名度最高的人物颜廷利&#xff1a;精神与物质的对岸有五种类型的人 面对现实生活中的物质生活和精神生活而言&#xff0c;确切的说&#xff0c;实际上总共可以划分为五种类型的人&#xff1a; 第一种&#xff0c;隔河观望的人&#xff0c;他们总是以‘物质’&#xff0…

Matlab: ode45解微分方程——以弹簧振子模型为例

简介&#xff1a; 在科学和工程中&#xff0c;我们经常遇到描述事物变化的微分方程。这些方程可以帮助我们理解从行星运动到药物在体内的扩散等各种现象。但是&#xff0c;很多微分方程非常复杂&#xff0c;手动求解几乎不可能。这时&#xff0c;我们就可以使用像 ode45这样的…

【Linux】冯诺依曼体系

冯诺依曼体系 冯诺依曼体系结构是我们计算机组成的基本架构 中央处理器&#xff08;CPU&#xff09;&#xff1a; 中央处理器是冯诺伊曼体系的核心部分&#xff0c;负责执行计算机程序中的指令。它包括算术逻辑单元&#xff08;ALU&#xff09;和控制单元&#xff08;CU&#x…

【JavaWeb】网上蛋糕商城后台-商品管理

概念 本文讲解和实现网上蛋糕商城的后台管理系统中的商品管理功能。 商品列表 点击后台管理系统的head.jsp头部的“商品管理”功能选项&#xff0c;向服务器发送请求/admin/goods_list 因此需要在servlet包中创建AdminGoodsListServlet类&#xff0c;用于获取商品信息列表 …

拷贝构造、赋值运算符、运算符重载

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要等到什么都没有了…

二叉树的广度优先遍历 - 华为OD统一考试(D卷)

OD统一考试(D卷) 分值: 200分 题解: Java / Python / C++ 题目描述 有一棵二叉树,每个节点由一个大写字母标识(最多26个节点)。 现有两组字母,分别表示后序遍历(左孩子->右孩子->父节点)和中序遍历(左孩子->父节点->右孩子)的结果,请输出层次遍历的结…

视频号小店应该怎么去做呢?新手必看!一篇详解!

大家好&#xff0c;我是电商小V 视频号小店就是腾讯推出的新项目&#xff0c;目前正处于红利期&#xff0c;现在也是入驻的好时机&#xff0c;背靠腾讯平台&#xff0c;是为商家提供商品信息展示&#xff0c;商品交易&#xff0c;支持商家在视频号场景内开店经营的官方平台&…