小結:
1 如何自定義組件
- 組件和頁面一樣,也是由四個文件組成,所以我們自定義組件的時候,模擬pages文件夾,把所有的所有的組件都放在一個文件夾中,每個組件又由一個文件夾包裹,方便管理,在對應目錄右擊,選擇新建組件
- 如果頁面中要使用我們定義好的組件,必須現在對應頁面的json文件中進行引用:代碼如下
{
"usingComponents": {
"com" : "/componentes/com/com" //形式 :組件名:組件路徑
}
}
在該頁面的wxml文件中,就可以直接使用:
<com name = "{{name1}}" bind:jia1 ="jia"></com>
-頁面向組件傳值:要先在組件的js文件中的properties定義屬性,在頁面中就可以對這個組件的屬性進行賦值了。
-組件向頁面傳遞事件:組件要先捕獲事件,然后事件的響應函數里面用triggerEvent來把事件拋出來,然后頁面捕獲,組件拋出的事件。
2 小程序路由跳轉js版
- wx.switchTab 只能跳轉到tabbar頁面 ,並關閉所有非tabbar頁面,而且路由不能傳值
- wx.reLaunch 關閉所有的頁面,並打開你要跳轉的頁面.路由是可以攜帶參數
- wx.redirectTO 關閉當前的頁面,跳轉到應用內的某個頁面,但是不能跳轉到tabbar頁面,路由可以攜帶參數
- wx.navigateTo 保留當前的頁面,跳轉到應用內的某個頁面,但是不能跳轉到tabbar頁面,路由也可以攜帶參數。如果使用他,就會出現回退按鈕,並且也可以用wx.navigateBack來進行返回
- wx.navigateBack 里面有delta參數,他是用來表示回退多少個頁面。
3 wx.request 相當於發送ajax請求
wx.request({
url: //請求路徑
data:{} //請求發送的數據
header:{} //請求頭
methond: "" //請求方法
success(res){
console.log(res.data)
}
})
小程序的登錄流程圖

