您的位置:首页 > 移动开发 > 微信开发

uniapp 微信小程序

2021-12-29 17:46 1681 查看

官网:

  1. uniapp文档
  2. 微信小程序文档
  3. vue2文档
  4. vue3文档

单位

单位 描述
rpx
小程序中使用,
750rpx
= 屏幕宽度
vw/vh
h5的单位,
100vw
= 屏幕宽度,
100vh
= 屏幕的高度

图像

官网: image

image的mode一般有: | mode | 描述 | | -- | -- | heightFix | 高度不变,宽度自动变化,保持原图宽高比不变 widthFix | 宽度不变,高度自动变化,保持原图宽高比不变 aspectFit | 保持纵横比缩放图,可以完整地将图片显示出来。 aspectFill | 保持纵横比缩放图片,只保证图片的短边能完全显示出来

导航

绑定触底事件

即, 下拉到底部时, 触发自定义的事件, 动态获取数据.

  1. 页面部分滚动

    <scroll-view
    @scrolltolower="handleToLower"
    scroll-y
    class="view"
    >
    </scroll-view>
    
    <style lang="scss" scoped>
    .view {
    // 计算滚动区域
    height: calc(100vh - 36px);
    }
    </style>

    假如

    scroll-view
    的display为flex时, 需要添加
    enable-flex
    属性

  2. 页面全部滚动

    <script>
    export default {
    onReachBottom(){
    // ... 执行
    }
    };
    </script>

轮播图

一般需要指定三个属性

  1. autoplay
    自动播放
  2. indicator-dots
    指示器
  3. circular
    衔接轮播
<swiper autoplay indicator-dots circular>
<swiper-item v-for="item in banner" :key="item.id">
<image :src="item.thumb"></image>
</swiper-item>
</swiper>

注:

swiper-item
的高度和宽度都为
100%
,

分段器

即tab

<template>
<view>
<view class="home_tab">
<view class="home_tab_title">
<view class="title_inner">
<uni-segmented-control
:current="current"
:values="items.map((item) => item.title)"
@clickItem="onClickItem"
styleType="text"
activeColor="#dd3915"
></uni-segmented-control>
</view>
</view>
<view class="home_tab_content">
<view v-if="current === 0"><home-recommend></home-recommend></view>
<view v-if="current === 1"><home-category></home-category></view>
<view v-if="current === 2"><home-new></home-new></view>
<view v-if="current === 3"><home-album></home-album></view>
</view>
</view>
</view>
</template>

<script>
import { homeAlbum } from "./home-album";
import { homeCategory } from "./home-category";
import { homeNew } from "./home-new";
import { homeRecommend } from "./home-recommend";
// 分段器
import { uniSegmentedControl } from "@dcloudio/uni-ui";

export default {
components: {
homeAlbum,
homeCategory,
homeNew,
homeRecommend,
uniSegmentedControl,
},
data() {
return {
items: [
{ title: "推荐" },
{ title: "分类" },
{ title: "最新" },
{ title: "专辑" },
],
current: 0,
};
},
methods: {
onClickItem(e) {
if (this.current !== e.currentIndex) {
this.current = e.currentIndex;
}
},
},
};
</script>

<style lang="scss">
.home_tab {
.home_tab_title {
.title_inner {
width: 60%;
margin: 0 auto;
}
}
}
</style>

使用scss

安装依赖 由于安装

node-sass
提示错误, 所以替换了:

"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"style-resources-loader": "^1.4.1",
<style lang="scss">
.home_tab {
.home_tab_title {
.title_inner {
width: 60%;
margin: 0 auto;
}
}
}
</style>

或:

<style lang="scss" scoped>
.home_tab {
.home_tab_title {
.title_inner {
width: 60%;
margin: 0 auto;
}
}
}
</style>

存储数据

  1. app.globalData

    // 设置
    getApp().globalData.data = {}
    
    // 获取
    const data = getApp().globalData.data
  2. vuex
    uniApp
    内已经内嵌了
    vuex

    第一步: 定义 ./stor/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
    state: {
    hasLogin: false, // 登录状态
    userInfo: {}, // 用户信息
    },
    mutations: {
    setHasLogin(state, value){
    state.hasLogin = value
    console.log(state.hasLogin)
    }
    },
    actions: {},
    getters: {}
    })

    第二步: 在

    mian.js
    中挂载
    store

    import Vue from 'vue'
    import App from './App'
    import store from './store'
    
    Vue.config.productionTip = false
    Vue.prototype.$store = store
    
    App.mpType = 'app'
    
    const app = new Vue({
    ...App,
    store,
    })
    app.$mount()

    第三步: 使用

    vuex

    // 获取state中的值
    this.$store.state.loginStatus
    
    // 修改state中的值
    this.$store.commit('setHasLogin', true);
    
    // 调用actions中的方法
    // 要在actions中定义方法
    this.$store.dispatch('',{number:123})
    
    // 调用getters中的方法
    // 要在getters中定义方法
    this.$store.getters.reverseLoginStatus
  3. uni.setStorage/uni.getStorage
    见: 数据缓存

生命周期钩子函数

有三类:

APP.vue
生命周期: | 函数名 | 说明 | | -- | -- |
onLaunch
| 当
uni-app
初始化完成时触发(全局只触发一次)
onShow
| 当
uni-app
启动,或从后台进入前台显示
onHide
| 当
uni-app
从前台进入后台
onError
| 当
uni-app
报错时触发

