小程序一篇搞定

day1 :

1, 申请账号 ,找到appid

2, 下载工具

3, 创建git ,使用git仓库来使用tag来管理项目 

// 关联项目到自己的仓库 
git remote add origin https://github.com/a654688383/learnMiNiProgramer.git

// 上传项目
git push -u origin master

// 修改项目 打tag提交
git add .
git status
git commit -m "testTag1"
git tag testtag1

// 查看日志  切换tag
git tag
git checkout testtag1

// 提交 tag到远程 
git push --tags

// 切换到某个tag ,注意这个时候 处于 tag所在的快照分支 ,非master ,提交代码 需要切换到mastergit checkout testtag1

// 回滚到某个版本 回退到某个版本  取hash的某一段
git log
git reset --hard hashvalue

4,删掉项目 ,搞清app和pages 都是干嘛的, 搞清 json,js,wxss,wxml都是干嘛的, 然后根据报错从头创建一遍,有快捷键。

*******************************************

day2 

1,  project.config.json / sitemap.json / app.json / app.js  / app.wxss / page.json 都是干嘛的

1,project.config.json // 项目的 配置文件
2, sitemap.json // 小程序搜索相关的可配置
3, app.json //  全局的配置 
4, app.js  // 全局的生命周期相关
5,app.wxss  //  全局的样式配置 
5.  page.json // 局部页面设置

2,  mvvm 

// mvvm  m:model     v: view   vm :viewModel


viewModel 干了两件事:
 a: domListeners  监听dom  
 b: data bindings  绑定数据,根据数据改变dom

*********************************
1,  react 和 vue的 mvvm  

view // DOM 

model // js obj

mvvm  // react vue

2, 小程序的 mvvm

view // DOM 

model // APP service 逻辑层

mvvm  // Mina框架  小程序框架

3,小程序的双线程模型

宿主环境为了执行小程序的各种文件 ,提供了双线程模型:

1. 渲染层   WXML WXSS 运行于渲染层,以页面为单位分为多个线程

2. 逻辑层   js脚本使用jsCore运行于逻辑层


这两种线程 经由 微信客户端进行中转交互

*******************************************

day3

1,了解小程序的生命周期

// 小程序的生命周期 
1,下载小程序包
2,启动小程序
3,加载app.json
4, 注册app(),执行生命周期函数
5,加载自定义组件,注册自定义组件 
6. 加载解析 page.json
7, 渲染层加载page.WXML, 逻辑层注册page();
8,执行page的生命周期;

*****************
App({

  /**
   * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
   * 一般获取用户信息 
   * 
   */
  onLaunch: function () {
    wx.getUserInfo({
      success:(e)=>{
        console.log(e.userInfo)
      }
    })
   // setTimeout(()=>{throw new Error()},1000)

  },

  /**
   * 当小程序启动,或从后台进入前台显示,会触发 onShow
   * 小程序在后台的存活时间,一般为两个小时
   * * 判断小程序进入场景
   * 通过用户信息来发请求给服务器
   
   */
  onShow: function (options) {
    console.log(options.scene)
    
  },

  /**
   * 当小程序从前台进入后台,会触发 onHide
   */
  onHide: function () {
    
  },

  /**
   * 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
   */
  onError: function (msg) {
    console.log('error',msg)
  },
  /**
   * 
   * 当小程序页面找不到的时候
  */
  onPageNotFound:function(){

  }
})


2, 了解获取用户信息的三种方式

1, wx.getUserInfo 即将废弃
 wx.getUserInfo({
      success:(e)=>{
        console.log(e.userInfo)
      }
    })


2. button   官方推荐 需要用户点击

<button 
open-type="getUserInfo"
bindgetuserinfo="getUserInfoHandle"
>按钮</button>

 getUserInfoHandle:function(e){
    console.log(e.detail.userInfo)
  },




3.  open-data标签 只做展示
<open-data type='userNickName'></open-data>

3 ,了解getApp() 获取全局实例

