之前自定义了顶部和底部导航栏,那接下来就写一个简略的二级页面,这个是出了导航页面之外常常用到的。
目录
- 构造
- 模板
- 款式
- 办法
- 示例
构造
一个一般页面的构造应该是如下所示:
<!-- html -->
<template>
<view class="list"> 列表内容 </view>
</template>
<!-- js -->
<script setup name="list"></script>
<!-- css -->
<style lang="scss" scoped></style>
模板
uniapp 内置了罕用的组件,能够间接应用,和微信小程序一样。
容器类
- view
- scroll-view
- swiper
文本类
- icon
- text
- rich-text
- progress
表单类
- form
- input
- textarea
- label
- radio
- checkbox
- button
- picker
- slider
- switch
其余
- navigator
- image
- audio
- video
- webview
- canvas
- map
款式
款式反对 css
、scss
、less
、stylus
,反对@import
导入内部样式表。
尺寸
通用尺寸
反对以下通用尺寸:
rpx
响应式 pxpx
屏幕像素
非凡尺寸
nvue 不反对,vue 反对:
rem
根字体大小vh
viewpoint height,视窗高度,vw
viewpoint width, 视窗宽度,
nvue 不反对百分比;
计算公式
uni-app 中页面的宽度计算公式:
750 * 元素在设计稿中的宽度 / 设计稿基准宽度
;
例如:
- 设计稿宽度为 750px,元素 A 在设计稿的宽度为 100px,那么元素在 uniapp 外面的宽度为
750*100/750
为 100rpx; - 设计稿宽度为 375px,元素 A 在设计稿的宽度为 100px,那么元素在 uniapp 外面的宽度为
750*100/375
为 200rpx;
导入
应用@import 'path/name.scss'
;
例如:
@import "./index.scss";
全局款式
App.vue
中的款式即为全局款式,对于每一个页面通用,nvue
页面不反对全局款式。
内联款式
在组件的属性中应用 class 或者 style 增加款式。
<!-- style -->
<view :style="{'width':'100rpx'}"> </view>
<!-- class -->
<view class="block"></view>
选择器
在 uniapp 中,*
选择器有效,page
相当于 body
,微信小程序仅反对class
选择器。
选择器 | 样例 | 样例形容 |
---|---|---|
.class | .intro | 抉择所有领有 class=”intro” 的组件 |
#id | #firstname | 抉择领有 id=”firstname” 的组件 |
element | view | 抉择所有 view 组件 |
element, element | view, checkbox | 抉择所有文档的 view 组件和所有的 checkbox 组件 |
::after | view::after | 在 view 组件后边插入内容,仅 vue 页面失效 |
::before | view::before | 在 view 组件前边插入内容,仅 vue 页面失效 |
css 变量
CSS 变量 | 形容 | App | 小程序 | H5 |
---|---|---|---|---|
–status-bar-height | 零碎状态栏高度 | 零碎状态栏高度、nvue 留神见下 | 25px | 0 |
–window-top | 内容区域间隔顶部的间隔 | 0 | 0 | NavigationBar 的高度 |
–window-bottom | 内容区域间隔底部的间隔 | 0 | 0 | TabBar 的高度 |
NavigationBar | 导航栏 | 44px | 44px | |
TabBar | 底部选项卡 | HBuilderX 2.3.4 之前为 56px,2.3.4 起和 H5 调为统一,对立为 50px。(但能够自主更改高度) | 50px |
字体
应用 @font-face
自定义字体。
@font-face {
font-family: 'iconfont',
src: url('iconfont.ttf') format('truetype');
}
.test {font-family: 'iconfont';}
办法
这是 js 中的一些内容。
这里重点关注一下生命周期,包含页面的组件的生命周期。
页面生命周期
罕用到的就是 onLaunch
,onLoad
,onShow
,onHide
等钩子函数。
函数名 | 阐明 | 平台差别阐明 | 最低版本 |
---|---|---|---|
onInit | 监听页面初始化,其参数同 onLoad 参数,为上个页面传递的数据,参数类型为 Object(用于页面传参),触发机会早于 onLoad | 百度小程序 | 3.1.0+ |
onLoad | 监听页面加载,该钩子被调用时,响应式数据、计算属性、办法、侦听器、props、slots 已设置实现,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参),参考示例 | ||
onShow | 监听页面显示,页面每次呈现在屏幕上都触发,包含从上级页面点返回露出以后页面 | ||
onReady | 监听页面首次渲染实现,此时组件已挂载实现,DOM 树 ($el) 已可用,留神如果渲染速度快,会在页面进入动画实现前触发 | ||
onHide | 监听页面暗藏 | ||
onUnload | 监听页面卸载 | ||
onResize | 监听窗口尺寸变动 | App、微信小程序、快手小程序 | |
onPullDownRefresh | 监听用户下拉动作,个别用于下拉刷新,参考示例 | ||
onReachBottom | 页面滚动到底部的事件(不是 scroll-view 滚到底),罕用于下拉下一页数据。具体见下方注意事项 | ||
onTabItemTap | 点击 tab 时触发,参数为 Object,具体见下方注意事项 | 微信小程序、QQ 小程序、支付宝小程序、百度小程序、H5、App、快手小程序、京东小程序 | |
onShareAppMessage | 用户点击右上角分享 | 微信小程序、QQ 小程序、支付宝小程序、抖音小程序、飞书小程序、快手小程序、京东小程序 | |
onPageScroll | 监听页面滚动,参数为 Object | nvue 暂不反对 | |
onNavigationBarButtonTap | 监听原生标题栏按钮点击事件,参数为 Object | App、H5 | |
onBackPress | 监听页面返回,返回 event = {from:backbutton、navigateBack},backbutton 示意起源是左上角返回按钮或 android 返回键;navigateBack 示意起源是 uni.navigateBack;详见 | app、H5、支付宝小程序 | |
onNavigationBarSearchInputChanged | 监听原生标题栏搜寻输入框输出内容变动事件 | App、H5 | 1.6.0 |
onNavigationBarSearchInputConfirmed | 监听原生标题栏搜寻输入框搜寻事件,用户点击软键盘上的“搜寻”按钮时触发。 | App、H5 | 1.6.0 |
onNavigationBarSearchInputClicked | 监听原生标题栏搜寻输入框点击事件(pages.json 中的 searchInput 配置 disabled 为 true 时才会触发) | App、H5 1.6.0 | |
onShareTimeline | 监听用户点击右上角转发到朋友圈 微信小程序 | 2.8.1+ | |
onAddToFavorites | 监听用户点击右上角珍藏 | 微信小程序、QQ 小程序 | 2.8.1+ |
组件生命周期
罕用到的就是 created
,onLoad
,onShow
,onHide
等钩子函数。
生命周期钩子 | 形容 | H5 | App 端 | 小程序 | 阐明 |
---|---|---|---|---|---|
beforeCreate | 在实例初始化之后被调用 详情 | √ | √ | √ | |
created | 在实例创立实现后被立刻调用 详情 | √ | √ | √ | |
beforeMount | 在挂载开始之前被调用 详情 | √ | √ | √ | |
mounted | 挂载到实例下来之后调用 详情 留神:此处并不能确定子组件被全副挂载,如果须要子组件齐全挂载之后在执行操作能够应用 $nextTick 详情 √ | √ | √ | ||
beforeUpdate | 数据更新时调用,产生在虚构 DOM 打补丁之前 详情 | √ | √ | √ | |
updated | 因为数据更改导致的虚构 DOM 从新渲染和打补丁,在这之后会调用该钩子 详情 | √ | √ | √ | |
activated | 被 keep-alive 缓存的组件激活时调用 详情 | √ | √ | x | |
deactivated | 被 keep-alive 缓存的组件停用时调用 详情 | √ | √ | x | |
beforeUnmount | 实例销毁之前调用。在这一步,实例依然齐全可用 详情 | √ | √ | √ | |
unmounted | Vue 实例销毁后调用。调用后,Vue 实例批示的所有货色都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁 详情 | √ | √ | √ | |
errorCaptured | 当捕捉一个来自子孙组件的谬误时被调用 详情 | √ | √ | √ | – |
罕用办法
以下都是 vue3 中的 setup
语法糖上面的应用场景。
uniapp
导入你要应用的办法。
import {
onLoad,
onShow,
onHide,
onPullDownRefresh,
onShareAppMessage,
onShareTimeline,
onAddToFavorites,
} from "@dcloudio/uni-app";
onLoad
: 页面加载。
onLoad((option) => {// option 页面参数});
onShow
: 页面显示;
onShow((e) => {// e});
onHide
: 页面暗藏;
onHide(() => {});
onPullDownRefresh
:下拉刷新;
// 监听下拉刷新
onPullDownRefresh(() => {
// 开始下拉刷新
uni.startPullDownRefresh();
// 进行下拉刷新
uni.stopPullDownRefresh();});
在 pages.json
配置:
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"enablePullDownRefresh": true,
"app-plus": {
"pullToRefresh": {
"support": true,
"color": "#f33",
"style": "circle"
}
}
}
}
onShareAppMessage
:转发到聊天界面;
onShareAppMessage((res) => {const promise = new Promise((resolve) => {
resolve({title: "自定义题目",});
});
return {
path: "/pages/index/index?id=1&name=mark",
imgUrl: "https://example.com/a.png",
title: "首页",
promise,
};
});
onShareTimeline
:转发到朋友圈;
onShareTimeline((res) => {
return {
path: "/pages/index/index",
query: "name=mark",
imgUrl: "https://example.com/a.png",
title: "自定义题目",
};
});
onAddToFavorites
:增加到珍藏;
onAddToFavorites((res) => {
// webview 页面返回 webViewUrl
console.log("webViewUrl:", res.webViewUrl);
return {
title: "自定义题目",
imageUrl: "https://example.com/a.png",
query: "name=mark&age=18",
};
});
vue
导入你要应用的办法。
import {ref, reactive, watch, computed, onMounted, onUnmounted, getCurrentInstance} from "vue";
ref
:适宜根本数据类型,应用.value
拜访和批改值。
let show = ref(true);
show.value = false;
reactive
:适宜援用数据类型,不能间接赋值,必须指定属性批改值。
const person = reactive({
id: 1,
name: "mark",
age: 18,
});
person.name = "jack";
watch
: 监听数据值变动。
watch(() => [person],
(val) => {//...},
{
deep: true,
immediate: true,
}
);
computed
计算属性;
const sayHi = computed(() => {return `Hi,${person.name}!`;
});
onMounted
: 挂载到实例下来之后调用;
onMounted(() => {});
onUnmounted
:实例销毁后调用;
onUnmounted(() => {});
getCurrentInstance
:容许拜访对高级应用或库创建者有用的外部组件实例;
const {proxy} = getCurrentInstance();
defineProps
:接管来自父组件的数据;
const props = defineProps({
width: {
type: Number,
default: 100,
},
color: {
type: String,
default: "#555",
},
show: {
type: Boolean,
default: true,
},
list: {
type: Array,
default() {return [];
},
},
person: {
type: Object,
default() {
return {
id: 1,
name: "mark",
};
},
},
clickMe: {
type: Function,
default() {return "Default function";},
},
});
例如:
<myChild class="post" :width="200" color="#f00" show :list="[1,2,3]" :person="{"id": 2,"name":"jack"}"></myChild>
defineEmits
:向父组件发送事件和数据;
const emits = defineEmits();
例如:
const emits = defineEmits(["success", "fail"]);
emits("success", true);
父组件接管:
<myChild @success="handlerSuccess"></myChild>
const handlerSuccess = (val) => console.log(val); // true
defineExpose
:指定向组件外裸露的属性和办法,默认敞开;
defineExpose({});
例如:
const a = ref(1);
const b = ref(2);
const sum = (a, b) => a + b;
defineExpose({
a,
b,
sum,
});
vuex
vuex 状态治理,次要是引入和应用。
- 引入
import {useStore} from "vuex";
- 应用
const store = useStore();
// 异步办法
store.dispatch({
type: "saveInfo",
data: {
name: "mark",
memo: "no",
},
});
// 同步办法
store.commit({
type: "SAVE_USER",
data: {
id: 1,
name: "mark",
},
});
// 获取状态
store.getters.getUser;
示例
新建页面
在 pages/index
文件夹上面新建一个 list.vue
的文件,在 pages.json
注册路由。
{
"path": "pages/index/list",
"style": {"navigationBarTitleText": "列表"}
}
编写代码
- 模板局部
<view class="block list">
<view class="block-statusbar"></view>
<q-navbar :center="navConfig.center" :right="navConfig.right" />
<view class="block-main block-two-level">
<view class="list-person">
<view v-for="(val, key) in person" :key="key"> {{key}}:{{val}} </view>
</view>
</view>
</view>
- 款式局部
.list-person {padding: 30rpx;}
在 uni.scss
外面定义以下全局变量。
// 全局变量
$statusBarHei: var(--status-bar-height); // 状态栏高度
$navBarHei: 110rpx; // 顶部导航栏高度
$tabBarHei: 120rpx; // 底部导航高度
一个导航页面包含状态栏、顶部导航栏、两头内容区和底部导航栏四块区域,一个一般的页面就是没有底部导航栏。
能够在之前的 styles
文件夹的 global.scss
外面定义全局款式规定,包含整体页面,两头局部,状态栏局部的款式。
// 全局款式
.block {
position: relative;
width: 100%;
height: 100vh;
// 次要内容
.block-main {
position: relative;
top: calc($statusBarHei + $navBarHei);
left: 0;
box-sizing: border-box;
height: calc(100vh - $statusBarHei - $navBarHei - $tabBarHei);
background: $white;
// 二级页面
&.block-two-level {height: calc(100vh - $statusBarHei - $navBarHei);
}
}
}
// 状态栏
.block-statusbar {
width: 100%;
height: $statusBarHei;
}
- 脚本局部
// 导入依赖
import {ref, reactive} from "vue";
const person = reactive({
id: 1,
name: "mark",
age: 18,
});
const navConfig = reactive({
center: {
show: true,
name: "列表页面",
},
right: {show: false,},
});
成果展现
最初
以上就是编写一个简略的利用页面的次要内容,有不足之处,请多多斧正。