pages/xxx/index.vue
生命周期:

函数名 说明
onLoad
监听页面加载,其参数为上个页面传递的数据

组件生命周期 | 函数名 | 说明 | | -- | -- |

beforeCreate
| 在实例初始化之后被调用
created
| 在实例创建完成后被立即调用
beforeMount
| 在挂载开始之前被调用
mounted
| 挂载到实例上去之后调用
beforeUpdate
| 数据更新时调用,发生在虚拟 DOM 打补丁之前 (仅H5平台支持)
updated
| 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子 (仅H5平台支持)
beforeDestroy
| 实例销毁之前调用
destroyed
| Vue 实例销毁后调用

封装request

// 封装自定义请求

export default (params) => {
return new Promise((resolve, reject) => {
// 加载中
uni.showLoading({
title: "加载中...",
});
wx.request({
...params,
success(res) {
// .data => 服务器返回的数据
resolve(res.data); // 成功
},
fail(err) {
reject(err); // 失败
},
complete() {
// 完成请求时
// 隐藏loading
uni.hideLoading();
},
});
});
};

main.js
中:

import Vue from "vue";
import App from "./App";
import request from "./utils/request";

Vue.config.productionTip = false;
Vue.prototype.request = request;

App.mpType = "app";

const app = new Vue({
...App,
});
app.$mount();

使用时:

this.request({
url: "http://xxxx",
data: {}
})

登录组件

<!-- 微信授权登录全程代码实现 -->
<template>
<view>
<view v-if="isLoading">
<view>
<view class="header">
<!-- <image src="../../static/img/wx_login.png"></image> -->
</view>
<view class="content">
<view>申请获取以下权限</view>
<text>获得你的公开信息(昵称,头像、地区等)</text>
</view>

<button
class="bottom"
type="primary"
open-type="getUserInfo"
withCredentials="true"
lang="zh_CN"
@getuserinfo="getUserInfo"
>
授权登录
</button>
</view>
</view>
</view>
</template>

<script>
export default {
data() {
return {
SessionKey: "",
OpenId: "",
appKey: "abcdef",
nickName: null,
avatarUrl: null,
isLoading: uni.getStorageSync("isLoading") || true, //默认为true
};
},
methods: {
getUserInfo() {
/* 获取用户信息 */
uni.getUserInfo({
provider: "weixin",
// 获取成功后调用
success: (infoRes) => {
let nickName = infoRes.userInfo.nickName; //获取用户登录昵称
let avatarUrl = infoRes.userInfo.avatarUrl; //获取用户头像
this.nickName = nickName;
this.avatarUrl = avatarUrl;

console.log("nickName: ", nickName);
console.log("avatarUrl: ", avatarUrl);
try {
uni.setStorageSync("isLoading", false); //记录是否第一次授权  false:表示不是第一次授权
this.updateUserInfo();
} catch (e) {
console.log(e);
}
},
fail(res) {},
});
},
login() {
/* 登录函数 */
uni.showLoading({
title: "登录中...",
});

// 1.wx获取登录用户code
uni.login({
provider: "weixin",
success: (loginRes) => {
let code = loginRes.code;
if (!this.isLoading) {
//非第一次授权获取用户信息

uni.getUserInfo({
provider: "weixin",
success: (infoRes) => {
//获取用户信息后向调用信息更新方法
let nickName = infoRes.userInfo.nickName; //昵称
let avatarUrl = infoRes.userInfo.avatarUrl; //头像
this.nickName = nickName;
this.avatarUrl = avatarUrl;

console.log("nickName: ", nickName);
console.log("avatarUrl: ", avatarUrl);
this.updateUserInfo(); //调用更新信息方法
},
});
}

//2.将用户登录code传递到后台置换用户SessionKey、OpenId等信息
uni.request({
url: `${this.serveHost}/login`, //接入后端提供的登录接口
data: {
code: code, //传入参数code获取登录凭证
},
method: "GET",
header: {
"content-type": "application/json",
}, //请求头
success: (res) => {
// 成功登录后调用
// 可以: openId、或SessionKdy存储//隐藏loading

uni.hideLoading();
},
});
},
});
},

updateUserInfo() {
/* 向后台更新信息 */

uni.request({
url: `${this.serveHost}/user`, //服务器端地址
data: {
appKey: this.appKey, //Vuex封装app密钥 this.$store.state.appKey
customerId: "this.customerId", //自定义id  this.customerId
nickName: this.nickName, //昵称
headUrl: this.avatarUrl, //头像
},
method: "POST",
header: {
"content-type": "application/json",
},
success: (res) => {
if (res.data.state == "success") {
uni.reLaunch({
//信息更新成功后跳转到小程序首页
url: "/pages/home/index",
});
}
},
});
},
},
onLoad() {
//默认加载
this.login();
},
};
</script>

<style>
.header {
margin: 90rpx 0 90rpx 50rpx;
border-bottom: 1px solid #ccc;
text-align: center;
width: 650rpx;
height: 300rpx;
line-height: 450rpx;
}

.header image {
width: 200rpx;
height: 200rpx;
}

.content {
margin-left: 50rpx;
margin-bottom: 90rpx;
}

.content text {
display: block;
color: #9d9d9d;
margin-top: 40rpx;
}

.bottom {
border-radius: 80rpx;
margin: 70rpx 50rpx;
font-size: 35rpx;
}
</style>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: