概述
uni-app
(Union Application) 是一个基于Vue.js的前端框架;开发规范借鉴了微信小程序
前端技能点:
- 前后端分离,后端给接口和API文档,注重前端
- 用uni-app框架
作用:
- 创业团队可以更快的开发上线一个app,更容易抢占互联网市场,获取利润
- 原先多个人开发的工作现在只需要一个人完成,节省人力物力成本
- 个人开发者私活利器,包办多端产品
- 毕业设计多平台
优势:
- 同一套代码编译多端(Android、IOS、H5、小程序)
- 接近原生系统,效率更好
- 利用Hbuiler X,开发效率高,内存占用少
- 开发(人力、维护、时间)成本低
- 学过Vue之后,学习成本很低
- 支持npm与自定义组件
- 社区活跃,版本迭代快
HBuilder X调试
点击工具-设置,添加小程序运行配置:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qrwpm0H4-1620737310925)(D:Desktopmarkdown学习笔记前端uni-app.assetsimage-20210329095358519.png)]
点击运行按钮-微信小程序开发者工具,会自动打开开发工具并运行:
Vue.js简介
Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架。
Vue 只关注视图层, 采用自底向上增量开发的设计。
Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
MVC与MVVN思想
后端MVC开发模式
Model(数据增删改)+View(前端页面)+Controller(处理业务+路由)
前端MVVN开发模式
View(页面HTML)+Model(单页面的静态数据JSON)+ViewModel(核心调度者协调器)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5UPvXssA-1620737310932)(D:Desktopmarkdown学习笔记前端uni-app.assetsimage-20210329111637677.png)]
ViewModel实现数据双向绑定:
- 数据丢给VM来做数据渲染的动作,再交给HTML
- 如果用户修改了HTML的数据,VM会再次传递到Model里面
测试MVVN双向绑定
uni-app框架中的页面全是.vue,编写第一个index.vue代码:
<!-- <template> <script> <style>这三个标签在每个页面都只能存在一个
templete:View-->
<template>
<!-- div -->
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<!-- 虚拟DOM:数据双向绑定 -->
<text class="title">{{title}}</text>
<!-- :value 数据与data中的title进行绑定
@input 事件绑定 "change" 事件名称-->
<input type="text" :value="title" @input="change"/>
</view>
</view>
</template>
<script>
// VM对象:协调者 调度器
export default {
// Model:所有的数据
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
// methods:所有用户自定义的方法
methods: {
change(e){
var txtTitle=e.detail.value;
// 更新data中的title
this.title=txtTitle;
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
测试结果:input框中输入的内容,可以同步的回显在text页面框中
vue同样支持JSON对象和数组的渲染:
<view>
I am {{student.age}} years old. <br/>
I have skills such as: {{skill[0]}},{{skill[1]}},{{skill[2]}},{{skill[3]}}
</view>
data() {
return {
title: 'Hello',
student:{
age:18
},
skill:["Java","HTML","CSS","Vue","uni-app"]
}
},
页面路由以及标题配置
页面路由
pages底下所有的页面都要在pages.json中配置页面路由,实际上创建页面时,框架也会为我们自动创建:
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
}
,{ //自动创建
"path" : "pages/hello/hello",
"style" :
{
"navigationBarTitleText": "私有页面标题", //覆盖全局标题
"enablePullDownRefresh": false
}
}
],
"globalStyle": { //标题栏
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8", //导航栏颜色
"backgroundColor": "#F8F8F8" //窗口背景色
}
}
标题配置
"globalStyle": { //标题栏
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8", //导航栏颜色
"backgroundColor": "#F8F8F8" //窗口背景色
//查看uni-app官网,有更多的参数属性可以配置
}
宏观讲解项目配置
项目结构
static文件:css、js、jpg
unpackage文件:打包目录,会构建一个dev/app-plus(手机)、dev/mp-weixin(小程序);发布会有一个build/app-plus。
App.vue:提取每个页面公共css,可以在其他vue中使用(可以被局部style覆盖)
<style>
/*每个页面公共css */
.green{
background-color: #4CD964;
}
</style>
<view class="green" style="width: 300px; height: 300px;"> 调用 </view>
main.js:项目的入口文件,可以统一配置全局的对象、数组、函数(如url与用户信息)
manifest.json:项目配置与发布
- 项目默认分配一个uni-app;
- App图标、启动图配置是发布用的;
- App模块权限是第三方的权限(支付、定位、摄象头等)
- h5配置(https设置、端口设置)
- 微信小程序配置(官方的App ID、本地测试环境建议取消勾选“检查安全域名和TLS版本”)
uni.scss:常用变量样式,预处理,用于插件开发
应用与页面的生命周期
应用的生命周期
app.vue中的函数触发时机:
<script>
export default {
onLaunch: function() { //当uni-app 初始化完成时触发(全局只触发一次)
console.log('App Launch')
},
onShow: function() { //当 uni-app 启动,或从后台进入前台显示
console.log('App Show')
},
onHide: function() { //当 uni-app 从前台进入后台
console.log('App Hide')
}
}
</script>
微信小程序中额外的两个生命周期触发方法 | 触发时机 |
---|---|
onError | 当 uni-app 报错时触发 |
onPageNotFound | 页面不存在监听函数 |
页面的生命周期
除了应用的触发方法,还有一些方法,可以查看官方文档:https://uniapp.dcloud.io/
onLoad() {
console.log('页面加载')
},
onShow() {
console.log('页面显示')
},
onReady() {
console.log('页面初次渲染完成')
},
onHide() {
console.log('页面隐藏')
},
onUnload() {
console.log('页面关闭')
},
onShareAppMessage() {
console.log('页面分享')
},
onPageScroll() {
console.log('页面滚动')
},
onBackPress() { // 不支持小程序,通常写在onLoad中
console.log('页面返回')
},
由于测试需要跳转,跳转代码如下:
<!-- open-type对应onBackPress()页面跳转 -->
<navigator url="../index/index" open-type="navigateBack">
<view class="green" style="width: 300px; height: 300px;"></view>
</navigator>
px&upx像素
px是固定大小的像素,但每个手机的像素不一致,为了兼容不同的机型,引入了upx,根据屏幕大小做自适应。
750upx是屏幕的宽度,可以在不同机型上做自适应,1:1的显示一个正方形:
<view class="green" style="width: 750upx; height: 750upx;"></view>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JUFgJCdj-1620737310935)(D:Desktopmarkdown学习笔记前端uni-app.assetsimage-20210330113009171.png)]
注意:字体和变宽都会设定为固定像素,用px即可(并不是所有地方都用upx)
数据绑定
在标签外部,都用{{表达式}}
{{student.age+'1'}} //字符串拼接{{student.age>=18 ? '成年':'未成年'}} //三元表达式
v-bind:
在标签内时,需要用v-bind:(也可以只写一个:)
<navigator v-bind:url=url >
事件处理
用户与应用交互的方式
创建event.vue做一些简单的测试:
<template> <view> <input type="text" style="width: 300upx; height: 100upx; color: #55430e;" @input="change" @focus="focus" @blur="blur" @confirm="confirm" @tap="tap" @longpress="longpress" @touchstart="touchstart" @touchend="touchend" @touchmove="touchmove" /> </view></template><script> export default { data() { return { } }, methods: { //所有函数写在methods对象中 focus(){ console.log("获得焦点") }, blur(){ console.log("失去焦点") }, confirm(){ console.log("点击完成/回车") }, tap(){ console.log("触摸按压") }, longpress(){ console.log("长按") }, touchstart(){ console.log("触摸开始") }, touchend(){ console.log("触摸结束") }, touchmove(){ console.log("触摸移动") }, } }</script>
条件语法
条件渲染v-if与v-show
<view> <view v-if="isShow"> now you see me </view> <view v-else> can not see </view> <!-- false:在前端隐藏整个标签的代码 --> <view v-show="isShow"> now you see me </view> </view>
三元运算
<view v-if="sex==1?true:false"> 男 </view> <view v-if="sex==1"> 男 </view> <view v-else-if="sex==0"> 女 </view> <view v-else> 未知 </view>
列表渲染嵌套v-for
嵌套双循环需要指定index避免冲突
<template> <view> <!-- (stu,stuIndex) (对象,下标) 下标可以省略,但是在多重循环中,避免index冲突,显示定义成不一样的--> <view v-for="(stu,stuIndex) in stuArray"> <view>学生姓名:{{stu.name}},年龄:{{stu.age}}</view> <view> 擅长技能: <!-- <view v-for="skill in stu.skills">{{skill}}</view> --> <!-- block只显示对象的元素(简单的字符串拼接),而view显示标签(会换行) --> <block v-for="(skill,skillIndex) in stu.skills">{{skill}},</block> </view> </view> </view></template><script> export default { data() { return {//循环遍历一个列表 stuArray:[ { name:"joey", age:21, skills:["Java","HTML","CSS","Vue","uni-app"], }, { name:"carmine", age:22, skills:["Java","HTML","uni-app"], }, { name:"spark", age:23, skills:["HTML","CSS","Vue","uni-app"], } ] } }, methods: { } }</script>
:key的作用
<!-- :key 保证组件和数据捆绑唯一 --><view v-for="stu in stuArray" :key="stu.id"> <!-- 用:value使复选款的value与{{}}表达式关联 --> <checkbox :value="stu.name" >{{stu.name}}</checkbox></view><button type="primary" @click="addStu">新增学生</button>
条件编译(跨端)
**写法:**以 #ifdef 或 #ifndef 加 %PLATFORM% 开头,以 #endif 结尾。
- #ifdef:if defined 仅在某平台存在
- #ifndef:if not defined 除了某平台均存在
- %PLATFORM%:平台名称
支持的文件
- .vue
<!-- #ifdef H5 --> <view> 只在H5编译 </view> <!-- #endif --> <!-- #ifdef MP-WEIXIN --> <view> 只在微信小程序编译 </view> <!-- #endif --> <!-- #ifndef MP --> <view> 不在小程序全端编译,只在IOS、Android、H5编译 </view> <!-- #endif -->
- .js
onLoad() { // #ifdef H5 console.log("只在H5编译"); // #endif },
- .css
<style> /* 在多端显示不同的颜色 */ .color { /* #ifdef H5 */ background-color: #4CD964; /* #endif */ /* #ifdef APP-PLUS */ background-color: #007AFF; /* #endif */ width: 200upx; height: 200upx; }</style>
Flex自适应布局(重点)
Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。
Flex容器的属性
flex-direction
属性决定主轴的方向(即项目的排列方向)。
.box { flex-direction: row | row-reverse | column | column-reverse;}
flex-wrap
属性定义,如果一条轴线排不下,如何换行。
.box{ flex-wrap: nowrap | wrap | wrap-reverse; 不换行 | 换行 | 换行,第一行在上方;}
justify-content
属性定义了项目在主轴上的对齐方式
.box { justify-content: flex-start | flex-end | center | space-between | space-around;}flex-start(默认值):左对齐flex-end:右对齐center: 居中space-between:两端对齐,项目之间的间隔都相等(等比)space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
align-items
属性定义项目在交叉轴上对齐方式
.box { align-items: flex-start | flex-end | center | baseline | stretch;}baseline: 项目的第一行文字的基线对齐。stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
align-content
属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。(把轴线当作item来进行排列)
.box { align-content: flex-start | flex-end | center | space-between | space-around | stretch; }
导入外部样式
<style> @import url("flex.css");</style>
Flex元素的属性
order
属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。
.item { order: <integer>;}
flex-grow
属性定义项目的放大比例,默认为0
,即如果存在剩余空间,也不放大。
.item { flex-grow: <number>; /* 全为1 就等比放大*/}
flex-shrink
属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
.item { flex-shrink: <number>; /* 设置为0 就不进行缩放 */}
flex-basis
属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto
,即项目的本来大小。
.item { flex-basis: <length> | auto; /* 可以直接设置像素300upx */}
align-self
属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items
属性。默认值为auto
,表示继承父元素的align-items
属性,如果没有父元素,则等同于stretch
。
.item { align-self: auto | flex-start | flex-end | center | baseline | stretch;}
项目实战
tabBar
配置在page.json中:
"tabBar":{ "color":"#8F8F94", "selectedColor":"#007AFF", "backgroundColor":"#FFFFFF", "borderStyle":"black", "list":[ { "pagePath":"pages/index/index", "text":"首页", "iconPath":"static/tabBar/index1.png", "selectedIconPath":"static/tabBar/index2.png" }, { "pagePath":"pages/me/me", "text":"我的", "iconPath":"static/tabBar/mine1.png", "selectedIconPath":"static/tabBar/mine2.png" }, { "pagePath":"pages/search/search", "text":"搜索", "iconPath":"static/tabBar/search1.png", "selectedIconPath":"static/tabBar/search2.png" } ] }
swiper轮播图组件
Tips:输入"usw",可以自动生成swiper的模板
<view class="page"> <swiper :indicator-dots="true" :autoplay="true" class="carousel"> <swiper-item> <image src="../../static/swiper/swiper_1.jpg" class="carousel"></image> </swiper-item> <swiper-item> <image src="../../static/swiper/swiper_2.jpg" class="carousel"></image> </swiper-item> </swiper></view>
.carousel { width: 100%; height: 440upx; //根据图片的高度而设定}
拉取数据swiperList(json),并进行列表渲染:
<swiper-item v-for="swiper in swiperList"> <image :src="swiper.image" class="carousel"></image></swiper-item>
原生导航栏禁用
ps:小程序中的状态栏禁不掉
在pages.json中的style属性添加禁用:
"style": { "app-plus": { "titleNView":false //禁用 }}
引入组件实现全局变量
方法一
在commons/commons.js中提取全局变量:
//提取公共文件const doubanUrl ="https://images.weserv.nl"; //豆瓣电影export default{ doubanUrl //常量导出}
导入common:
import common from "../../commons/commons.js"//拼接使用"image":common.doubanUrl+"/?url=img1.doubanio.com/view/photo/l/public/p2410755737.webp",
方法二
也可以在main.js中挂载到Vue:
Vue.prototype.doubanUrl="https://images.weserv.nl";
所有页面都可以获取Vue对象(this.即可,无需import):
"image":this.doubanUrl+"/?url=//img3.doubanio.com/view/photo/l/public/p2556561071.webp",
小程序Https
需要登录之后对域名进行配置,并且只支持Https协议。
一旦允许某些域名之后,就可以不用勾选“不校验合法域名、HTTPs证书”。
scroll-view可滚动视图
通过本地json获取热门影像的数据:
// 获取热门数据getHotData(){ // 特别注意:非H5端不能用uni.request来请求本地json数据!!! // const dataRes=await this.$http({url:'/new_movies.json'}) const {subjects:dataRes}=require('../../static/mock/top250.json') // 截取10条数据 let newArr=[] for(let i=0;i<dataRes.length;i++){ if(i+this.hotCount-10<this.hotCount){ let item=dataRes[i+this.hotCount-10] // 对图片做处理 item.images.small=item.images.small.replace('https://','https://images.weserv.nl/?url=') newArr.push(item) } } this.hotData=[...this.hotData,...newArr]},
利用v-for来列表渲染动态的滚动视图(评分稍后补充):
<scroll-view scroll-x="true" class="page-block hot"> <view class="single-poster" v-for="item in hotData" :key="item.id"> <view class="poster-wapper"> <image :src="item.images.small" class="poster"></image> <view class="movie-name"> {{item.title}} </view> <view class="movie-score-wapper"> ... <view class="movie-score"> 9.0 </view> </view> </view> </view></scroll-view>
自定义组件
编写components/helloComp.vue文件:
<!-- 定义组件名称为 helloComp --><template name="helloComp"> <view> {{msg}} <!-- 动态接收 --> <input type="text" :value="myval" class="txt"/> </view></template><script> export default { //定义组件名称为 helloComp name:"helloComp", data() { return { msg:"这是自定义组件~~~" }; }, //定义组件内部使用的属性 props:{ //自定义变量,用于接收父组件(首页或者其他页面)传入的参数值 myval:{ //传入的是一个对象 type: String //定义参数类型 } } }</script><style> .txt{ color: red; }</style>
在需要使用的vue中导入:
// 导入自定义组件 import helloComp from "../../components/helloComp.vue"
在components对象中注册组件:
components:{ //在components对象中注册 helloComp, trailerStars }
在template中使用组件:
<!-- 使用自定义组件 --> <helloComp myval="Hello next~~~"></helloComp>
通过自定义组件动态显示得分
评分+星星的组件:
<template name="trailerStars"> <view> <view class="movie-score-wapper"> <image v-for="yellow in yellowScore" src="../static/icons/star-yellow.png" class="star-icon"></image> <image v-for="gray in grayScore" src="../static/icons/star-gray.png" class="star-icon"></image> <view class="movie-score" v-if="showNum==1"> {{innerScore}} </view> </view> </view></template><script> export default { name:"trailerStars", data() { return { yellowScore:0, grayScore:5 //默认显示5个灰色星星 }; }, props:{ innerScore:0, //定义外部传入的分数 showNum:0 //定义是否需要显示具体的得分数 1:显示 0:不显示 }, //生命周期,组件创建完成后被调用 created() { var tempScore=0 if(this.innerScore != null && this.innerScore != undefined && this.innerScore != ''){ tempScore=this.innerScore; } this.yellowScore=parseInt(tempScore/2); //计算黄色星星 this.grayScore=5-this.yellowScore; } }</script><style> .movie-score-wapper{ display: flex; flex-direction: row; } .star-icon{ width: 20upx; height: 20upx; margin-top: 6upx; } .movie-score{ font-size: 12px; color: grey; margin-left: 8upx; }</style>
调用组件:
<trailerStars :innerScore="item.rating.average" showNum="1"></trailerStars>
vedio组件开发
vedio组件来开发热门视频模块(hotTrailerList从猫眼电影拿):
<view class="hot-movies page-block"> <video v-for="hotTrailer in hotTrailerList" :src="hotTrailer.src" :poster="hotTrailer.poster" class="hot-movie-single" controls> </video></view>
配置相应的CSS样式:
/* 热门预告 */.hot-movies{ display: flex; flex-direction: row; flex-wrap: wrap; justify-content: space-between; //视频间隙 padding: 0 20upx 20upx 20upx;}.hot-movie-single{ width: 350upx; height: 220upx; margin-top: 10upx;}
最后
以上就是帅气店员为你收集整理的微信小程序开发入门——uni-app框架uni-appMVC与MVVN思想页面路由以及标题配置宏观讲解项目配置应用与页面的生命周期px&upx像素数据绑定事件处理条件语法Flex自适应布局(重点)项目实战的全部内容,希望文章能够帮你解决微信小程序开发入门——uni-app框架uni-appMVC与MVVN思想页面路由以及标题配置宏观讲解项目配置应用与页面的生命周期px&upx像素数据绑定事件处理条件语法Flex自适应布局(重点)项目实战所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复