【微信小程序学习笔记02理解与初始准备】【实战天气微信小程序】
2018-09-16 16:20
585 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。(github:KuanG97) https://blog.csdn.net/m0_37136491/article/details/82694331
视图层
列表渲染
条件渲染
模板
事件
何为WXSS
实战天气wxapp
配置(因为用到别人写好的模拟天气数据的API作练习,为避免跨域问题)
代码
直接编译对应开发页码
涉及的核心知识点
实战天气的代码完整下载
快捷链接
2. 使用
3. 支持的选择器:
4. 全局(app.wxss)与局部(对应page文件夹里的.wxss,
目录
参与的udacity 微信小程序的纳米学位期间的学习笔记,其中代码或描述若有不足部分敬请指点,万分感谢!
注册小程序账号,获取AppID
要在手机微信上运行测试小程序,必须获取AppID。
开发准备
目录结构
当下基于ReactJs的AntDesignPro v2.0版本的目录使用了umiJs作为项目脚手架。与wxApp一样是基于功能与页面的维度的目录结构不再扁平化。
特点都是:结构更加清晰,减少耦合(独立,增加可维护性,),一删全删,方便 copy 和共享。
├── images ##推荐公共图片等资源放在此处! ├── pages # 业务页面入口和常用模板 │ ├── index # 同类型页面文件夹(基于功能与页面的维度的目录结构) │ │ - index.js ## 页面数据逻辑(必须) │ │ - index.wxml ## 页面结构(必须) │ │ - index.wxss ## 页面样式表(非必须) │ │ - index.jason ## 页面配置(非必须) │ └── logs # 日志 │ ├── logs.wxml │ └── logs.js ├── utils # 工具类 ├── app.js # 小程序逻辑(必须) ├── app.wxss # 小程序公共样式表(非必须) ├── app.jason # 小程序公共配置(必须)!决定页面路径、窗口、网络超时时间、设置tab
为了方便开发者减少配置项,描述页面的四个文件必须具有相同的路径与文件名。
删快速模板中不必要的代码
- 删除 app.js 中的所有代码。 这里会存储整个小程序会执行的一些逻辑,例如权限获取等。我们暂时不需要。
- 删除 app.wxss 中的所有代码。这里会存储整个小程序的一些样式。我们暂时不需要。
- 删除 app.json 中的第四行 “pages/logs/logs” 以及第三行最后的逗号,这里声明了小程序的第二个页面,我们暂时不需要。
- 删除 pages/logs 文件夹以及其中的所有文件。这里定义了小程序的第二个页面,我们暂时不需要。
- 删除 utils 文件夹以及其中的所有文件。 这里定义了一些用途函数,我们暂时不需要。
- 删除 index.js 中的所有代码,这里会定义 index 页面的逻辑。只保留一行 Page({})
- 删除 index.wxml 中的所有代码,这里会定义 index 页面的布局。只保留一行
<view class="title">hello world!</view>
- 删除 index.wxss 中的所有代码,这里会定义 index 页面的样式。只保留
.title { margin-top: 300rpx; text-align: center; }
视图层
何为WXML
WeiXin Markup Language是框架设计的一套标签语言。与HTML的基本功能一样用于构建出页面的结构。其次还能实现数据绑定,列表渲染,条件渲染,模板(可理解为想ReactJs之类js框架中的component),事件。
数据绑定
<!--wxml--> <view> {{message}} </view>
列表渲染
<!--wxml--> <view wx:for="{{array}}"> {{item}} </view>
条件渲染
<!--wxml--> <view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
模板
<!--wxml--> <template name="staffName"> <view> FirstName: {{firstName}}, LastName: {{lastName}} </view> </template> <template is="staffName" data="{{...staffA}}"></template> <template is="staffName" data="{{...staffB}}"></template> <template is="staffName" data="{{...staffC}}"></template>
// page.js Page({ data: { staffA: {firstName: 'Hulk', lastName: 'Hu'}, staffB: {firstName: 'Shang', lastName: 'You'}, staffC: {firstName: 'Gideon', lastName: 'Lin'} } })
事件
<view bindtap="add"> {{count}} </view>
何为WXSS
WeiXin Style Sheets是一套样式语言,用于描述 WXML 的组件样式。
WXSS 具有 CSS 大部分特性。为性能着想,依旧不建议使用内联样式。
与 CSS 相比,WXSS 扩展的特性
1. 尺寸单位rpx:可以根据屏幕宽度进行自适应。
规定屏幕宽为750rpx。如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。同理iPhone6 Plus 1rpx = 0.552px= 1物理像素。
2. 使用
@import语句可以导入外联样式表,@import后跟需要导入的外联样式表的相对路径
3. 支持的选择器:
类、id、元素、和(,)、::after、::before
4. 全局(app.wxss)与局部(对应page文件夹里的.wxss,
注意!会覆盖 app.wxss 中相同的选择器)
实战天气wxapp
效果
配置(因为用到别人写好的模拟天气数据的API作练习,为避免跨域问题)
代码
weather.wxml
<view class='contain'> <button class="location-wrapper" open-type="{{ locationAuthType==1 ? 'openSetting' : ''}}" bindopensetting="onTapLocation" bindtap="onTapLocation" plain="true"> <view class="location"> <image class="location-icon" src="/img/icon/location-icon.png"></image> <view class="location-text">{{city}}</view> </view> <!-- 0: 未弹窗, 1: 已拒绝, 2: 已同意 --> <view wx:if="{{locationAuthType==0}}"class="location-tips">点击获取当前位置</view> <view wx:if="{{locationAuthType==1}}"class="location-tips">点击开启位置权限</view> <view wx:if="{{locationAuthType==2}}"class="location-tips"></view> </button> <view class="title">{{nowTemp}}</view> <view class="weather">{{nowWeather}}</view> <image class='weatherBg' src='{{bgUrl}}'></image> <view class="day-weather" bindtap = "onTapDayWeather"> <view class="day-text">{{todayDate}}</view> <view class="temp-text">{{todayTemp}}</view> <image class="arrow-icon" src="/img/icon/arrow.png"></image> </view> </view> <view class="timeTitle"> <image class="timeTitleIcon" src="/img/icon/time-icon.png"></image> <view class="timeTitleText">未来24小时天气预测</view> </view> <scroll-view class='scrollView' scroll-x style="width: 100%"> <view class='list'> <view class='listItem' wx:key="index" wx:for="{{forecast}}"> <view class= 'item'>{{item.time}}</view> <image class= 'itemImg' src='{{item.img}}'></image> <view class= 'item'>{{item.temp}}</view> </view> </view> </scroll-view>
weather.js
// 初始化常量:中文天气、天气对应的nav颜色 const weatherMap = { 'sunny': '晴天', 'cloudy': '多云', 'overcast': '阴天', 'lightrain': '小雨', 'heavyrain': '大雨', 'snow': '雪' } const weatherColorMap = { 'sunny': '#cbeefd', 'cloudy': '#deeef6', 'overcast': '#c6ced2', 'lightrain': '#bdd5e1', 'heavyrain': '#c5ccd0', 'snow': '#aae1fc' } // 腾讯:通过经纬度得出对应位置的城市 const QQMapWX = require('../../libs/qqmap-wx-jssdk.js') // 未弹窗 const UNPROMPTED = 0 // 无权限 const UNAUTHORIZED = 1 // 已同意 const AUTHORIZED = 2 Page({ data:{ nowTemp: '14°', nowWeather: '阴天', bgUrl:"", forecast:[], todayTemp: "", todayDate: "", city:"广州市", locationAuthType: UNPROMPTED }, onLoad(){ // 实例化API核心类 this.qqmapsdk = new QQMapWX({ key: 'EAXBZ-33R3X-AA64F-7FIPQ-BY27J-5UF5B' }); // 无参调用getNow则无停止刷新时间 wx.getSetting({ success: res => { let auth = res.authSetting['scope.userLocation'] this.setData({ locationAuthType: auth ? AUTHORIZED : (auth === false) ? UNAUTHORIZED : UNPROMPTED }) if (auth) this.getCityAndWeather() else this.getNow() //使用默认城市广州 }, fail: () => { this.getNow() //使用默认城市广州 } }) }, // callback为停止刷新函数参数 getNow(callback) { // 发起网络请求url请求链接、data请求参数 wx.request({ url: 'https://test-miniprogram.com/api/weather/now', data: { city: this.data.city }, success: res => { let result = res.data.result let now = result.now let forecastRes = result.forecast let forecast=[]; let nowHour = new Date().getHours() for (let i = 0; i < 8; i += 1) { forecast.push({ time: (i*3 + nowHour) % 24 +'时', img: '/img/icon/' + forecastRes[i].weather+'-icon.png', temp: forecastRes[i].temp+'°' }) } forecast[0].time = "现在"; this.setToday(result.today); this.setData({ nowTemp: now.temp + '°', nowWeather: weatherMap[now.weather], bgUrl: '/img/' + now.weather + '-bg.png', forecast: forecast }) // 根据weather设置对应头部颜色 wx.setNavigationBarColor({ frontColor: '#000000', backgroundColor: weatherColorMap[now.weather], }) }, // 在完成刷新(无论成功失败)都调用 complete: () => { // &&当callback存在则调用下拉刷新动作的函数 callback && callback() } }) }, // 下拉刷新 onPullDownRefresh: function () { // 下拉刷新是调用getNow方法并返回一个停止下拉刷新动作的函数为参数 this.getNow(() => { wx.stopPullDownRefresh() }) }, setToday(result) { let date = new Date() this.setData({ todayTemp: `${result.minTemp}° - ${result.maxTemp}°`, todayDate: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} 今天` }) }, onTapDayWeather() { // wx.showToast() wx.navigateTo({ url: '/pages/weather/list/list?city='+this.data.city, }) }, onTapLocation() { this.getCityAndWeather() }, getCityAndWeather() { wx.getLocation({ success: res => { //调用接口 this.qqmapsdk.reverseGeocoder({ location: { latitude: res.latitude, longitude: res.longitude }, success: res => { let city = res.result.address_component.city this.setData({ city: city, locationAuthType: AUTHORIZED }) this.getNow() }, fail: () => { console.log("city fail"); } }) }, fail: () => { console.log("locat fail"); this.setData({ locationAuthType: UNAUTHORIZED, }) } }) } })
list.wxml
<view> <view class='date-item' wx:for="{{weekWeather}}"> <view class="date-wrapper"> <view class="day">{{item.day}}</view> <view class="date">{{item.date}}</view> </view> <view class="temp">{{item.temp}}</view> <image class="weather-icon" src="{{item.iconPath}}"></image> </view> </view>
list.js
const dayMap = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'] Page({ date: { weekWeather: [] }, onLoad(options) { this.setData({ city: options.city }) this.getWeekWeather() }, onPullDownRefresh() { this.getWeekWeather(() => { wx.stopPullDownRefresh() }) }, getWeekWeather(callback) { wx.request({ url: 'https://test-miniprogram.com/api/weather/future', data: { time: new Date().getTime(), city: this.data.city }, success: res => { let result = res.data.result this.setWeekWeather(result) }, complete: () => { callback && callback() } }) }, setWeekWeather(result) { let weekWeather = [] for (let i = 0; i < 7; i++) { let date = new Date() date.setDate(date.getDate() + i) weekWeather.push({ day: dayMap[date.getDay()], date: `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`, temp: `${result[i].minTemp}° - ${result[i].maxTemp}°`, iconPath: '/img/icon/' + result[i].weather + '-icon.png' }) } weekWeather[0].day = '今天' this.setData({ weekWeather: weekWeather }) } })
直接编译对应开发页码
涉及的核心知识点
- 生命周期——进入第二页,返回第一页的生命周期顺序理解:
//初始页 onLoad onShow onReady onHide //进入第二页,则第一页隐藏(并没有卸载) onLoad onShow onReady onUnload //返回第一页(第二页卸载,且由于第二页还存在只是隐藏了而已无需再加载和准备页面,所以只调用了onshow
- 调用API(wx.request)
- 异步调用:所有生命周期函数、所有手势响应函数、所有函数类型的参数
- 理解setData中的异步和同步(调用 setData 之后,this.data 的值将会立即改变。然而,小程序的页面(即视图层)需要等待页面再次渲染才能够更新。总结:页面数据无需刷新的重新渲染对应部分为异步,赋值为同步);与React中的status很相似(直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。)
- 下拉刷新(配置开启下拉刷新+且要注意每次下拉刷新后无论成功与否都要使用wx.stopPullDownRefresh())
- 按钮响应(bindTap)
- 页面跳转并能传参(wx.navigateTo)
- 获取位置(通过 wx.getLocation 获取当前经纬度,通过百度api将经纬度转换为城市)
- 条件渲染(wx.if)
实战天气的代码完整下载
我学习微信小程序的整理,不仅仅只有天气! clickHere 》
快捷链接
全部React学习笔记的目录 Click Here>>
全部Javascript学习笔记的目录 Click Here>>
Less学习笔记 Click Here>>
安利一波前端开发推荐使用的工具 Click Here>>
ESLint问题记录 Click Here>>
github各类实战练习源码下载 Click Here>>
如果你觉得我的东西能帮到你,无限欢迎给我的github库点个收藏Star~0v 0~
相关文章推荐
- 微信小程序开发学习笔记008--微信小程序项目02
- 微信小程序开发学习笔记006--微信小程序组件详解02
- 微信小程序学习笔记(1)--------准备工作
- JDBC基础学习笔记_02JDBC编程的mysql数据准备并编写程序
- 微信小程序项目实战之天气预报
- 菜鸟Java学习笔记02--配置JDK环境变量的目的和HelloJava程序
- 微信小程序实战之天气预报
- 微信小程序学习笔记(一)教程收集
- 微信小程序学习笔记——view和Flexbox
- 微信小程序学习(2)_开发准备和开发工具简介
- 【C++ 学习笔记小程序02】 简单函数
- 微信小程序,学习笔记(一)框架,视图层
- 微信小程序实战之天气预报
- 微信小程序学习笔记(六)
- 微信小程序学习笔记1
- (原创)c#学习笔记02--编写c#程序02--控制台应用程序
- 微信小程序学习笔记——第一弹:小程序代码结构
- 地球人己阻止不了程序猿们学习cocos2d-x了-学习笔记02
- 微信小程序学习笔记(十五)switch开关选择器
- 微信小程序学习笔记--20170425--登录验证实现