1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 微信小程序|开发实战篇之九-image-picker图片选择器组件及其子组件

微信小程序|开发实战篇之九-image-picker图片选择器组件及其子组件

时间:2021-12-30 06:55:39

相关推荐

微信小程序|开发实战篇之九-image-picker图片选择器组件及其子组件

开发实战篇之九

前言1、grid格子组件1.1 grid骨架文件wxml1.2 grid的js文件分析1.3 grid-item的wxml文件分析1.4 grid-item的wxss文件分析1.5 grid在页面中的使用2、image-picker图片选择组件

前言

实战篇内容参考:

1、Lin Ui开源组件源码分析。https://doc./

2、开发过程遇到问题。

1、grid格子组件

分析:grid组件是一整个布局,为了使得布局具有灵活性,因此将grid中的单元也抽象出来成为grid-item组件。

1.1 grid骨架文件wxml

<view class="x-grid x-class" bind:tap="tapGrid"><view bind:tap="tapGridItem"data-grid-index="{{item.index}}"class="x-grid-item x-class-grid x-grid-class {{index%rowNum !== rowNum-1 &&(showBorder||showColBorder) ? 'side-grid':''}} {{(index<gridItems.length-(gridItems.length%rowNum||rowNum)) &&(showBorder||showRowBorder)? 'center-grid':''}}" wx:for="{{gridItems}}" wx:key="key"style="min-width:{{100/rowNum}}%;"><slot name="{{item.key}}"></slot></view></view>

为了在grid布局中添加新组件,因此就在view标签之间使用slot插槽。为整体的grid添加tapGrid监听事件,每一个grid-item添加tapGridItem监听事件。

1.2 grid的js文件分析

编写跟grid-item的父子组件关系,并触发initGrids函数。

