运行uniapp
- HBuilderX下载
- 浏览器中运行
- HBuilderX中,选中项目,点击运行(工具栏)-> 运行到浏览器 -> Chrome
- 微信开发者工具
- 首次需配置
- 开启服务端口:微信开发者工具中,点击设置(工具栏) -> 安全设置 -> 打开服务端口
- 配置微信开发者工具的安装路径:HBuilderX中,点击运行(工具栏)-> 运行到小程序模拟器 -> 微信开发者工具 -> 填写微信开发者工具的安装路径
- HBuilder中,点击运行(工具栏)-> 运行到小程序模拟器 -> 微信开发者工具
- 运行 App 到手机或模拟器
- mumu模拟器下载
- adb调试桥(命令行工具)
- 功能:连接手机设备、安装App、热更新、调试打印log等
- 下载
- 配置,或者直接在HBuilderX中下载插件
- 配置adb环境变量
- 将安装目录配置到环境变量 path
- cmd,敲入 adb 验证是否配置成功
- HBuilderX中配置adb
- HBuilder中,点击运行(工具栏)-> 运行到手机或模拟器 -> ADB路径设置
- 配置mumu模拟器
- cmd命令行,adb connect 127.0.0.1:7555,mumu的默认运行端口7555
- cmd命令行,adb devices,查看是否连接成功
- 运行项目
- HBuilder中,点击运行(工具栏)-> 运行到手机或模拟器 -> 运行到Android App基座
uni-app概述
局部样式和全局样式
- 全局样式:uni.css,App.vue
- 局部样式:pages里的vue文件都是,相当于
<style scoped></style>(uni-app的style标签不写scoped属性)
app.vue 和 pages 里的页面
<!-- # App.vue -->
<script>
export default {
// 1. 应用生命周期
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
},
// 2. 定义全局数据
globalData: {
name: 'shan',
age: 16,
}
}
</script>
<style>
/* 3.每个页面公共css */
.title {
color: lightcoral;
}
</style>
<!-- # pages/index/index.vue -->
<template>
<view class="content">
<text class="title">{{title}}</text>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
}
},
// 页面生命周期
onLoad() {
console.log("this->", this); // vue 的实例
// 全局数据 globalData
const app = getApp() // 当前应用实例
console.log("globalData->", app.globalData)
// 当前页面路由
const pages = getCurrentPages() // 当前页面栈实例
console.log("route->", pages[pages.length - 1].route)
},
// vue 组件的生命周期
beforeCreate() {
console.log('beforeCreate')
},
created() {
console.log('created')
},
methods: {}
}
</script>
<style>
.title {
font-size: 36rpx;
}
</style>

