一、常用内置组件
1、view:视图容器,类似于div
2、text:文本组件,用于包裹文本内容
3、button:按钮组件,在小程序端的主题色与其他端主题色不一样
4、image:图片,支持相对路径、绝对路径、导入
mode="widthFix" 高度根据宽度自适应
<image :scr="img" mode="widthFix"></image>
import img from './img/image.png'
data() {
return {
img: img
}
}
5、scroll-view:
隐藏滚动条 :show-scrollbar="false"
<scroll-view scroll-x="true" class="x-scroll" :show-scrollbar="false">
<view></view>
</scroll-view>
.x-scroll {
white-space: nowrap;
}
// H5隐藏滚动条
.x-scroll {
// :deep 或 :global
:global(.x-scroll .uni-scroll-view::-webkit-scrollbar) {
display: none;
}
}
6、swiper:
<swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000">
<swiper-item>
<view class="swiper-item"></view>
</swiper-item>
<swiper-item>
<view class="swiper-item"></view>
</swiper-item>
</swiper>
二、修改组件样式:
方案一:wx小程序 和 app 的修改方案
.uni-forms-item_label {
color: red !important;
padding-left: 10rpx;
}
方案二:wx小程序 H5 app 的修改方案 (推荐)
:deep(.uni-forms-item__label) {
color: pink !important;
}
方案三:wx小程序 H5 app 的修改方案
:global(.uni-forms-item__label) {
color: purple !important;
}
三、路由跳转:
1、通过navigator 组件跳转
<navigator url="/pages/detail01/detail01" open-type="navigate">
<button type="default">01-detail navigate</button>
</navigator>
<navigator url="/pages/detail01/detail01" open-type="redirectTo">
<button type="default">02-detail redirectTo</button>
</navigator>
<navigator url="/pages/category/category" open-type="switchTab">
<button type="default">03-category switchTab</button>
</navigator>
2、通过navigatorTo、redirectTo、navigateBack、switchTab API跳转
<button type="default" @click="goToDetail01"></button>
<button type="default" @click="goToDetail02"></button>
<button type="default" @click="goToDetail03"></button>
methods: {
goToDetail01() {
uni.navigateTo({
url: '/pages/detail01/detail01'
})
},
goToDetail02() {
uni.redirectTo({
url: '/pages/detail01/detail01'
})
},
goToDetail03() {
uni.switchTab({
url: '/pages/category/category'
})
}
}
路由方式 | 页面栈表现 | 触发时机 |
---|---|---|
初始化 | 新页面入栈 | uni-app打开的第一个页面 |
打开新页面 | 新页面入栈 | 调用uni.navigateTo或使用组件<navigator open-type="navigate"/> |
页面重定向 | 当前页面出栈,新页面入栈 | 调用uni.redirectTo或使用组件<navigator open-type="redirectTo"/> |
页面返回 | 页面不断出栈,直到目标返回页 | 调用uni.navigateBack或使用组件<navigator open-type="navigateBack"/>或用户点击左上角返回按钮或安卓用户点击物理back按键 |
Tab切换 | 页面全部出栈,只留下新的Tab页面 | 调用uni.switchTab或使用组件<navigator open-type="switchTab"/>或用户切换Tab |
重加载 | 页面全部出栈,只留下新的页面 | 调用uni.reLaunch或使用组件<navigator open-type="relaunch"/> |
四、页面间的通信:
页面间通信的方式:
- url查询字符串
- EventChannel
- 事件总线
- 全局数据 globalData
- 本地数据存储
- Vuex和Pinia
1. url查询字符串(home 向detail 组件的传递)
1. 组件的方式
// home.vue
<navigator url="/pages/detail?name=coder&id=100" open-type="navigate">
<button type="default"></button>
</navigator>
// detail.vue
onLoad(options) {
console.log('接收到的参数:', options)
}
2. Api 的方式
// home.vue
<button type="default" @click="goToDetail()"></button>
goToDetail() {
uni.navigateTo({
url: "/pages/detail?name=coder&id=100"
})
}
// detail.vue
onLoad(options) {
console.log('接收到的参数:', options)
}
2. EventChannel
home组件向detail 组件的传递
// home.vue
<button type="default" @click="goToDetail()"></button>
goToDetail() {
uni.navigateTo({
url: "/pages/detail?name=coder&id=100",
success(res) {
res.eventChannel.emit("acceptDataFromHome", {
data: '从home 传递的数据'
})
}
})
}
// detail.vue
onLoad(options) {
console.log('接收到的参数:', options)
const eventChannel = this.getOpenerEventChannel();
eventChannel.on('acceptDataFromHome', (data) => {
console.log('接收到的参数', data)
})
}
detail组件向home 组件的传递(返回)
1. 组件方式
<navigator :delta="1" open-type="navigateBack">
<button type="default">返回</button>
</navigator>
2. Api 方式
// detail.vue
<button type="default" @click="goBackHome">返回</button>
goBackHome() {
uni.navigateBack({
delta: 1
})
const eventChannel = this.getOpenerEventChannel()
eventChannel.emit("acceptDataFormDetail", {
data: '数据传递'
})
}
// home.vue
goToDetail() {
uni.navigateTo({
url: '/pages/detail?name=coder&id=100',
events: {
acceptDataFromDetail(data) {
console.log('拿到detail 传递过来的数据', data)
}
}
})
}
3. 事件总线
// detail.vue
<button type="default" @click="goBackHome">返回</button>
goBackHome() {
uni.navigateBack({
delta: 1
})
uni.$emit('acceptData', {
data: 'detail 向home 传递数据'
})
}
// home.vue
methods: {
acceptFn(param) {
console.log("param", param)
}
}
onLoad() {
uni.$on('acceptData', this.acceptFn(data))
}
onUnload() {
uni.$off('acceptData', this.acceptFn(data))
}
五、生命周期:
1、常用的应用的生命周期:
- onLaunch:当
uni-app
初始化完成时触发(全局只触发一次),参数为应用启动参数,同 uni.getLaunchOptionsSync 的返回值 - onShow:当
uni-app
启动,或从后台进入前台显示,参数为应用启动参数,同 uni.getLaunchOptionsSync 的返回值 - onHide:当
uni-app
从前台进入后台
2、常用的页面的生命周期:
- onLoad:监听页面加载,该钩子被调用时,响应式数据、计算属性、方法、侦听器、props、slots 已设置完成,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参)
- onShow:监听页面显示,页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面
- onReady: 监听页面初次渲染完成,此时组件已挂载完成,DOM 树($el)已可用,注意如果渲染速度快,会在页面进入动画完成前触发
- onHide:监听页面隐藏
- onUnload: 监听页面卸载
- onResize:监听窗口尺寸变化
- onPullDownRefresh:监听用户下拉动作,一般用于下拉刷新
- onReachBottom:页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据
六、封装接口请求方法:
const TIME_OUT = 6000
const BASE_URL = '/api/'
class HYRequest {
request(url, methods, data) {
return new Promise((resolve, reject) => {
uni.request({
url: BAS_URL + url,
method: method || "GET",
timeout: TIME_OUT,
data: data,
success(res) {
resolve(res.data)
},
fail(err) {
reject(err)
}
})
})
}
get(url, params) {
return this.request(url, "GET", params)
}
post(url, data) {
return this.request(url, "POST", data)
}
}
export default new HYRequest()
七、数据存储:
// 将数据存储到本地(localStorage)
// 1. 异步
uni.setStorage({
key: 'user',
data: {
name: 'coder'
}
})
uni.getStorage({
key: 'user',
success: (data) => {
console.log(data)
}
})
uni.removeStorage({
key: 'user'
})
// 2. 同步
uni.setStorageSync('token', 'abc')
const token = uni.getStorageSync('token')
uni.removeStorageSync('token')
easycom 组件的使用:
当组件的路径定义为:components/组件名称/组件名称.vue 时,该组件可以直接使用,不需要引用
组件中的生命周期与vue 的组件生命周期相同
八、compositionAPI进行组件的通信:
1.通过url 传递参数
home页面向detail页面传值
//home.vue
function goToDetail() {
uni.navigateTo({
url: '/pages/detail?name=coder&id=1'
})
}
// detail.vue
import { onLoad } from '@dcloudio/uni-app'
接收数据方式一:
onLoad((options) => {
console.log(options)
})
接收数据方式二:
const props = defineProps({
name: String,
id: String
})
console.log(props.name, props.id)
2.通过eventChannel 传递参数 (home向detail 传递)
// home.vue
function goToDetail() {
uni.navigateTo({
url: '/pages/detail?name=coder&id=1',
success(res) {
res.eventChannel.emit('acceptDataFromHome', {
data: 'home传递的值'
})
}
})
}
// detail.vue
import { onLoad } from '@dcloudio/uni-app'
import { ref, getCurrentInstance } from 'vue'
获取当前组件的实例
const $instance = ref(getCurrentInstance().proxy)
onLoad((options) => {
console.log(options)
// const eventChanne = $instance.value.getOpenerEventChannel()
const eventChannel = $instance.value.getOpenerEventChannel()
eventChannel.on('acceptDataFromHome', (value) => {
console.log(value)
})
})
detail向home传递
// detail.vue
import { ref, getCurrentInstance } from 'vue'
const $instance = ref(getCurrentInstance().proxy) // this
function goBack() {
uni.navigateBack({
delta: 1
})
const eventChannel = $instance.value.getOpenerEventChannel()
eventChannel.emit('acceptDataFromDetail', {
data: 'detail的数据'
})
}
// home.vue
function goToDetail() {
uni.navigateTo({
url: '/pages/detail?name=coder&id=1',
events: {
acceptDataFromDetail(value) {
console.log(value)
}
}
})
}
3.通过事件总线传递数据
// detail
function goBack() {
uni.navigateBack({
delta: 1
})
通过事件总线触发事件
uni.$emit('acceptDataFromDetail', {
data: 'detail传递的数据'
})
}
// home.vue
import { onLoad, onUnload } from '@dcloudio/uni-app'
function acceptDataFromDetail(value) {
console.log('detail传递过来的数据', value)
}
onLoad(() => {
uni.$on('acceptDataFromDetail', acceptDataFromDetail)
})
onUnload(() => {
uni.$off('acceptDataFromDetail', acceptDataFromDetail)
})
九、uni-app中使用Pinia
uni-app内置了Pinia,使用HBuilder X 不需要手动安装,直接使用即可
使用CLI需要手动安装,执行yarn add Pinia 或 npm install Pinia
使用步骤:
1.在main.js中安装Pinia插件
app.use(Pinia.createPinia())
2.然后创建一个store
3.然后在组件就可以直接使用了
// main.js
import App from './App'
import * as Pinia from 'pinia'
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
app.use(Pinia.createPinia())
return {
app,
Pinia
}
}
// @/store/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => {
return {
count: 800
}
},
actions: {
// 同步
increment() {
this.count++;
},
decrement() {
this.count--
}
}
})
// detail.vue
<view>{{ count }}</view>
<button type="default" @click="addCount">addCount</button>
<button type="default" @click="subCount">subCount</button>
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/store/counter.js'
const counterStore = useCounterStore()
const { count } = storeToRefs(counterStore)
function addCount() {
counterStore.increment()
}
十、样式的混入:
// @/style/global.scss
@mixin normalFlex($direction: row, $justify: space-between) {
display: flex,
flex-direction: $direction,
justify-content: $justify
}
// uni.scss
@import '@/style/global.scss';
// home.vue
@include normalFlex(column, space-around);