轻源码

  • QingYuanMa.com
  • 全球最大的互联网技术和资源下载平台
搜索
一起源码网 门户 微信小程序 查看主题

monsterk1:微信小程序上手篇《四》初级实践篇

发布者: winter1998 | 发布时间: 2017-9-11 16:39| 查看数: 3912| 评论数: 1|帖子模式

作者:monsterk1,来自授权地址

微信小程序开发,快捷方便,容易上手,学习成本不高,但是好的程序员必须要经常开发来积攒经验才为上策。在我的微信小程序上手篇中,笔者把微信小程序的demo通读了一遍,可以说收获良多,很多东西只有在自己理解的情况下才能牢牢记住,在文章的最后一篇中笔者也说了,学会了就得举一反三,通过现有的知识做出能力范围内可以实现的东西,这对于开发者来说是最好的实践。因此笔者在这里特别推出一个初级教程,而其中的知识基本上都是在demo中就可以获得的,只要你通读了我之前的文章,我相信你也能开发出一个简单的小程序。

  好了,废话不多说,先上小程序示例的效果图:

  由于demo能学到的有限,笔者暂时能想出来的实例就是类似这样的应用,不过技术都是一步一步增长的,从小做起,然后才能强大。

  前期准备:

  1.准备好图片,百度搜索多的是。

  2.准备好json格式内容,我们的内容是以json形式存储的。

  笔者是一名app开发,本想以json格式文件存储模型,但是一直找不到好的读取项目中本地json的方法,如有所知,能够评论告诉笔者,笔者先在此谢过。

  这里笔者给大家一份自己写的json,仅供参考:

  1. [
  2. {"url":"",
  3. "name":"猪肉",
  4. "price":"32.4"},
  5. {"url":"",
  6. "name":"水果",
  7. "price":"17.5"},
  8. {"url":"",
  9. "name":"蔬菜",
  10. "price":"10.2"},
  11. {"url":"",
  12. "name":"玩具",
  13. "price":"50.1"},
  14. {"url":"",
  15. "name":"电脑",
  16. "price":"4500.2"}
  17. ]

  大家以这样的格式写就好,内容自定。

  做好前期准备,就正式进入敲代码阶段。

  首先创建项目,然后将项目中没有用的东西删除掉:

  1.utils的文件夹删除,此项目用不到;

  2.pages中的logs文件夹删除,此项目用不到;

  3.app.js中删除无用代码,留下一个空白的onLaunch方法和空白的globalData对象,app.json中删除"pages/logs/logs","navigationBarTitleText"改为我们的“小型超市购物”,app.wxss中我们将padding改为50rpx 0;

  4.index的每一个文件都清空;

  我们先从app.js文件着手,此时你的代码应该和我的一样:

  1. App({
  2. onLaunch: function () {
  3. },
  4. globalData:{
  5. }
  6. })

  很空,且让我们慢慢添加。在这里,我希望复习一下之前demo中运用的传值方法,记得demo中有个方法是:

  1. getUserInfo:function(cb)

  很多读者应该都记得,而且对于新手来说这个方法不好用,很难理解,因此我们在这里再复习一遍,自己来使用它(cb这个参数笔者现在才知道全称应该是callback,回传值)。

  我们现在也写一个方法,名为getItem,用来获取我们商品的列表数据:

  1. getItem : function (callback) {
  2. },

  这个方法就是获取我们的商品数据的,在这里,我们仿照demo中的写法,在globalData中设置一个值(有一些读者可能会想的比较明白,可能事后会发现这个值根本用不到,只不过我们是为了模仿demo的写法才用的这个值):

  1. globalData:{
  2. items:null
  3. }

  在这里我们有个空的items,这个就是我们的商品数据,然后我们再模仿getUserInfo中的写法:

  1. if (this.globalData.items) {
  2. typeof callback == "function" && callback(this.globalData.items)
  3. }
  4. else {
  5. this.globalData.items = [
  6. {"url":"",
  7. "name":"猪肉",
  8. "price":"32.4"},
  9. {"url":"",
  10. "name":"水果",
  11. "price":"17.5"},
  12. {"url":"",
  13. "name":"蔬菜",
  14. "price":"10.2"},
  15. {"url":"",
  16. "name":"玩具",
  17. "price":"50.1"},
  18. {"url":"",
  19. "name":"电脑",
  20. "price":"4500.2"}
  21. ]
  22. typeof callback == "function" && callback(this.globalData.items)
  23. }

  因为我们的items此时为空的,所以第一个if我们是走不进去的,然后在else中我们直接设置了items,用我们前期准备的json赋值给它,它就成了一个数组,数组中包含对象。在这之后我们回传这个值给callback的参数,让其能够获取我们的商品数据。

  到这里,我们的app的代码都码好了,很简单,这里的逻辑只是让app公开一个方法回调,拿到我们设置的json(这里又可以举一反三,用请求同理)。接下来我们就要开始处理index文件了。

  在文件中我们输入page,系统自动会给我们拼接上Page({...})代码,回车即可:

  1. Page({
  2. data:{
  3. String1
  4. },
  5. onLoad:function(options){
  6. // 生命周期函数--监听页面加载
  7. String2
  8. },
  9. onReady:function(){
  10. // 生命周期函数--监听页面初次渲染完成
  11. String3
  12. },
  13. onShow:function(){
  14. // 生命周期函数--监听页面显示
  15. String4
  16. },
  17. onHide:function(){
  18. // 生命周期函数--监听页面隐藏
  19. String5
  20. },
  21. onUnload:function(){
  22. // 生命周期函数--监听页面卸载
  23. String6
  24. },
  25. onPullDownRefresh: function() {
  26. // 页面相关事件处理函数--监听用户下拉动作
  27. String7
  28. },
  29. onReachBottom: function() {
  30. // 页面上拉触底事件的处理函数
  31. String8
  32. },
  33. onShareAppMessage: function() {
  34. // 用户点击右上角分享
  35. return {
  36. title: 'title', // 分享标题
  37. desc: 'desc', // 分享描述
  38. path: 'path' // 分享路径
  39. }
  40. }
  41. })

  内容很多,我们将多余代码删除,只留下:

  1. Page({
  2. data:{
  3. String1
  4. },
  5. onLoad:function(options){
  6. // 生命周期函数--监听页面加载
  7. String2
  8. }
  9. })