relations: {'../grid-item/index': {type: 'child',// 关系建立在页面节点树时触发initGrids函数linked() {this.initGrids();},unlinked() {this.initGrids();}},},

// 初始化子组件数据,组件序号index、编号key、内容cellinitGrids() {// 1、获取所有的子组件节点itemslet items = this.getRelationNodes('../grid-item/index');// 子节点个数不变 不需要更新if (this.data.childNum === items.length) return;// 2、js语法通过map 获取数据对象 数组const gridItems = items.map((item, index) => {item.setData({index,});return {index:index,key: item.data.key,cell: item.data.cell};});// 页面渲染grid-item数据this.setData({gridItems: gridItems,childNum: items.length});},

给grid整体和grid-item都添加监听事件,这样就能够提供自定义定制功能。

// 点击grid-item// 获取当前排列的index,并以该index从gridItem[]中获取数据// data-grid-index="{{item.index}}"tapGridItem(e) {// console.log(e.target.dataset);const {gridIndex } = e.target.dataset;this.setData({currentIndex: gridIndex,currentCell: this.data.gridItems[gridIndex].cell});},// 点击grid整体tapGrid() {this.triggerEvent('gridtap', {index: this.data.currentIndex,cell: this.data.currentCell}, {bubbles: true, composed: true });// 重置当前itemthis.setData({currentIndex: -1,currentCell: -1});}

1.3 grid-item的wxml文件分析

使用viewhover-属性,使用isHover控制grid-item的点击事件,添加tap事件“tapGridItem

<viewhover-class="{{isHover?'x-grid-item-hover':''}}"hover-start-time="20"hover-stay-time="50"class="x-grid-item x-grid-item-class grid-item"mut-bind:tap="tapGridItem"><slot /></view>

hover-class决定点击事件时,对grid-item进行半透明处理。

1.4 grid-item的wxss文件分析

每个grid-item添加布局

.grid-item {display: flex;justify-content: center;align-items: center;flex-direction: column;padding: 32rpx 16rpx;box-sizing: border-box}.x-grid-item-hover {/* 透明度0.5 */opacity: .5}

1.5 grid在页面中的使用

index.wxml

<x-grid x-class="grid" show-border="{{true}}"><x-grid-item bind:griditemtap="clickGrid" wx:for="{{grids1}}" wx:key="{{index}}" key="{{index}}" slot="{{index}}"cell="{{item}}" ><x-icon name="{{item.image}}" /><view class="text">{{item.text}}</view></x-grid-item></x-grid>

index.js

clickGrid(event) {// console.log(event);wx.showToast({title: event.detail.cell.text,icon: 'none'}); },

2、image-picker图片选择组件

选择需要的图片上传,可自定义上传图片的数量。

image-picker的wxml文件:

<!--components/image-picker/index.wxml--><!-- 图片 --><x-grid row-num="{{ size }}" x-class="x-class"><x-grid-item wx:for="{{ urls }}" wx:key="index" key="{{ index }}" slot="{{ index }}" x-grid-item="x-grid-item"><view class="item x-item-class" catchtap="onPreviewTap" data-index="{{ index }}"><view class="close" data-index="{{ index }}" catchtap="onDelTap"><x-icon name="close" color="#fff" size="22" x-class="close-icon" /></view><image class="{{size === 3? 'img': 'min-img'}}" mode="{{ mode }}" src="{{newOrOld==='old'? item:item.url }}" /></view></x-grid-item><!-- add 按钮 --><x-grid-item wx:if="{{ showBtn }}" x-grid-item="x-grid-item"><!-- 自定义图片选择按钮 --><view class="item x-item-class {{size === 3? 'img': 'min-img'}}" catchtap="onAddTap" wx:if="{{ custom }}"><slot></slot></view><view class="item x-item-class {{size === 3? 'img': 'min-img'}}" catchtap="onAddTap" wx:else><image class="add-icon" src="./image/add.png" /></view></x-grid-item></x-grid>

思路主要是使用grid格子布局将图片通过wx:for="{{ urls }}"展示出来,然后有add添加按钮,进行添加图片。

主要分析下preview预览图片函数,使用urlscells区分两种图片的链接,一种是字符串数组,一种是字符串对象数组。然后在组件初始化时,使用变量newOrOld变量区分两种链接类型,预览时根据对cells数组的判断,newOrOld是否为old进行判断,然后将不同结构中存储的url放入previewImgList[]数组中去,再调用wx.previewImage()预览图片。

// 点击预览图片 previewonPreviewTap(e) {// 当前图片索引 data-indexconst index = e.currentTarget.dataset.index;// urls = 'http://...'类似的地址数组const urls = this.data.urls;let tempFilePath = '';// 预览list是字符串数组let previewImageList = [];const newOrOld = this.data.newOrOld;const cellsIsObject = Object.prototype.toString.call(this.data.cells) === '[object Object]';// 第一个 if 是对 cells 的兼容处理// 如果cells是object对象if (cellsIsObject) {const cells = this.data.cells;tempFilePath = cells[index].url;for (let i = 0; i < cells.length; i++) {previewImageList.push(cells[i].url);}} else if (newOrOld === 'old') {// old urls是字符串数组tempFilePath = this.data.urls[index];previewImageList = this.data.urls;} else {// cells中不是object,newOrOld === 'new'...// url中存的url是object对象tempFilePath = this.data.urls[index].url;for (let i = 0; i < urls.length; i++) {previewImageList.push(urls[i].url);}}// 因为wx预览图片需要当前图片和预览图片组,所以每次点击预览时生成previewImageListlet detail = {index, // 下标current: urls[index], // 当前显示图片的http链接all: urls // 需要预览的图片http链接列表};let option = {};if (this.data.preview === true) {wx.previewImage({current: tempFilePath, // 当前显示图片的http链接urls: previewImageList // 需要预览的图片http链接列表});}// 传递给父组件 当前显示的图片等数据this.triggerEvent('imgpreview', detail, option);},

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。