其他页面
- page.json 全局页面配置,类似小程序 app.json
- manifest.json 跨端配置
uni-app 组件
内置组件
- view
- text
- button
- image
- scrollview
- swiper
尺寸单位 rpx
- uniapp支持通用css单位,px/rpx(推荐)/vh/vw
- rpx(responsive pixel),可根据屏幕宽度自适应
- 规定屏幕宽为750rpx
- 若设计稿标准为iPhone6(760px),一个100px的宽度,在uniapp的宽度计算为:100px/760px = uniapp宽度/760rpx,即1rpx=1px
条件编译
console.log('1111111111111')
其他
- 样式导入 @import
- 背景图片
- 小程序不支持本地图片,支持base64/线上图片
- uniapp支持小于40kb的本地图片
- 字体图标
扩展组件(uni-ui)
- 安装
- 官网按需下载,自动导入
- 在uni.scss可以改uni-ui提供的内置scss变量
- uni-from
- 更改组件样式
- global(选择器) {}!important 全局
- deep(选择器) {}!important 局部
路由
路由(组件)
<navigator url="/pages/index/index">
<button type="default">index</button>
</navigator>
<navigator url="/pages/detail/detail" open-type="redirect">
<button type="default">当前页打开 detail</button>
</navigator>
<navigator url="/pages/cart/cart" open-type="switchTab">
<text>cart tab</text>
</navigator>
- open-type 属性
- navigate(默认),对应 uni.navigateTo 的功能
- redirect,对应 uni.redirectTo 的功能
- switchTab,对应 uni.switchTab 的功能
- navigateBack,对应 uni.navigateBack 的功能
- reLaunch,对应 uni.reLaunch 的功能,抖音小程序与飞书小程序不支持
路由(API)
gotoPage() {
uni.navigateTo({
url: "/pages/detail/detail"
})
}
页面之间通讯
url(query)和eventChannel
methods: {
gotoDetail() {
uni.navigateTo({
url: "/pages/detail/detail?name=shan&id=123",
events: {
acceptDataFromOtherPage: function(data) {
console.log('otherPage', data)
}
},
success(res) {
res.eventChannel.emit('acceptDataFromHomePage', {
data: "home data"
})
}
})
}
onLoad(option) {
const urlQuery = option
console.log('urlQuery', urlQuery)
const eventChannel = this.getOpenerEventChannel();
eventChannel.emit('acceptDataFromOtherPage', {
data: 'fromDetailPage'
});
eventChannel.on('acceptDataFromHomePage', function(data) {
console.log('formHomePage', data)
})
},
<script setup>
import { ref, getCurrentInstance } from 'vue';
import { onLoad } from '@dcloudio/uni-app'
const $instance = ref(getCurrentInstance().proxy)
onLoad(() => {
const eventChannel = $instance.value.getOpenerEventChannel()
eventChannel.on('acceptDataFromHomePage', function(data) {
console.log('formHomePage111', data)
})
})
</script>

- 特殊字符时需要对参数进行编码
encodeURIComponent(JSON.stringify(item))
<navigator :url="'/pages/test/test?item='+ encodeURIComponent(JSON.stringify(item))"></navigator>
onLoad: function (option) {
const item = JSON.parse(decodeURIComponent(option.item));
}
事件总线
uni.$emit(eventName, Object)
uni.$on(eventName, callback)
uni.$once(eventName, callback)
uni.$off(eventName, callback)
globalData
本地数据存储
- uni.setStorage 异步
- uni.setStorageSync 同步
- uni.getStorage
- uni.getStorageSync
- uni.getStorageInfo
- uni.getStorageInfoSync
- uni.removeStorage
- uni.removeStorageSync
- uni.clearStorage
- uni.clearStorageSync
uni.setStorage({
key: 'storage_key',
data: 'hello',
success: function () {
console.log('success');
}
});
Vuex和pinia,状态管理库
常用的页面生命周期
<script setup>
import { ref, onMounted } from 'vue';
import {
onLoad,
onShow,
onReady,
onHide,
onUnload,
onPullDownRefresh,
onReachBottom
} from '@dcloudio/uni-app'
onLoad(() => { console.log('onLoad') })
onShow(() => { console.log('onShow') })
onReady(() => { console.log('onReady') })
onUnload(() => { console.log('onUnload') })
onHide(() => { console.log('onHide') })
onReachBottom(() => { console.log('onReachBottom')})
onPullDownRefresh(() => {
console.log('onPullDownRefresh')
setTimeout(()=>{
uni.stopPullDownRefresh()
}, 1000)
})
uni.setStorage({
key: 'storage_key',
data: 'hello',
success: function () {
console.log('success');
}
});
</script>
自定义组件
- vue标准组件需要创建、引用、注册
- easycom组件,符合
根目录/components/s-button/s-button.vue的目录结构,可以在页面中直接使用
<view>
<s-button type="success" @onBtnClick="handleClick">button</s-button>
<s-button type="default" @onBtnClick="handleClick">button</s-button>
</view>
<template>
<view :class="['s-btn', type]" @click="handleBtnClick">
<slot></slot>
</view>
</template>
<script setup>
const props = defineProps({
type: String,
default: 'default'
})
const emit = defineEmits(['onBtnClick'])
function handleBtnClick() {
console.log('buttonclick')
emit('onBtnClick')
}
</script>
<style>
.s-btn {
text-align: center;
line-height: 60rpx;
height: 60rpx;
margin: 10rpx;
}
.default {
background-color: aquamarine;
}
.success {
background-color: lightgreen
}
</style>
pinia
import App from './App'
import { createSSRApp } from 'vue'
import * as Pinia from 'pinia';
export function createApp() {
const app = createSSRApp(App)
app.use(Pinia.createPinia());
return {
app,
Pinia,
}
}
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => {
return { count: 100 }
},
actions: {
increment() { this.count ++; },
decrement() { this.count --; }
}
})
<template>
<view>
<button @click="handleAdd">+</button>
<button @click="handleSub">-</button>
<text>{{ counter.count }}</text>
</view>
</template>
<script setup>
import { useCounterStore } from '@/stores/counter.js'
const counter = useCounterStore()
function handleAdd() {
counter.increment()
}
function handleSub() {
counter.decrement()
}
</script>