1. 플렉스 레이아웃
[box model] 을 기반으로 하는 전통적인 레이아웃 솔루션은 표시 속성 + 위치 속성 + 부동 속성 에 의존합니다.
1. 플렉스 레이아웃이란 무엇입니까?
- Flex는 유연한 레이아웃 (flexible Layout)이라는 뜻을 가진 Flex Box 의 약어 로, 박스 형태의 모델에 최대한의 유연성을 제공하기 위해 사용됩니다.
- 모든 컨테이너를 Flex 레이아웃으로 지정할 수 있습니다.
- 디스플레이: '플렉스'
컨테이너에는 기본적으로 가로 기본 축과 세로 교차 축이라는 두 개의 축이 있습니다 .
- 주축의 시작 위치(경계와의 교차점)를 주 시작이라고 하고 끝 위치를 주 끝이라고 합니다.
- 교차축의 시작 위치를 교차 시작, 끝 위치를 교차 끝이라고 합니다.
항목은 기본적으로 기본 축을 따라 정렬됩니다. 단일 항목이 차지하는 주축 공간을 기본 크기라고 하며, 단일 항목이 차지하는 교차축 공간을 교차 크기라고 합니다.
2. 플렉스 속성
속성 | 효과 |
---|---|
플렉스 방향 | 주축의 방향은 기본적으로 행 방향입니다. |
플렉스 랩 | 하나의 축 선을 정렬할 수 없는 경우 선을 어떻게 감싸야 합니까? |
플렉스 플로우 | flex-direction 속성과 flex-wrap 속성의 약자입니다. |
정당화 내용 | 주축에서 항목의 정렬을 정의합니다. |
항목 정렬 | 교차축에서 항목이 정렬되는 방식 정의 |
내용 정렬 | 속성은 여러 축의 정렬을 정의합니다. |
[참고] Flex 레이아웃으로 설정한 후에는 하위 요소의 float,clear,vertical-align 속성이 유효하지 않습니다.
flex-direction
기본 축(컨테이너의 기본 축을 따라)에서 하위 요소의 배열을 정의합니다. 여기에는 다음 값이 포함됩니다.
row
(기본값): 하위 요소가 주축을 기준으로 왼쪽에서 오른쪽으로 배열됩니다.row-reverse
: 하위 요소는 주축을 기준으로 오른쪽에서 왼쪽으로 배열됩니다.column
: 하위 요소는 주축을 기준으로 위에서 아래로 배열됩니다.column-reverse
: 하위 요소는 주축을 기준으로 아래에서 위로 배열됩니다.
flex-wrap
컨테이너 너비가 충분하지 않을 때 하위 요소가 어떻게 래핑되는지 정의합니다. 여기에는 다음 값이 포함됩니다.
nowrap
(기본값): 하위 요소는 줄바꿈되지 않으며, 컨테이너 너비를 초과하는 부분은 압축됩니다.wrap
: 하위 요소는 한 줄씩 줄바꿈되며, 컨테이너 너비를 초과하는 하위 요소는 다음 줄로 이동됩니다.wrap-reverse
: 하위 요소는 반대 행으로 줄바꿈되며, 컨테이너 너비를 초과하는 하위 요소는 다음 줄부터 정렬됩니다.
flex-flow
flex-direction
및 두 가지 속성flex-wrap
의 약어 입니다 . 여기에는 공백으로 구분된 두 개의 값이 포함됩니다.
flex-direction
값(기본값은row
)입니다.flex-wrap
값(기본값은nowrap
)입니다.
justify-content
기본 축에서 하위 요소의 정렬을 정의합니다. 여기에는 다음 값이 포함됩니다.
flex-start
(기본값): 하위 요소는 컨테이너의 시작 가장자리를 기준으로 배열됩니다.flex-end
: 하위 요소는 컨테이너 끝 근처에 배열됩니다.center
: 하위 요소는 컨테이너의 기본 축 중앙에 배치됩니다.space-between
: 하위 요소는 컨테이너에 고르게 분산됩니다. 첫 번째 하위 요소는 시작 가장자리에 있고 마지막 하위 요소는 마지막 가장자리에 있습니다.space-around
: 하위 요소는 하위 요소 사이에 공백을 두고 컨테이너에 고르게 분산됩니다.
align-items
교차 축(주 축에 수직인 축)에서 하위 요소의 정렬을 정의합니다. 여기에는 다음 값이 포함됩니다.
stretch
(기본값): 하위 요소가 교차 축을 채우기 위해 늘어납니다.flex-start
: 하위 요소는 교차축의 시작 가장자리에 정렬됩니다.flex-end
: 하위 요소는 교차축의 마지막 가장자리에 정렬됩니다.center
: 하위 요소는 컨테이너의 교차축 중앙에 배치됩니다.baseline
: 하위 요소는 기준선을 기준으로 정렬됩니다.
align-content
교차축에서 하위 요소의 여러 행 정렬을 정의합니다. 다음 값을 포함하여 여러 행의 하위 요소가 있는 경우에만 적용됩니다.
stretch
(기본값): 여러 행의 하위 요소가 교차 축을 채우기 위해 늘어납니다.flex-start
: 여러 행의 하위 요소가 교차축의 시작 가장자리에 정렬됩니다.flex-end
: 여러 행의 하위 요소가 교차축의 끝 가장자리에 정렬됩니다.center
: 여러 행의 하위 요소가 컨테이너의 교차축 중앙에 배치됩니다.space-between
: 여러 행의 하위 요소가 컨테이너에 고르게 분포되어 있으며 첫 번째 행은 시작 가장자리에, 마지막 행은 마지막 가장자리에 있습니다.space-around
: 여러 행의 하위 요소가 컨테이너에 균등하게 분산되며 각 행 사이에는 공백이 있습니다.
더 많은 예제를 직접 테스트해야 합니다 . 자세한 내용은 공식 웹사이트 AIP 애플릿 구성 | WeChat 공개 문서를 보거나 Flex 레이아웃 구문 튜토리얼 | Rookie 튜토리얼(runoob.com)을 참조 하세요.
2. 종합사례
1、스와이프
1.1 공통 속성
속성 | 유형 | 기본값 | 필수의 | 설명하다 | 최소 버전 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
표시 점 | 부울 | 거짓 | 아니요 | 패널 표시점 표시 여부 | 1.0.0 | |||||||||||||
표시기 색상 | 색상 | RGBA(0, 0, 0, .3) | 아니요 | 포인터 색상 | 1.1.0 | |||||||||||||
표시기 활성 색상 | 색상 | #000000 | 아니요 | 현재 선택된 표시점의 색상 | 1.1.0 | |||||||||||||
자동 재생 | 부울 | 거짓 | 아니요 | 자동으로 전환할지 여부 | 1.0.0 | |||||||||||||
현재의 | 숫자 | 0 | 아니요 | 현재 슬라이더의 인덱스 | 1.0.0 | |||||||||||||
간격 | 숫자 | 5000 | 아니요 | 자동 전환 시간 간격 | 1.0.0 | |||||||||||||
지속 | 숫자 | 500 | 아니요 | 슬라이드 애니메이션 지속 시간 | 1.0.0 | |||||||||||||
회보 | 부울 | 거짓 | 아니요 | 연결 슬라이딩 사용 여부 | 1.0.0 | |||||||||||||
수직의 | 부울 | 거짓 | 아니요 | 슬라이딩 방향이 세로인지 여부 | 1.0.0 | |||||||||||||
다중 항목 표시 | 숫자 | 1 | 아니요 | 동시에 표시되는 슬라이더 수 | 1.9.0 | |||||||||||||
완화 기능 | 끈 | "기본" | 아니요 | 이징 애니메이션 유형을 전환하려면 스와이프를 지정하세요. | 2.6.5 | |||||||||||||
|
||||||||||||||||||
바인드체인지 | 이벤트 핸들 | 아니요 | 현재 변경사항이 있을 때 변경 이벤트가 트리거됩니다. event.detail = {current, source} | 1.0.0 | ||||||||||||||
바인딩 전환 | 이벤트 핸들 | 아니요 | swiper-item의 위치가 변경되면 전환 이벤트가 트리거됩니다. event.detail = {dx: dx, dy: dy}. Skyline은 비worklet 구성요소 메소드만 콜백으로 지원합니다. | 2.4.3 | ||||||||||||||
바인딩애니메이션마무리 | 이벤트 핸들 | 아니요 | animationfinish 이벤트는 애니메이션이 끝나면 발생하며, event.detail은 위와 동일합니다. Skyline은 비worklet 구성요소 메소드만 콜백으로 지원합니다. | 1.9.0 |
2. 홈하단메뉴
새로운 미니 프로그램 프로젝트를 생성한 후, 새로운 페이지를 생성하고 app.json 의 페이지 에 tabBer를 바인딩합니다 .
app.json
{
"pages": [
"pages/index/index",
"pages/meeting/list/list",
"pages/vote/list/list",
"pages/ucenter/index/index",
"pages/logs/logs"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle": "black"
},
"tabBar": {
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "/static/tabBar/coding.png",
"selectedIconPath": "/static/tabBar/coding-active.png"
},
{
"pagePath": "pages/meeting/list/list",
"iconPath": "/static/tabBar/sdk.png",
"selectedIconPath": "/static/tabBar/sdk-active.png",
"text": "会议"
},
{
"pagePath": "pages/vote/list/list",
"iconPath": "/static/tabBar/template.png",
"selectedIconPath": "/static/tabBar/template-active.png",
"text": "投票"
},
{
"pagePath": "pages/ucenter/index/index",
"iconPath": "/static/tabBar/component.png",
"selectedIconPath": "/static/tabBar/component-active.png",
"text": "设置"
}
]
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}
효과
3. 홈페이지 콘텐츠 구축
3.1 백엔드 인터페이스 생성
프로젝트에 config/api.js 파일을 생성하고 ,
// 以下是业务服务器API地址 // 本机开发API地址 var WxApiRoot = 'http://localhost:8080/demo/wx/'; // 测试环境部署api地址 // var WxApiRoot = 'http://192.168.0.101:8070/demo/wx/'; // 线上平台api地址 //var WxApiRoot = 'https://www.oa-mini.com/demo/wx/'; module.exports = { IndexUrl: WxApiRoot + 'home/index', //首页数据接口 SwiperImgs: WxApiRoot+'swiperImgs', //轮播图 MettingInfos: WxApiRoot+'meeting/list', //会议信息 };
3.2 모의 데이터 생성
우리는 액체 레벨의 배경에 연결되어 있지 않으므로 애플릿의 Mock을 사용하여 일부 가짜 데이터를 시뮬레이션할 수 있습니다.
우리의 가짜 데이터를 사용하여 7 에 넣으세요.
{ "data": { "images":[ { "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner1.png", "text": "1" }, { "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner2.png", "text": "2" }, { "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner3.png", "text": "3" }, { "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner4.png", "text": "4" }, { "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner5.png", "text": "5" }, { "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner6.png", "text": "6" } ] }, "statusCode": "200", "header": { "content-type":"applicaiton/json;charset=utf-8" } }
우리는 홈페이지에 메소드 테스트를 작성합니다.
index.js
// index.js // 获取应用实例 const app = getApp() const api = require("../../config/api") Page({ data: { imgSrcs:[] }, // 事件处理函数 bindViewTap() { wx.navigateTo({ url: '../logs/logs' }) }, // 轮播图的方法 loadSwiperImgs(){ let that=this; wx.request({ url: api.SwiperImgs, dataType: 'json', success(res) { console.log(res) that.setData({ imgSrcs:res.data.images }) } }) }, onLoad() { if (wx.getUserProfile) { this.setData({ canIUseGetUserProfile: true }) } // 一进来就调用轮播图的方法 this.loadSwiperImgs(); }, getUserProfile(e) { // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗 wx.getUserProfile({ desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写 success: (res) => { console.log(res) this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } }) }, getUserInfo(e) { // 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息 console.log(e) this.setData({ userInfo: e.detail.userInfo, hasUserInfo: true }) } })
중요한 코드
const api = require("../../config/api") Page({ data: { imgSrcs:[] }, // 轮播图的方法 loadSwiperImgs(){ let that=this; wx.request({ url: api.SwiperImgs, dataType: 'json', success(res) { console.log(res) that.setData({ imgSrcs:res.data.images }) } }) }, onLoad() { if (wx.getUserProfile) { this.setData({ canIUseGetUserProfile: true }) } // 一进来就调用轮播图的方法 this.loadSwiperImgs(); } })
[참고] 이 위치에서 이것을 여는 것을 잊지 마세요
컴파일 후 컴파일러에 출력된 데이터를 확인합니다.
3.3 캐러셀 차트 만들기
이전에 액체 수위 데이터를 이미 설정했으므로 여기에 캐러셀 차트 페이지를 작성합니다.
<view> <swiper autoplay="true" indicator-dots="true" indicator-color="#fff" indicator-active-color="#00f"> <block wx:for="{ {imgSrcs}}" wx:key="text"> <swiper-item> <view> <image src="{ {item.img}}" class="swiper-item" /> </view> </swiper-item> </block> </swiper> </view>
3.4 사례--홈페이지 콘텐츠 구축
우리는 콘텐츠의 예를 제공하기 위해 회의 사례를 사용합니다.
이전 단계를 기반으로 홈페이지에서 호출되는 메서드를 만듭니다 .
//首页内容 loadMeetingInfos() { let that = this; wx.request({ url: api.MettingInfos, dataType: 'json', success(res) { console.log(res) that.setData({ lists: res.data.lists }) } }) }
Mack를 사용하여 데이터 시뮬레이션
JSON 데이터 패킷
{ "data": { "lists": [ { "id": "1", "image": "/static/persons/1.jpg", "title": "对话产品总监 | 深圳·北京PM大会 【深度对话小米/京东/等产品总监】", "num":"304", "state":"进行中", "starttime": "2022-03-13 00:00:00", "location": "深圳市·南山区" }, { "id": "1", "image": "/static/persons/2.jpg", "title": "AI WORLD 2016世界人工智能大会", "num":"380", "state":"已结束", "starttime": "2022-03-15 00:00:00", "location": "北京市·朝阳区" }, { "id": "1", "image": "/static/persons/3.jpg", "title": "H100太空商业大会", "num":"500", "state":"进行中", "starttime": "2022-03-13 00:00:00", "location": "大连市" }, { "id": "1", "image": "/static/persons/4.jpg", "title": "报名年度盛事,大咖云集!2016凤凰国际论坛邀您“与世界对话”", "num":"150", "state":"已结束", "starttime": "2022-03-13 00:00:00", "location": "北京市·朝阳区" }, { "id": "1", "image": "/static/persons/5.jpg", "title": "新质生活 · 品质时代 2016消费升级创新大会", "num":"217", "state":"进行中", "starttime": "2022-03-13 00:00:00", "location": "北京市·朝阳区" } ] }, "statusCode": "200", "header": { "content-type":"applicaiton/json;charset=utf-8" } }
공들여 나열한 것
<view class="indexbg"> <swiper autoplay="true" indicator-dots="true" indicator-color="#fff" indicator-active-color="#00f"> <block wx:for="{ {imgSrcs}}" wx:key="text"> <swiper-item> <view> <image src="{ {item.img}}" class="swiper-item" /> </view> </swiper-item> </block> </swiper> <view class="mobi-title"> <text class="mobi-icon">❤</text> <text class="mobi-text">会议信息</text> </view> <block wx:for-items="{ {lists}}" wx:for-item="item" wx:key="item.id" class="bg"> <view class="list" data-id="{ {item.id}}"> <view class="list-img"> <image class="video-img" mode="scaleToFill" src="{ {item.image}}"></image> </view> <view class="list-detail"> <view class="list-title"><text>{ {item.title}}</text></view> <view class="list-tag"> <view class="state">{ {item.state}}</view> <view class="join"><text class="list-num">{ {item.num}}</text>人报名</view> </view> <view class="list-info"><text>{ {item.location}}</text>|<text>{ {item.starttime}}</text></view> </view> </view> </block> <view class="section"> <text>到底啦</text> </view> </view>
index.js
// index.js // 获取应用实例 const app = getApp() const api = require("../../config/api") Page({ data: { imgSrcs: [{ "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner1.png", "text": "1" }, { "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner2.png", "text": "2" }, { "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner3.png", "text": "3" }, { "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner4.png", "text": "4" }, { "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner5.png", "text": "5" }, { "img": "https://cdn-we-retail.ym.tencent.com/tsr/home/v2/banner6.png", "text": "6" }], "lists": [ { "id": "1", "image": "/static/persons/1.jpg", "title": "对话产品总监 | 深圳·北京PM大会 【深度对话小米/京东/等产品总监】", "num": "304", "state": "进行中", "starttime": "2022-03-13 00:00:00", "location": "深圳市·南山区" }, { "id": "1", "image": "/static/persons/2.jpg", "title": "AI WORLD 2016世界人工智能大会", "num": "380", "state": "已结束", "starttime": "2022-03-15 00:00:00", "location": "北京市·朝阳区" }, { "id": "1", "image": "/static/persons/3.jpg", "title": "H100太空商业大会", "num": "500", "state": "进行中", "starttime": "2022-03-13 00:00:00", "location": "大连市" }, { "id": "1", "image": "/static/persons/4.jpg", "title": "报名年度盛事,大咖云集!2016凤凰国际论坛邀您“与世界对话”", "num": "150", "state": "已结束", "starttime": "2022-03-13 00:00:00", "location": "北京市·朝阳区" }, { "id": "1", "image": "/static/persons/5.jpg", "title": "新质生活 · 品质时代 2016消费升级创新大会", "num": "217", "state": "进行中", "starttime": "2022-03-13 00:00:00", "location": "北京市·朝阳区" } ] }, // 事件处理函数 bindViewTap() { wx.navigateTo({ url: '../logs/logs' }) }, // 轮播图的方法 loadSwiperImgs() { let that = this; wx.request({ url: api.SwiperImgs, dataType: 'json', success(res) { console.log(res) that.setData({ imgSrcs: res.data.images }) } }) }, //首页会议信息的ajax loadMeetingInfos() { let that = this; wx.request({ url: api.MettingInfos, dataType: 'json', success(res) { console.log(res) that.setData({ lists: res.data.lists }) } }) }, onLoad() { if (wx.getUserProfile) { this.setData({ canIUseGetUserProfile: true }) } // 一进来就调用轮播图的方法 this.loadSwiperImgs(); }, getUserProfile(e) { // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗 wx.getUserProfile({ desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写 success: (res) => { console.log(res) this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } }) }, getUserInfo(e) { // 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息 console.log(e) this.setData({ userInfo: e.detail.userInfo, hasUserInfo: true }) } })
wxss
/**index.wxss**/ .userinfo { display: flex; flex-direction: column; align-items: center; color: #aaa; } .userinfo-avatar { overflow: hidden; width: 128rpx; height: 128rpx; margin: 20rpx; border-radius: 50%; } .usermotto { margin-top: 200px; } /**index.wxss**/ .section { color: #aaa; display: flex; justify-content: center; } .list-info { color: #aaa; } .list-num { color: red; /* font-weight: 700; */ } .join { padding: 0px 0px 0px 10px; color: #aaa; } .state { margin: 0px 6px 0px 6px; border: 1px solid #4083ff; color: #4083ff; padding: 3px 5px 3px 5px; } .list-tag { padding: 3px 0px 10px 0px; display: flex; align-items: center; } .list-title { display: flex; justify-content: space-between; font-size: 11pt; color: #333; font-weight: bold; } .list-detail { display: flex; flex-direction: column; margin: 0px 0px 0px 15px; } .video-img { width: 80px; height: 80px; } .list { display: flex; flex-direction: row; background-color: seashell; border-bottom: 1px solid #cecece; padding: 10px; } .mobi-text { font-weight: 700; padding: 15px; } /* .mobi-icon { border-left: 5px solid #57f564; } */ .indexbg{ background-color: rgba(219, 219, 219, 0.678); } .mobi-title { /* background-color: rgba(219, 219, 219, 0.678); */ margin: 10px 0px 10px 0px; } .swiper-item { height: 300rpx; width: 100%; border-radius: 10rpx; } .userinfo { display: flex; flex-direction: column; align-items: center; color: #aaa; } .userinfo-avatar { overflow: hidden; width: 128rpx; height: 128rpx; margin: 20rpx; border-radius: 50%; } .usermotto { margin-top: 200px; }