在这里我们不需要options这个参数(这个参数后面会用到),删除即可。
  现在来说一下逻辑,我们需要在这个首页显示的是一个列表,因此我要拿到数据来展示,而数据在app的实例中我们写了一个方法叫做getItem来获取,为了保存这个数据,我们需要一个变量来存储它,既然如此,我们先在data中设定一个存储用的变量:

  1. data: {
  2. items:[]
  3. },

  为什么是数组?我们的json和getItem返回的本来就是一个数组,所以我们创建一个数组去存储它。

  之后我们就要去获取它,很简单在onLoad方法中,我们去调用app的getItem方法,因此别忘了先获取app实例:

  1. var app = getApp()

  然后在onLoad中调用:

  1. onLoad: function () {
  2. var that = this
  3. app.getItem(function(item){
  4. that.setData({
  5. items:item,
  6. })
  7. })
  8. },

  这个方法很眼熟,跟demo中几乎一样吧。记得getItem的参数我们已经定义为了function,所以在这里我们需要传入一个function,其次既然它符合了function,别忘了我们后面还有回调用的callback(this.globalData.items)方法,所以我们要用一个参数去接收它,我在这里用了item(在实际开发中使用items更好,这里是方便读者区分)。在我们的获取到商品数据的同时,我们使用setData将它传输给我们index中的items变量进行存储,这样我们就可以在wxml中获取我们的数据了。

  来到wxml中,我们需要一个大容器来展示数据:

  1. <view class="container">
  2. </view>

  这个容器是根据container的样式,而container是保存在app.wxss中,如果你不知道具体内容,可以回去看一下。既然有了容器,我们就需要展示。我们的目的是展示一个列表,我之前的文章说了,block是我们将来经常用到的东西,在这里我们正好使用它:

  1. <block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">
  2. </block

  因为我们的items是一个数组,所以我们得需要用for语句去显示它,我们这里的用法与demo中无二,这样我们就能获取到items中每一个数据。其次,我希望每一条数据为一大块,而且需要有一定的间隔如:

  我们首先要用一个view来承载一行一行的格子:

  1. <block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">
  2. <view>
  3. </view>
  4. </block>