openid與unionid
openid:是用單個微信應用表示用戶的唯一標識。亞洲:餅哥小程序上openid :123,那該用戶再張成的小程序上他的opendid不是123,是其他任意一個值,上面的意思:同一用戶再不用不同應用上的openid不同,但是再同一應用上唯一。
場景: 假設你們公司有2個小程序。但是你們老板想把用戶做統一處理。比如新用戶登入任意一個小程序,就發送發送禮包。但是只要再一個小程序上另過了,就不能再另一個上面領取。
unionnid:一個用戶在多個小程序有唯一的標識
小程序的登入
1 小程序端執行wx.login()獲取code
2 將1中的code發送到后端,后端調用auth.code2Session這個接口,得到openid和session_key
3 自定義登入狀態,我們生成一個key與openid和session_key相綁定。把key返回到小程序中
4 小程序端保存,然后下次請求需要登入的接口的時候,把key帶上。
小程序連入django,小程序的app.js
//app.js
App({
/*
當小程序初始話完成,會觸發onlaunch(全局只觸發一次)
*/
onLaunch: function () {
let that = this
// 登錄
wx.login({
success: res => {
// 發送 res.code 到后台換取 openId, sessionKey, unionId
console.log(res.code)
wx.request({
url: that.globalData.baseurl + "login/",
data: { "code": res.code },
method: "POST",
success(e) {
wx.setStorageSync('token', e.data.data.token)
}
})
}
})
/**可以在全局使用 */
globalData: {
userInfo: null,
baseurl: "http://127.0.0.1:8000/"
}
})
django的settings
#設置django—redis緩存 需要你下載插件pip install django-redis
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379',
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"PASSWORD": "Admin123",
},
},
}
# 配置數據庫
import pymysql
pymysql.install_as_MySQLdb()
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'wxxcx',
'USER':'root',
'PASSWORD':'123456',
'HOST':'127.0.0.1',
'PORT': 3306,
#'OPTIONS': {'charset': 'utf8mb4'},
}
}
urls主路由
from django.conf.urls import url
from django.contrib import admin
from app01.views import test, user
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'test/', test.Test.as_view()),
url(r'login/', user.Login.as_view())
]
自定義有關小程序的settings
AppId="xxxx" # 寫你自己的小程序的id
AppSecret="xxxx" # 寫你自己的小程序的秘鑰
code2Session="https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code"
自定義獲取小程序的登錄wx_login
from app01.wx import settings
import requests
def get_login_info(code):
code_url = settings.code2Session.format(settings.AppId, settings.AppSecret, code)
response = requests.get(code_url)
json_response = response.json() # 把它變成json的字典
if json_response.get("session_key"):
return json_response
else:
return False
得到openid以及加密並返回小程序token
from rest_framework.views import APIView
from rest_framework.response import Response
from app01.wx import wx_login
from django.core.cache import cache
import hashlib, time
from app01.models import Wxuser
class Login(APIView):
def post(self, request):
param = request.data
if not param.get('code'):
return Response({'status':1, "msg":"缺少參數"})
else:
code = param.get('code')
user_data = wx_login.get_login_info(code)
if user_data:
val = user_data['session_key'] + "&" + user_data['openid']
md5 = hashlib.md5()
md5.update(str(time.clock()).encode('utf-8'))
md5.update(user_data['session_key'].encode('utf-8'))
key = md5.hexdigest()
cache.set(key, val)
has_user = Wxuser.objects.filter(openid=user_data['openid']).first()
if not has_user:
Wxuser.objects.create(openid=user_data['openid'])
Wxuser.objects.update()
return Response({
'status': 0,
'msg': 'ok',
'data': {'token':key}
})
else:
return Response({'status':2, 'msg': "無效的code"})
models.py
from django.db import models
# Create your models here.
class Wxuser(models.Model):
id = models.AutoField(primary_key=True)
openid=models.CharField(max_length=255)
name = models.CharField(max_length=50)
avatar = models.CharField(max_length=200)
language = models.CharField(max_length=50)
province = models.CharField(max_length=50)
city = models.CharField(max_length=50)
country = models.CharField(max_length=50)
#gender = models.CharField(max_length=50)
creat_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
def __str__(self):
return self.openid
小程序授權
1 因為部分功能需要用同意后才能使用。
2 wx.getSetting來判斷該用戶有沒有對接口授權,我判斷哪個接口,就必須給wx.getSetting傳對應的scope值
- 一個scope值對應這個一個或多個接口
3 如果我們重wx.getSetting中發現scope值是false,標識沒有授權,我們可以通過wx.authorize發起授權,對那個接口授權,就給wx.authorize傳對應scope值就可以了。如果用用戶同意授權,就可以直接使用對應的接口了。
4 但是scope.userInfo沒有辦法使用wx.authorize自動彈起彈框。必須要用戶手動點擊按鈕喚起授權彈框。
代碼格式:
<button open-type="getUserInfo" bindgetuserinfo="user1">用戶信息</button>
我們可以再響應函數的參數中獲取用戶信息。e.detail,這個和直接調用wx.getUserInfo獲取的內容一樣。
scope 列表
小程序的頁面的js文件
// pages/test3/test3.js
Page({
/**
* 頁面的初始數據
*/
data: {
},
click:function() {
wx.navigateBack({
delta:2
})
},
luyin:function(){
wx.getSetting({
success(res) {
if (!res.authSetting['scope.record']) { //錄音的scope
wx.authorize({
scope: 'scope.record',
success() {
// 用戶已經同意小程序使用錄音功能,后續調用 wx.startRecord 接口不會彈窗詢問
wx.startRecord()
},fail(){
console.log('你沒有授權')
}
})
}else{
wx.startRecord()
}
}
})
},
user:function(){
wx.getSetting({
success(res) {
if (!res.authSetting['scope.userInfo']) {
wx.authorize({
scope: 'scope.userInfo',
success() {
console.log('進來了')
}
})
} else {
console.log('已經授權')
}
}
})
},
user1:function(e){
console.log("e",e.detail)
wx.getSetting({
success(res) {
if (res.authSetting['scope.userInfo']) { //用戶信息的scope
wx.getUserInfo({
success: (res) =>{
console.log("res", res)
}
})
}
}
})
},
})
小程序頁面的wxml文件
<!--pages/test3/test3.wxml-->
<text>pages/test3/test3.wxml</text>
<button bindtap="click">tiao</button>
<button bindtap="luyin">錄音</button>
<button open-type="getUserInfo"
bindgetuserinfo="user1">用戶信息</button>
<!--要想要將用戶的信息授權時彈框,必須用一個button按鈕,且open-type必須為getUserInfo以及給事件為bindgetuserinfo-->