1, 在app中定义
globalData:{
    name:'xiaoming',
    age:'111'
  }


2. 在page.js中操作

const app = getApp();
let {name,age} = app.globalData;
console.log(name, age)

// pages/home/home.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    name: name, 
    age:age
  },
)}

3, 在html中使用变量
<view>{{name}}</view>
<view>{{age}}</view>

4 ,了解request请求

1, 使用wx.request({}) 
  一般入参对象有几个属性参数, url, success ,error ....,
2, 如果没有配置域名,那么会发不出去请求,调试的时候可以设置不校验域名
3, 尽量所以的回调函数 使用箭头函数

5,常用属性

1,id
2,class
3,style
4,hidden
5,data-*
6,bind/catch

day4

1, 了解rpx

1, 这个单位是以750px(iphone6 375 *2) 屏幕为标准模版。其他屏幕自适应。

2, 放手机上,一般就是 1px = 2rpx; 比如 iphone6 下满屏 375px 就写 750rpx;

3, 所以调试样式的时候就在iphone6上去调试就好了

2,了解样式引入复用, 还有官方的ui库还有使用;

3, 了解wxs

wxs的特性
1, 写起来差不多跟js一样,只能使用es5以下的语法
2,不能够作为事件的回调函数, 不能够能拿到其他模块的变量方法,只能作为局部存在
3,在ios中wxs比js块 2到20倍,在安卓无差异


个人觉得可以作为工具函数来使用

写法有两种 :

1, 自建wxs 
 //  utils.wxs
function process(a,b){
   return a + b;
}
var price = '20';


module.exports ={
  process:process,
  price: price
}

//在wxml中使用
<wxs src='../../utils/utils.wxs' module='info'/>
<view>{{info.process(10,20)}}</view>
<view>{{info.price}}</view>



2.局部块wxs
<wxs module='info'>
function process(a,b){
   return a + b;
}
var price = '20';

module.exports ={
  process:process,
  price: price
}
</wxs>

<view>{{info.process(10,20)}}</view>
<view>{{info.price}}</view>






4,了解template 语法

template

1, 模版语法在以前没有组建的情况下,主要是提供了 html的复用

2, 可以配合 import使用,但是无法递归引用模版

3, 可以使用变量,data属性传入

4, 必须有name属性, 也是其唯一标识,使用的话是is属性





使用起来有两种方式
1, 自建template 文件夹

// template.wxml
<template name='info'>
  <view>{{name}}</view> 
  <view>{{age}}</view> 
</template>

// 在wxml中使用
<import src='../../template/template.wxml'   />
<template is='info' data="{{name:'xiaoming',age:18}}" />

2, 使用局部模块 template

<template name='info'>
  <view>{{name}}</view> 
  <view>{{age}}</view> 
</template>


<template is='info' data="{{name:'xiaoming',age:18}}" />

**********************
import
import可以引用 template

include

可以引入 除了template,wxs的文件, 算是复制, 可以递归导入wxml

day5:

1,组件都都有自己的特殊事件类型

input 有bindinput/bindblur/bindfocus

scroll-view 有 bindscrolltowpper/bindscrolltolower

2, 所以组件共有的事件

1,touchstart   // 手指触摸开始


2, touchmove  // 手指触摸并且移动

3,touchcancel   // 来电弹窗打断触摸操作,不常用


4,touchend  // 手指触摸结束


5,tap  // 手指点击


6,longpress  // 手指点击超过了350ms以上,和tap只会生效其中一个


7,longtap  // 手指点击超过了350ms以上,推荐使用longpress替代

3,绑定事件的形式 以及写法

形式有两种:
1, bind  冒泡  事件从目标向外冒泡
2, catch  捕获 事件从外往内捕获传递

bind 的写法:
1 , bindtap='xxx'
2, bind:tap='xxx'

4, 事件对象 event

1, type   事件类型
2, timeStamp  页面打开到触发事件经过的毫秒数