当然,这么简单是无法达成我们要的效果的,需要修改样式,在index.wxss中添加一个样式:

  1. .item {
  2. display: flex;
  3. background-color: white;
  4. flex-direction: row;
  5. align-items: flex-start;
  6. margin: 20rpx auto;
  7. padding: 5rpx;
  8. box-sizing: border-box;
  9. border: 1px solid #d0d0d0;
  10. border-radius: 2px;
  11. width: 90%;
  12. }

  这个是我们整个一行的样式,如此一来我们就基本达到我们的效果,然后把样式表加入wxml中的view:

  1. <block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">
  2. <view class="item">
  3. </view>
  4. </block>

这步完成,大的框架已经搭好了,我们现在添加数据。首先添加商品名称,我希望序列号和商品名称显示在左上角:

  1. <block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">
  2. <view class="item">
  3. <text>{{index + 1}}.{{item.name}}</text>
  4. </view>
  5. </block>

然后,我们需要添加我们的商品图片,没有图片顾客怎么浏览商品呢:

  1. <block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">
  2. <view class="item">
  3. <text>{{index + 1}}.{{item.name}}</text>
  4. <image src="{{item.url}}" mode="aspectFit"></image>
  5. </view>
  6. </block>

现在看起来整个显示不够美观,商品名和图片紧贴在一起,图片太大,没事,我们添加样式就行:

  1. .p{
  2. padding-right:10rpx;
  3. }
  4. .image{
  5. box-sizing: border-box;
  6. border: 1px solid #d0d0d0;
  7. width: 100px;
  8. height: 80px;
  9. background-color: 'white';
  10. }

  然后将样式加入:

  1. <block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">
  2. <view class="item">
  3. <text class='p'>{{index + 1}}.{{item.name}}</text>
  4. <image class='image' src="{{item.url}}" mode="aspectFit"></image>
  5. </view>
  6. </block>

好了,看上去美观多了是不是?最后我们把价格添加:

  1. <block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">
  2. <view class="item">
  3. <text class='p'>{{index + 1}}.{{item.name}}</text>
  4. <image class='image' src="{{item.url}}" mode="aspectFit"></image>
  5. <text>{{item.price}} 元</text>
  6. </view>
  7. </block>

 这样子整体效果还不是特别好,我们继续添加样式:

  1. .price{
  2. line-height: 80px;
  3. width: 50%;
  4. text-align: center;
  5. }

  加入样式:

  1. <block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">
  2. <view class="item">
  3. <text class='p'>{{index + 1}}.{{item.name}}</text>
  4. <image class='image' src="{{item.url}}" mode="aspectFit"></image>
  5. <text class='price'>{{item.price}} 元</text>
  6. </view>
  7. </block>

差不多了,我们的长相看的过去了,现在我的需求变成了点击每一行进去可以看详情,所以我们得新建一个页面来显示详情,添加item的文件,.js .wxss .wxml创建好。

  记得需要在app.json中配置我们的新页面,不然无法显示和添加页面:

  1. "pages":[
  2. "pages/index/index",
  3. "pages/item/item"
  4. ],

  我们等等处理item文件,我们先来添加点击处理,来到index.js中,我们添加一个点击方法:

  1. itemTap: function (event){
  2. }

