转载请注明出处:王亟亟的大牛之路
最近公司项目忙得不可开交,各种不可描述的事情,然后学习基本停机。这个周末没出去浪,就在家把之前王夫人给我设计的小程序做了做,然后一步步分享做的过程中遇到的问题和积累,希望大家爬坑过程中能帮到一些吧
组件化
组件化本身是一个可以讲的很大,也可以浓缩为
封装可复用的,模版组件
基于mvvm的微信小程序当然也支持这一特性,我们做项目的时候也可以把注入公用的header footer之类的封一封(其实工具类的组装也可以作为组件化的一种形式)
小程序的组件化挺有意思的基于Component,自行实现了一套比较深的实现(这篇不讲实现),第一次看感觉跟Page好,或者说是换汤不换药。但内部组件(页面)的生命周期,事件处理等有自己的特点,这个之后再写的时候再提吧
然后微信,本身的sample已经写清楚了一些要素,那我这边也就在这个基础上做发散,官方传送门如下:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/
目录结构
这边贴一下代码结构
蓝色是自定义的组件(啊呀,好像没取components/nav这类名字)
红色是引用他的首页
设计图长这样
做的长这样(UI还没调,效果先实现吧,反正大家也就看个思路,长啥样无所谓了)
实现
功能来源是https://github.com/Tencent/weui-wxss组件库中提取出来的,我做的工作就是把本来Page页面改成Component,然后给大家理一理过程。
首先是提取功能代码在
dist/example/navbar目录下,有3个文件
我们先完全copy过来,然后添加一个navbar.json文件
navbar.json
{
"component": true,
"usingComponents": {}
}
如果有用到其他组件,那就定义一下,没有的话可以不管。
component要为true。(证明我是谁嘛,这个好理解)
因为设计图只需要2个tab页,所以把navbar.wxml文件进行了微调(没有重要步骤的我就不多做解释了)
<view class="page">
<view class="page__bd">
<view class="weui-tab">
<view class="weui-navbar">
<block wx:for="{{tabs}}" wx:key="*this">
<view id="{{index}}" class="weui-navbar__item {{activeIndex == index ? 'weui-bar__item_on' : ''}}" bindtap="tabClick">
<view class="weui-navbar__title">{{item}}</view>
</view>
</block>
<view class="weui-navbar__slider" style="left: {{sliderLeft}}px; transform: translateX({{sliderOffset}}px); -webkit-transform: translateX({{sliderOffset}}px);"></view>
</view>
<view class="weui-tab__panel">
<view class="weui-tab__content" hidden="{{activeIndex != 0}}">PHOTO</view>
<view class="weui-tab__content" hidden="{{activeIndex != 1}}">BLOG</view>
</view>
</view>
</view>
</view>
这边任意一个点击都会触发tabClick()这个方法
class=”weui-navbar__slider”的这个view用来绘制内容偏移的动画
样式这块,空间本身有一些属性,然后微信这套设计有一个自己的风格,复制的时候从多个地方扣过来。
navbar.wxss
/*!
* WeUI v1.1.1 (https://github.com/weui/weui-wxss)
* Copyright 2017 Tencent, Inc.
* Licensed under the MIT license
*/
.weui-navbar {
margin-top: 50px;
display: -webkit-box;
display: -webkit-flex;
display: flex;
position: absolute;
z-index: 500;
top: 0;
width: 100%;
border-bottom: 1rpx solid #ccc;
}
.weui-navbar__item {
position: relative;
display: block;
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
padding: 13px 0;
text-align: center;
font-size: 0;
}
.weui-navbar__item.weui-bar__item_on {
color: #F5CD79;
}
.weui-navbar__slider {
position: absolute;
content: " ";
left: 0;
bottom: 0;
width: 50%;
height: 3px;
background-color: #F5CD79;
-webkit-transition: -webkit-transform 0.3s;
transition: -webkit-transform 0.3s;
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
}
.weui-navbar__title {
display: inline-block;
font-size: 15px;
max-width: 8em;
width: auto;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
word-wrap: normal;
}
.weui-tab__panel {
box-sizing: border-box;
height: 100%;
padding-top: 50px;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
然后就是逻辑选手navbar.js (解释我写在注释里吧)
var sliderWidth = 96; // 需要设置slider的宽度,用于计算中间位置
Component({
properties: {
// 这里定义了tabs属性,属性值可以在组件使用时指定,类似于react的props和proptype
tabs: {
type: [],
value: ["PHOTO1", "BLOG1"],
}
},
data: {
// 初始化一些默认值ß
activeIndex: 0,
sliderOffset: 0,
sliderLeft: 0
},
created: function () {
//空间被创建时触发
console.log('--->navbar Component created')
var that = this;
wx.getSystemInfo({
success: function (res) {
that.setData({
sliderLeft: (res.windowWidth / that.data.tabs.length - sliderWidth) / 2,
sliderOffset: res.windowWidth / that.data.tabs.length * that.data.activeIndex
});
}
});
},
methods: {
// 按钮行为触发状态机变化
tabClick: function (e) {
this.setData({
sliderOffset: e.currentTarget.offsetLeft,
activeIndex: e.currentTarget.id
});
}
}
});
触发生命周期如图
也是由内向外计算,渲染,加载
主页面调用
首先,先添加引用
{
"usingComponents": {
"Nav": "../../common/navbar/navbar"
}
}
然后在页面里像使用普通控件一样使用就行了
<Nav tabs="{{数据源}}"></Nav>
总结:
网上有许多自定义tab的一些方案,无非就是写复杂的viewgroup然后用hidfe show替换
或者是改写swipe来实现。
本文的例子更偏向第一种,但是又有像swipe的滑动动画
具体的内容分析,之后会补上,这一篇作为开始,先撸个东西,之后再努力做好吧!
源码等这一系列结束后,放出吧(但是跟着步骤做的话一定是可以把demo撸出来的)