3, target  触发事件的组件的一些集合属性


4, currentTarget 当前触发事件的组件的一些集合属性


5, detail  额外的信息, 一般的data-xx 会传递进来


6, touches   触摸事件的触摸点的信息数组 


7, changedTouches  触摸事件,当前变化的触摸点的信息数组 

 

5,传递数据  data-* 

小程序向组件传递数据是data-*,然后在事件的event.currentTarget.dataset中就可以拿到*了,

<view 
bindtap="handleClick"
data-index="11"
 >111</view>

handleClick:(event)=>{
    console.log(event.currentTarget.dataset)
  }


day 6:

1,小程序组件基本

小程序组件由四部分组成

json js wxml  wxss

需要放到component文件夹下

****************

使用 


1, 建立组件 

2 , 在 需要引用的页面引入组件

{
  "usingComponents": {
    "test":"../../../component/test/test"
  }
}
3, 在页面使用组件
<test>
</test>
<test/>

4 hidden show 对自定义组件无效,需要用v-if

2,组建的注意事项

1, wxml的节点标签名字,只能是字母,中划线和下划线组成的组合,数字偶尔也可以

2,自定义组件可以引用其他的自定义组件

3,不要以 wx 作为前缀  微信

4,如果是全局组件,那么在 app.json里注册 就可以全局复用了

3, 自定义组件的样式 细节

1, 为了不造成 样式之间的混淆, 官方推荐使用class 不推荐使用id,属性,标签选择器。

4,组件页面 通信

 页面对组件之间传递  :
1,数据 properties

在组件属性定义好外部传入的值得相关项
   properties: {
  //  name: String,    // 此写法没有默认值
    name:{
      type:String,
      value:'defaultName',
      observer:function(newValuye, oldValue){  // 新值替换老值
        console.log(newValuye, oldValue);
      }
    }
  },


在页面内使用
<test name='1'/>
<test name='2'/>
<test name='3'/>
在组件内部使用值

<!--component/test/test.wxml-->
<view  >{{name}}</view>

2,样式

在组件中定义能传过来的样式
externalClasses:['props-class'], // 从父组件传递到组件样式值的变量,注意 驼峰不认识, 主流中划线

在组件中使用该样式 
<!--component/test/test.wxml-->
<view  class="props-class">{{name}}</view>

在页面中使用
<test name='1' props-class="red"/>
<test name='2' props-class="blue"/>
<test name='3' props-class="green"/>

在样式中定义
.red{
  color:red;
}
.blue{
  color:blue;
}
.green{
  color:green;
}



3,标签插槽, slot  

分为两类插槽,一类是 单个插槽, 另外一类是 多个插槽 

#单个插槽

 第一步预留插槽
<!--component/test/test.wxml-->
<view >header</view>
<slot/>
<view >footer</view>

 第二步 使用组件和插槽
 <test >
<view>woshichacao</view>
</test>

#多个插槽
 第一步 ,在组件中先开启新属性 
options:{
   multipleSlots:true
 },

第二步, 给slot们起个name属性
<view >header</view>
  <slot name='slot1'/>
  <slot name='slot2'/>
  <slot name='slot3'/>
<view >footer</view>

第三部 在页面使用slots ,主要是 slot属性, 顺序 无所谓
<test >
  <view slot='slot1'>111</view>
  <view slot='slot2'>111</view>
  <view slot='slot3'>111</view>
</test>


**************


 组件对页面之间传递  :
 自定义事件   

组件的事件要写到method属性中 

第一步,声明组件要发射的方法
click(){
     this.triggerEvent('click',{params:1},{}); //核心方法: 第一个参数是事件名字,第二个参数是数据,第三个参数是其他选项,
    }

第二步  组件中使用这个方法

<button size="mini" bindtap="click">+1</button>

第三步 在页面绑定这个方法 

<view>{{count}}</view>
<test bind:click='add'/>