我现在的需求是点击哪一行,哪一行的内容就要传到第二个页面,这样该如何实现呢?这个方法在demo中并没有体现,但是官方文档中有说明,在这里你们可以直接看我代码,在index.wxml中添加itemTap:

  1. <block wx:for="{{items}}" wx:for-item ="item" wx:key ="*this">
  2. <view bindtap="itemTap" data-item="{{item}}" class="item">
  3. <text class='p'>{{index + 1}}.{{item.name}}</text>
  4. <image class='image' src="{{item.url}}" mode="aspectFit"></image>
  5. <text class='price'>{{item.price}} 元</text>
  6. </view>
  7. </block>

  为了获取我们点击到的数据,我们需要用到data-这个语句,这个语句data-之后是我们自定义的key,然后=之后是我们的value,这样我们就可以在js中以key-value的形式获取我们的数据,我们在这里传过去的是一个对象。

  在index.js中我们修改点击事件的代码:

  1. itemTap: function (event){
  2. var item = event.currentTarget.dataset.item
  3. wx.navigateTo({
  4. url: '../item/item?name=' + item.name + '&url=' + item.url + '&price=' + item.price,
  5. })
  6. }

  event这个参数有哪些变量,我怎么知道里面有currentTarget这个变量?这里有个小技巧,先console.log(event),运行一遍,然后在调试中看console信息,你就能知道event里面包含哪些变量。总之我们拿到了我们的数据,之后我们跳转到新的页面。在这里我们看到与demo中不同的代码?name='+之后的代码,在这里笔者走了很多弯路,本来想要正向传值,但是系统又拿不到item的实例,后来我通过搜索别人大神和官方文档,我才知道微信小程序传值是以类似get方法的url拼接传值,真是有点意想不到。

  这里传值在哪里接收呢,哈哈,这就要用到我们之前删除的options参数(往上拉,你会看到我说的参数)。

  来到item.js,创建Page({...})代码:

  1. Page({
  2. data:{
  3. String1
  4. },
  5. onLoad:function(options){
  6. // 生命周期函数--监听页面加载
  7. String2
  8. }
  9. })

  看到了么,options参数,这里就能接收之前页面传过来的内容,它本身就是一个对象,因此我们直接创建一个对象去接收它:

  1. Page({
  2. data: {
  3. item:{}
  4. },
  5. onLoad: function (options) {
  6. this.setData({
  7. item:options,
  8. })
  9. }
  10. })

 这样我们就获取了商品数据,然后我希望标题也能够变成商品的名字,虽然demo中没有用到这个方法,不过很幸运,系统正好给了这样一个接口:

  1. wx.setNavigationBarTitle({
  2. title: options.name,
  3. })

  哈哈,简单,我们已经处理好所有的逻辑了,现在就来展示吧,item.wxml中:

  1. <view class="container item">
  2. <image class="image" src="{{item.url}}" mode="aspectFit"></image>
  3. <text class="title">{{item.name}}</text>
  4. <text class="price">{{item.price}} 元</text>
  5. </view>

  item.wxss中:

  1. .item {
  2. align-items: center;
  3. box-sizing: border-box;
  4. border: 1px solid lightgrey;
  5. border-radius: 5px;
  6. margin: 0rpx 10rpx;
  7. padding: 100rpx 0rpx 10rpx 10rpx;
  8. background-color: lightcyan;
  9. }
  10. .image {
  11. width: 100%;
  12. }
  13. .title {
  14. border-bottom: 1px solid lightgray;
  15. width: 80%;
  16. line-height: 100px;
  17. text-align: center;
  18. }
  19. .price {
  20. line-height: 80px;
  21. text-align: right;
  22. width: 80%;
  23. font-family: "YouYuan";
  24. font-size: 30px;
  25. font-weight: bold;
  26. font-style:oblique;
  27. }

  在这里关于wxml中的代码和wxss中的代码我就不多加阐述,因为我希望读者你自己去显示,用不同的方法来显示内容,在这里笔者感谢公司前端二胡同志友情帮助我编写部分css代码,毕竟笔者css还是个雏~


最新评论

风起云涌 发表于 2022-4-27 23:05
《源代码》微盘

浏览过的版块

轻源码让程序更轻更快

QingYuanMa.com

工作时间 周一至周六 8:00-17:30

侵权处理

客服QQ点击咨询

关注抖音号

定期抽VIP

Copyright © 2016-2021 https://www.171739.xyz/ 滇ICP备13200218号

快速回复 返回顶部 返回列表