Uniapp+Vue3.2写微信小程序学习笔记
uni-app开发微信小程序
安装uni-app
uni-app官方文档:https://uniapp.dcloud.io/quickstart-cli.html
# 使用 npm 安装 CLI
npm install -g @vue/cli@4
一大堆报错,葫芦娃救爷爷,放弃使用脚手架搭建了。最终选用了HBuilderX可视化界面进行搭建,简单暴力,可以直接开始学习使用。
HBuilderX官网下载地址:https://www.dcloud.io/hbuilderx.html
HBuilderX官方操作指南:https://uniapp.dcloud.io/quickstart-hx.html#创建uni-app
注意事项:因为是开发小程序,所以运行的时候使用的是微信小程序开发者工具运行,需要在设置里面开放端口。
Html常用标签
Html5常用标签参考手册:https://www.runoob.com/tags/ref-byfunc.html
CSS常用属性汇总
CSS属性参考手册:https://www.runoob.com/cssref/css-reference.html
CSS选择器参考手册:https://www.runoob.com/cssref/css-selectors.html
CSS听觉参考手册:https://www.runoob.com/cssref/css-ref-aural.html
CSS单位参考手册:https://www.runoob.com/cssref/css-units.html
javaScript
js参考手册:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/import
export
在创建 JavaScript 模块时,**export**
语句用于从模块中导出实时绑定的函数、对象或原始值,以便其他程序可以通过 import
语句使用它们。被导出的绑定值依然可以在本地进行修改。在使用 import 进行导入时,这些绑定值只能被导入模块所读取,但在 export 导出模块中对这些绑定值进行修改,所修改的值也会实时地更新。
无论您是否声明,导出的模块都处于严格模式
。 export 语句不能用在嵌入式脚本中。
语法存在两种 exports 导出方式:
- 命名导出(每个模块包含任意数量)
- 默认导出(每个模块包含一个)
// 导出单个特性
export let name1, name2, …, nameN; // also var, const
export let name1 = …, name2 = …, …, nameN; // also var, const
export function FunctionName(){...}
export class ClassName {...}
// 导出列表
export { name1, name2, …, nameN };
// 重命名导出
export { variable1 as name1, variable2 as name2, …, nameN };
// 解构导出并重命名
export const { name1, name2: bar } = o;
// 默认导出
export default expression;
export default function (…) { … } // also class, function*
export default function name1(…) { … } // also class, function*
export { name1 as default, … };
// 导出模块合集
export * from …; // does not set the default export
export * as name1 from …; // Draft ECMAScript® 2O21
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;
export { default } from …;
import
给定一个名为 myExport
的对象或值,它已经从模块 my-module
导出(因为整个模块被导出)或显式地导出(使用 export
语句),将 myExport
插入当前作用域。
import {myExport} from '/modules/my-module.js';
Copy to Clipboard
这将 foo
和 bar
插入当前作用域。
import {foo, bar} from '/modules/my-module.js';
你可以在导入时重命名接口。例如,将 shortName
插入当前作用域。
import {reallyReallyLongModuleExportName as shortName}
from '/modules/my-module.js';
引入模块可能有一个 default
export
(无论它是对象,函数,类等)可用。然后可以使用 import
语句来导入这样的默认接口。
最简单的用法是直接导入默认值:
import myDefault from '/modules/my-module.js';
其他
js语法和声明手册地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function
let
语句声明一个块级作用域的局部变量,并可以初始化为一个值(可选)。
const常量是块级范围的,非常类似用 let 语句定义的变量。但常量的值是无法(通过重新赋值)改变的,也不能被重新声明。
async函数是使用async
关键字声明的函数。 async 函数是AsyncFunction
构造函数的实例, 并且其中允许使用await
关键字。async
和await
关键字让我们可以用一种更简洁的方式写出基于Promise
的异步行为,而无需刻意地链式调用promise
。
Vue2 Vue3 Vue3.2的区别
Vue参考手册:https://v3.cn.vuejs.org/guide/migration/introduction.html#概览
Vue2写法
<template>
<view @click="btnClick">
{{name}}
</view>
</template>
<script>
export default {
data() {
return {
name:'张三'
}
},
methods: {
btnClick(){
this.name = '李四'
}
}
}
</script>
<style>
</style>
vue3.0写法
<template>
<view @click="btnClick">
{{name}}
</view>
</template>
<script>
import {ref} from 'vue'
export default{
setup() {
const name = ref('张三')
function btnClick(){
name.value='里斯'
}
return {name,btnClick}
}
}
</script>
<style>
</style>
Vue3.2写法
<template>
<view @click="btnClick">
{{name}}
</view>
</template>
<script setup>
//vue3.2写法
import {
ref
} from 'vue'
const name = ref('张三')
function btnClick() {
name.value = '里斯'
}
</script>
<style>
</style>
Vue3: reactive, ref,toRef,toRefs用法和区别
文章推荐:https://juejin.cn/post/7034038818139275294
Vue3.2全局引用js
设置一个可以被注入到应用范围内所有组件中的值。组件应该使用 inject
来接收 provide 的值。从 provide
/inject
的角度来看,可以将应用程序视为根级别的祖先,而根组件是其唯一的子级。该方法不应该与 provide 组件选项或组合式 API 中的 provide 方法混淆。虽然它们也是相同的 provide
/inject
机制的一部分,但是它们是用来配置组件而非应用所 provide 的值。通过应用提供值在编写插件时尤其有用,因为插件一般不能使用组件来提供值。这是对 globalProperties 的替代选择。
文章推荐:https://blog.csdn.net/qq_41619796/article/details/114284535
文章推荐:https://blog.csdn.net/versionli/article/details/116658613
官方文档:https://v3.cn.vuejs.org/api/application-config.html#compileroptions-whitespace
官方文档:https://v3.cn.vuejs.org/api/application-api.html#component
Provide inject引入
创建http.js,并在main.js中引入
import App from './App'
import {createSSRApp} from 'vue'
import {getCurrentInstance} from 'vue';
import {provide}from'vue'
import {http,apiBaseUrl} from '@/api/http.js'
export function createApp() {
const app = createSSRApp(App)
app.provide('$http',http)
app.provide('$apiBaseUrl',apiBaseUrl)
return {app}
}
使用
<template>
<uni-card title="新闻标题" extra="额外信息" isShadow="true">
<image src="../../static/img/物业管理1.webp" style="height: 240rpx;"></image>
<text>{{name}}</text>
<button @click="btnClick()">获取信息</button>
</uni-card>
</template>
<script setup>
import {ref} from 'vue'
import {inject} from 'vue'
const http = inject('$http')
const apiBaseUrl = inject("$apiBaseUrl")
const name = ref('张三')
function btnClick() {
http.get(apiBaseUrl + 'AdvertiseColumn/all').then(res => {
name.value = res.data
})
}
</script>
<style>
</style>
globalProperties引入全局变量
引入
import App from './App'
import {createSSRApp} from 'vue'
import {getCurrentInstance} from 'vue';
import {provide}from'vue'
import {http,apiBaseUrl} from '@/api/http.js'
export function createApp() {
const app = createSSRApp(App)
/* app.provide('$http',http)
app.provide('$apiBaseUrl',apiBaseUrl) */
app.config.globalProperties.$http = http
app.config.globalProperties.$apiBaseUrl = apiBaseUrl
return {app}
}
使用
<template>
<uni-card title="新闻标题" extra="额外信息" isShadow="true">
<image src="../../static/img/物业管理1.webp" style="height: 240rpx;"></image>
<text>{{name}}</text>
<button @click="btnClick()">获取信息</button>
</uni-card>
</template>
<script setup>
import {ref} from 'vue'
/* import {inject} from 'vue' */
/* const http = inject('$http')
const apiBaseUrl = inject("$apiBaseUrl") */
import {getCurrentInstance} from'vue'
const {proxy} = getCurrentInstance()
const name = ref('张三')
function btnClick() {
proxy.$http.get(proxy.$apiBaseUrl + 'AdvertiseColumn/all').then(res => {
name.value = res.data
})
}
</script>
<style>
</style>
九宫格布局
<template>
<view class="home">
<swiper circular indicator-dots>
<!-- v-for循环遍历数组 -->
<swiper-item v-for="item in swipers">
<image :src="item"></image>
</swiper-item>
</swiper>
<uni-section title="菜单" type="line">
<uni-grid :column="4" :highlight="true" @change=goBack>
<uni-grid-item v-for="(item, index) in list" :index="index" :key="index">
<view class="grid-item-box" style="background-color: #fff;">
<uni-icons :type="item.iconfont" customPrefix="iconfont" :size="30" :color="item.color" />
<text class="text">{{item.name}}</text>
</view>
</uni-grid-item>
</uni-grid>
</uni-section>
</view>
</template>
<script setup>
import {
ref,
reactive
} from 'vue'
const swipers = reactive([
'../../static/img/物业管理4.webp',
'../../static/img/物业管理2.webp',
'../../static/img/物业管理3.webp',
])
const list = reactive(
[{
iconfont: 'icon-gonggao',
color: '#4a5fe2',
name: '社区公告'
},
{
iconfont: 'icon-baoxiu',
color: '#ff0000',
name: '报事报修'
},
{
iconfont: 'icon-xinxi',
color: '#036eb8',
name: '信息采集'
},
{
iconfont: 'icon-jiaofeizhongxin',
color: '#007aff',
name: '生活缴费'
},
{
iconfont: 'icon-icon-jiankong',
color: '#438cff',
name: '监控'
},
{
iconfont: '',
color: 'red',
name: '送水'
},
{
iconfont: '',
color: '',
name: '我的车'
},
{
iconfont: '',
color: '',
name: '托管服务'
},
{
iconfont: '',
color: '',
name: '过户'
},
{
iconfont: '',
color: '',
name: '快递查询'
}
]
)
function goBack(e) {
let {
index
} = e.detail
switch (list[index].name) {
case '社区公告':
uni.navigateTo({
url: '../Announcement/Announcement'
})
break;
case '报事报修':
uni.navigateTo({
url: '../Repair/Repair'
})
break;
case '信息采集':
uni.navigateTo({
url: '../Information/Information'
})
break;
case '生活缴费':
uni.navigateTo({
url: '../PayCost/PayCost'
})
break;
default:
uni.navigateTo({
url: '../Monitor/Monitor'
})
}
}
</script>
<style lang="scss">
.home {
display: flex;
flex-direction: column;
}
.grid-item-box {
flex: 1;
// position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
align-items: center;
justify-content: center;
padding: 15px 0;
margin: 5%;
image {
display: flex;
flex-direction: column;
align-content: center;
justify-content: center;
width: 100%;
height: 100%;
}
}
swiper {
image {
width: 100%;
height: 100%;
}
}
</style>
跳转页面传参
主页面
<template>
<view v-for="(item,index) in informations" :key="index">
<uni-card :title="item.title" :extra="item.subTile" isShadow="true" :cover="item.imgUrl" @click="onClick(item)">
<view slot="actions" class="card-actions">
<view class="card-actions-item">
<uni-icons type="pengyouquan" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">分享</text>
</view>
<view class="card-actions-item">
<uni-icons type="heart" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">点赞</text>
</view>
<view class="card-actions-item">
<uni-icons type="chatbubble" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">评论</text>
</view>
</view>
</uni-card>
</view>
</template>
<script setup>
import {
ref,
inject,
reactive,
onMounted
} from 'vue';
const http = inject('$http');
const apiBaseUrl = inject('$apiBaseUrl');
const informations = reactive([]);
const name = ref('张三');
onMounted((e) => {
http.get(apiBaseUrl + "Information/all").then(res => {
res.data.data.forEach(
(item => {
informations.push({
title: item.title,
subTile: item.subTile,
content: item.content,
imgUrl: item.imageUrl
})
})
)
console.log(informations)
})
})
function onClick(e) {
uni.navigateTo({
url: '../AnnouncementTheDetail/AnnouncementTheDetail?obj=' + encodeURIComponent(JSON.stringify(e))
})
console.log('正在跳转页面')
console.log(JSON.stringify(e))
}
</script>
<style lang="scss">
.card-actions {
display: flex;
flex-direction: row;
justify-content: space-around;
}
</style>
子页面
<template>
<view class="info">
<text>{{info.title}}</text>
<text>{{info.subTile}}</text>
<image :src="info.imgUrl"></image>
<text>{{info.content}}</text>
</view>
</template>
<script setup>
import {
onLoad
} from '@dcloudio/uni-app'
import {
ref,
reactive
} from 'vue'
const info = reactive({
title: '',
subTile: '',
content: '',
imgUrl: ''
})
onLoad((e) => {
let information = JSON.parse(e.obj)
info.title = information.title
info.content = information.console
info.imgUrl = information.imgUrl
info.subTile = information.subTile
console.log(info)
})
</script>
<style lang="scss">
.info {
display: flex;
flex-direction: column;
}
</style>
弹窗
<template>
<view>
<button @click="titlePop()">标题弹窗</button>
<button @click="showLoading()">显示Loading弹窗</button>
<button @click="hideLoading()">隐藏Loading弹窗</button>
</view>
</template>
<script setup>
function titlePop() {
uni.showModal({
title: '弹窗标题',
content: '弹窗内容asdfasdfsdf',
showCancel: false,
})
}
function showLoading() {
uni.showLoading({
title: '加载中'
})
}
function hideLoading() {
uni.hideLoading()
}
</script>
<style>
</style>
网络请求
- 引用luch-request插件
- 封装http异常处理工具类,创建api 文件夹 http.js
import Request from '@/js_sdk/luch-request/luch-request/index.js'
export const apiBaseUrl = 'http://120.26.238.37:7300/api/'
const http = new Request()
http.config.header = {website:'123dfdf465132'}
/* 设置全局配置 */
http.setConfig((config) => {
config.header = {...config.header,a: 1111111, b: 2222}
return config
})
//请求前拦截,用来动态加参,例如token
http.interceptors.request.use((config) => { // 可使用async await 做异步操作
config.baseURL = apiBaseUrl
config.header = {...config.header,token:"not setting"}
// 演示custom 用处
// if (config.custom.auth) {
// config.header.token = 'token'
// }
if (config.custom.loading) {
uni.showLoading({
title:"加载中..."
})
}
/**
/* 演示
if (!token) { // 如果token不存在,return Promise.reject(config) 会取消本次请求
return Promise.reject(config)
}
**/
return config
}, config => { // 可使用async await 做异步操作
return Promise.reject(config)
})
// 请求后
http.interceptors.response.use(async(response) => {
// console.log(response)
if (response.config.custom.loading) {
uni.hideLoading()
}
return response
}, (response) => { /* 对响应错误做点什么 (statusCode !== 200)*/
// console.log(response)
// console.log(response.statusCode);
// //未登录时清空缓存跳转
// if(response.statusCode ==401){
// uni.clearStorageSync();
// uni.switchTab({
// url:"/pages/user/user"
// })
// }
return Promise.reject(response)
})
export {http}
- 引入main.js 全局变量
import App from './App'
import {createSSRApp,getCurrentInstance,provide} from 'vue'
import {http,apiBaseUrl} from '@/api/http.js'
export function createApp() {
const app = createSSRApp(App)
app.provide('$http',http)
app.provide('$apiBaseUrl',apiBaseUrl)
return {app}
}
- 使用封装好的http.js 进行http请求
<template>
<view v-for="(item,index) in informations" :key="index">
<uni-card :title="item.title" :extra="item.subTile" isShadow="true" :cover="item.imgUrl" @click="onClick(item)">
<view slot="actions" class="card-actions">
<view class="card-actions-item">
<uni-icons type="pengyouquan" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">分享</text>
</view>
<view class="card-actions-item">
<uni-icons type="heart" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">点赞</text>
</view>
<view class="card-actions-item">
<uni-icons type="chatbubble" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">评论</text>
</view>
</view>
</uni-card>
</view>
</template>
<script setup>
import {
ref,
inject,
reactive,
onMounted
} from 'vue';
const http = inject('$http');
const apiBaseUrl = inject('$apiBaseUrl');
const informations = reactive([]);
const name = ref('张三');
onMounted((e) => {
http.get(apiBaseUrl + "Information/all").then(res => {
res.data.data.forEach(
(item => {
informations.push({
title: item.title,
subTile: item.subTile,
content: item.content,
imgUrl: item.imageUrl
})
})
)
console.log(informations)
})
})
</script>
<style lang="scss">
.card-actions {
display: flex;
flex-direction: row;
justify-content: space-around;
}
</style>
页面生命周期onMounted
<template>
<view v-for="(item,index) in informations" :key="index">
<uni-card :title="item.title" :extra="item.subTile" isShadow="true" :cover="item.imgUrl" @click="onClick(item)">
<view slot="actions" class="card-actions">
<view class="card-actions-item">
<uni-icons type="pengyouquan" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">分享</text>
</view>
<view class="card-actions-item">
<uni-icons type="heart" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">点赞</text>
</view>
<view class="card-actions-item">
<uni-icons type="chatbubble" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">评论</text>
</view>
</view>
</uni-card>
</view>
</template>
<script setup>
import {
ref,
inject,
reactive,
onMounted
} from 'vue';
const http = inject('$http');
const apiBaseUrl = inject('$apiBaseUrl');
const informations = reactive([]);
const name = ref('张三');
onMounted((e) => {
http.get(apiBaseUrl + "Information/all").then(res => {
res.data.data.forEach(
(item => {
informations.push({
title: item.title,
subTile: item.subTile,
content: item.content,
imgUrl: item.imageUrl
})
})
)
console.log(informations)
})
})
function onClick(e) {
uni.navigateTo({
url: '../AnnouncementTheDetail/AnnouncementTheDetail?obj=' + encodeURIComponent(JSON.stringify(e))
})
console.log('正在跳转页面')
console.log(JSON.stringify(e))
}
</script>
<style lang="scss">
.card-actions {
display: flex;
flex-direction: row;
justify-content: space-around;
}
</style>