第四部 在页面中注册这个对应绑定的方法
 data: {
   count:0
  },

 add(obj){
    console.log(obj.detail) // 传递过来的参数
    this.setData({
      count:  ++this.data.count
      })
  }

、、、、、、、、、、、、、、、
通过页面来改变组件内部的数据 (不传值直接操作实例)
  第一步,组件内定义变量并且在组件内使用

  /**
   * 组件的初始数据
   */
  data: {
    name:'李刚'
  },
<view >{{name}}</view>

第二步, 在页面使用组件
<view bindtap="changeName">clickme</view>
<test id='name' />

第三步, 直接改变组件内部的值
  changeName(){
    const ele = this.selectComponent('#name');
    ele.setData({name:'王健林'});
  }

最后 应该是规范一下吧这个改变接口的方法在内部暴露出去  然后外部统一调用修改;
 一,在组件内自定义函数
 /**
   * 组件的方法列表
   */
  methods: {
    changeName(params){
      this.setData({name:params});
    }
  }
二, 在页面调用组件实例的方法


const ele = this.selectComponent('#name');
    ele.changeName('王健林');







5,组件的构造器component 对象

1. properties
2. data
3. methods
4. externalClasses
5. options
6. observers:{ // 监听properties ,data属性的变化;
    name(newvalue){  // 只有新值 ,没有老值
      console.log(newvalue)
    }
  }

7. 组件中的生命周期函数 ,一类是本组件的生命周期 ,另外一类是可以监听所在页面的生命周期
 lifetimes: { // 本组件的生命周期 
    created(){}, // 创建
    attached(){}, // 组件被添加到页面中
    ready(){}, // 被渲染出来
    movied(){}, // 位置移动
    detached(){} // 移除掉
  },
  pageLifeTimes: {  // 可以监听所在页面的生命周期
    show(){},
    hide(){},
    resize(){},
  }

day7:

1,网络请求 wx.request

 注意: 没有指定域名,又希望调试 ,就到详情---本地设置---勾选不校验域名即可

 wx.request方法使用对象需要包含很多个参数:
1,url
2,data
3, header 头部信息
4, method
5, dataType 告诉服务器,我要想什么格式的数据  一般是json ,或者string
6, responseTyoe 你告诉服务器,让服务器返回什么样的数据类型给你 ,一般是文本 可以是流 图片
7, success  
8, fail
9, complete 结束的函数,相当于finaly

2,封装该请求

export default function request(options){
  return new Promise( (resolve,reject)=>{
    wx.request({
      ...options,
      url: options.url || '',
      data: options.data || {},
      method: options.method || 'get',
      success: resolve, // resolve,reject 也是一个带参函数
      fail: reject,
    })
  })
}

在页面使用 

  /**
   * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
   * 一般获取用户信息 
   * 
   */
  onLaunch: function () {
    request({
      url:'http://123.207.32.32:8000/recommend'
    }).then((res)=>{
      console.log(res)
    })
  },

day8 

1, 展示系统弹窗

一共分为四类 

1, toast
  wx.showToast({  // 其他的看参数就好 
      title: 'iii', // 标题
      icon:'' , // 可以使用 自定义本项目内的如片 默认是对勾  
    })

2, modal  展示一个弹窗  取消确定  

  wx.showModal({  // 其他的看参数就好 
      title: 'iii', // 标题
      content:'ppppp',
      
    })

3, loading
  wx.showLoading({  // 其他的看参数就好 
      title: '111', // 标题
      mask:true, // 蒙版
    })
setTimeout(()=>{wx.hideLoading()},2000)

4, actionsheet  //下拉 选项

 wx.showActionSheet({
      itemList: ['111','222'],
    })

2,使用分享 

小程序只能分享给好友,不能分享到朋友圈,最多分享二维码到朋友圈

在页面内实现这个函数就可以实现分享功能

  onShareAppMessage:function(options){  // 实现这个函数就可以定制分享了
    return {
      title:'爆款',
      path:'', // 以/为开头的完整路径 默认是首页
      imageUrl:'https://s10.mogucdn.com/mlcdn/c45406/180917_18l981g6clk33fbl3833ja357aaa0_750x390.jpg', // 没有就是当前网页的快照 
    }
  }


如果说希望点击某个地方也出现分享,并不只是右上角的分享 ,那么需要这么干


<button sizi='mini' open-type="share">分享</button>

day 9  登录 

1,  登录流程 

前端 :

1, wx.login 得到code ,有效期五分钟

2,发送code 和标识 到后台 ,服务器返回一个 登录状态 ,比如token

3,讲token存储在小程序

4,请求需要登录态标识的token时, 携带token


后端 :

1, 凭借 appid + code + appsecret 换回 seesion_key + openid , 

2, 自定义登录状态与 session_key,openid关联,返回前端token

3, checkcode 这步就通过token 检查 session_,openid

2, 实现登录 

1,登录函数  登录 拿到 token ,前端存储在storage, app内存存储各一份 


2, 优化请求,检查存储token当前结果 ,

(1),没有直接去发请求
(2),有的话检查状态  一 过期直接去发请求,  二,没有过期给 当前 app内存存储一份

 

day10

1, 页面跳转 - navigator 组件 

navigator 组件的四个属性 

1, target   在哪个目标发生跳转 ,默认当前小程序 

2, url  当前小程序内部跳转链接  

3, open-type  跳转方式  

3, detal  当 open-type  是 navigateBack的时候 ,返回的层数 



 open-type 的 6种类型:

1, navgate 普通跳转  
2,  redirect 替换当前页面跳转
3, switchTab  跳转到对应的tabbar页面,并且关闭所有的非tab页面
4, relaunch 关闭所有页面 ,打开这一个页面
5, navigateback 返回 页面
6, exit 退出小程序 target = 'minProgram'时生效


使用 


<navigator url='/pages/about/about'>about</navigator>

2 , 页面跳转 - wx.api 跳转 

点击按钮 然后跳转

<button size="mini" bindtap="gotoabout">gotoabout</button>

 gotoabout(){
    wx.navigateTo({
      url: '/pages/about/about?name="111"',
    })
  }


 所有 的 navifator的 opentype 都有对应的api

3, 跳转过程中 数据的传递 

1, 父级页面向子级页面传递 

父级页面
<navigator url='/pages/about/about?name="111"'>about</navigator>

子级页面
  onLoad: function (options) {
    console.log(options)
  },


2, 子级页面向父级页面传递 

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    //getCurrentPages 返回一个浏览历史栈
    // 这个位置就可以拿到
    const pages = getCurrentPages();
    const home = pages[pages.length-2];  // 我觉得可遍历去拿个更稳定的值;
    console.log(pages)
    // 拿到页面实例操作页面数据, 其实可以优化到 页面内部方法去做这个事情
    home.setData({name:'王健林'});

  },

4,上拉加载更多

// 数据模型
 titles:["流行","新款","精选"],
    currentItem:'new',
    goods:{
      pop: { page: 0, list: [] },
      new :{page:0,list:[]},
      sell: { page: 0, list: [] },
    }

// 请求方法
getGoods(type){
    let page = this.data.goods[type].page+1;
    fetchGoods({type,page}).then((res)=>{
      console.log(res)
      // case 1
      // let listString = `goods.${type}.list`;
      // let pageString = `goods.${type}.page`;
      // this.setData({
      //   good:{
      //     ...this.data.goods,
      //     [type]:{
      //       list: [...this.data.goods[type].list, { aaa: 1 }],
      //       page:page
      //     }
      //   }
      // })
    
      // case 2 
      this.data.goods[type].list = [...this.data.goods[type].list,res.data];
      this.data.goods[type].page= page;
      this.setData({
        goods: { ...this.data.goods}
      });
    })
  },

// 触发上拉加载更多
  onReachBottom(){
    this.getGoods(this.data.currentItem)
  }

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值