什么是UniApp
- Union Application
- 前端框架
- 基于Vue.js
- 开发规范同小程序
- 一端开发,多端运行
开发工具
HBuilderX
框架基础
-
MVC
- M model - 模型层,数据的增删改查
- V view - 视图层,前端页面
- C controller - 控制层,处理业务
-
MVVM
- V view - HTML页面
- VM viewmodel - 调度者
- M model
index.vue <!-- <template/><script><style> 这三个标签在每个页面都只能存在一个 --> <!-- template: View --> <template> <view class="content"> <image class="logo" :src="image"></image> <view> <text class="title">{{title + ' very good'}}</text> <input type="text" :value="title" @input="change"/> </view> <navigator :url="url" > <!-- 错误写法:url="{{url}}" --> <view> I am {{student.age >= 18 ? '成年' : '未成年'}} years old. <br/> I have skills such as: {{skill[0]}},{{skill[1]}},{{skill[2]}},{{skill[3]}},{{skill[4]}} </view> </navigator> </view> </template> <script> // VM:协调者 调度器 export default { // Model: 所有的数据 data() { return { title: 'Hello NEXT学院', student: { age: 17 }, skill: ["Java", "HTML", "CSS", "Springcloud", "VUE"], url: "../hello/hello", image: "../../static/logo.png" } }, onLoad() { }, methods: { change(e) { var txtTitle = e.detail.value; this.title = txtTitle; } } } </script> <style> .content { text-align: center; height: 400upx; } .logo{ height: 200upx; width: 200upx; margin-top: 200upx; } .title { font-size: 36upx; color: #8f8f94; } </style>
-
生命周期
- 应用生命周期
App.vue <script> export default { onLaunch: function() { console.log('App Launch') }, onShow: function() { console.log('App Show') }, onHide: function() { console.log('App Hide') } } </script> <style> /*每个页面公共css */ </style>
- 页面生命周期
<template> <navigator url="../index/index" open-type="navigateBack"> <!-- <view class="green" style="width: 375px;height: 375px;"></view> --> <view class="green" style="width: 750upx;height: 750upx;"></view> </navigator> </template> <script> export default { data() { return { }; }, onLoad() { console.log("页面加载") }, onUnload() { console.log("页面关闭") }, onReady() { console.log("页面初次渲染完成") }, onShow() { console.log('页面show') }, onHide() { console.log('页面Hide') }, onShareAppMessage() { console.log('分享') }, onPageScroll() { console.log('页面滚动') }, onBackPress() { console.log('页面返回') } } </script> <style> .green { background-color: red; } </style>
- 应用生命周期
-
尺寸单位
响应式像素 upx
1upx = 750px -
数据绑定
{{表达式}}
表达式里面的内容可以进行运算
也支持三元表达式 -
路由
uni-app路由全部交给框架统一管理,开发者需要在pages.json里配置每个路由页面的路径及页面样式
- 路由跳转
uni-app 有两种路由跳转方式:使用navigator组件跳转、调用API跳转。
- 路由跳转
-
v-bind指令对属性的数据绑定
在标签内不能直接使用{{表达式}},对数据进行双向绑定的。
这个时候我们用 v-bind:组件的属性名 简写为 :组件的属性名
这个时候的属性值就可以直接写data中的属性来进行双向绑定
比如
<input type="text" v-bind:url="url"> <script> export default {data() {return {url: "../hello/hello"}}}</script>
-
事件
可以用 v-on (可以简写成@)指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码,这些js代码写在methods中。
<template> <view> <input type="text" style="background-color: #8F8F94;height: 100upx;" @input="change" @focus="focus" @blur="blur" @confirm="confirm" @click="click" @tap="tap" @longpress="longpress" @touchstart="touchstart" @touchend="touchend" @touchmove="touchmove" @touchcancel="touchcancel" /> <!-- 不推荐 @longtap="longtap" --> </view> </template> <script> export default { data() { return { }; }, methods: { change() { console.log("文本发生变化") }, focus() { console.log("获得焦点") }, blur() { console.log("失去焦点") }, confirm() { console.log("点击完成按钮/回车键") }, click() { console.log("组件单击事件") }, tap() { console.log("组件被触摸") }, longpress() { console.log("长时间按住") }, // FIX 不在推荐使用longtap longtap() { console.log("长时间触摸") }, touchstart() { console.log("触摸开始") }, touchend() { console.log("触摸结束") }, touchmove() { console.log("手指移动") }, touchcancel() { console.log("触摸被打断") }, } } </script> <style> </style>
-
条件渲染
v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染。
另一个用于根据条件展示元素的选项是 v-show 指令。不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。
支持三元运算符<template> <view> <!-- v-if v-show 的区别:前者是否会在dom中被移除,后者 display:none --> <view v-if="isShow"> now you see me </view> <view v-else> 看不见我 </view> <view v-show="isShow"> now you see me </view> <!-- 三元计算 --> <view v-if="sex1 == 1 ? true : false"> 男性 </view> <view v-if="sex0 == 0 ? true : false"> 女性 </view> <view> ======================== </view> <view v-if="sex1 == 1"> 男性 </view> <view v-else-if="sex1 == 0"> 女性 </view> <view v-else> 未知 </view> </view> </template> <script> export default { data() { return { isShow: true, sex0: 0, sex1: 2 }; } } </script> <style> </style>
-
列表渲染
<template> <view> <view v-for="(stuObj, stuIndex) in studentArray"> 当存在多重循环时,应该保证每层循环的下标是不一样的 <view>姓名: {{stuObj.name}}, 年龄: {{stuObj.age}}</view> <view> 擅长技能: <!-- <view v-for="sk in stuObj.skill"> {{sk}}, </view> --> block 不会做输出,只是会把里面内容循环相应的次数 <block v-for="(sk, skIndex) in stuObj.skill"> {{sk}}, </block> </view> </view> </view> </template> <script> export default { data() { return { studentArray: [ { name: "Jack", age: 19, skill: ["Java", "Springcloud", "VUE"] }, { name: "Steve", age: 20, skill: ["Java", "HTML", "CSS"], }, { name: "Stark", age: 18, skill: ["CSS", "Springcloud", "VUE"], }, { name: "Jason", age: 21, skill: ["Java", "VUE", "HTML"] }, { name: "Lucy", age: 16, skill: ["VUE", "HTML", "JS"] } ] }; } } </script> <style> </style>
带key值,保证循环每一项唯一
<template> <view> <view v-for="stu in studentArray" :key="stu.id"> <!-- :key 保证组件和数据捆绑唯一 --> <checkbox :value="stu.name" />{{stu.name}} </view> <button type="primary" @click="addStu">新增学生</button> </view> </template> <script> export default { data() { return { studentArray: [ { id: 1, name: "Jack", age: 19 }, { id: 2, name: "Steve", age: 20 }, { id: 3, name: "Stark", age: 18 } ] }; }, methods: { addStu() { var studentArray = this.studentArray; var newId = studentArray.length + 1; var newStu = { id: newId, name: "新生" + newId, age: 18 } // studentArray.push(newStu); // push 在数组的尾部进行添加 studentArray.unshift(newStu); // unshift 在数组的首部进行添加 } } } </script> <style> </style>
-
跨端兼容
条件编译是里用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。这些条件都是写在注释里面的
写法:以 #ifdef 或 #ifndef 加 %PLATFORM% 开头,以 #endif 结尾。
#ifdef:if defined 仅在某平台存在
#ifndef:if not defined 除了某平台均存在
%PLATFORM%:平台名称<template> <view> <!-- #ifdef H5 --> <view>只在H5编译</view> <!-- #endif --> <!-- #ifdef APP-PLUS --> <view>只在ios/安卓编译</view> <!-- #endif --> <!-- #ifdef MP --> <view>只在小程序(微信、支付宝、百度)进行编译</view> <!-- #endif --> <!-- #ifdef MP-WEIXIN --> <view>只在微信小程序进行编译</view> <!-- #endif --> <!-- #ifndef MP --> <view>不在小程序全短编译,只在ios/安卓/h5编译</view> <!-- #endif --> <view class="color"> </view> </view> </template> <script> export default { data() { return { }; }, onLoad() { // #ifdef H5 console.log("只在H5编译"); // #endif // #ifdef APP-PLUS console.log("只在APP-PLUS编译"); // #endif // #ifdef MP console.log("只在小程序(微信、支付宝、百度)进行编译"); // #endif // #ifdef MP-WEIXIN console.log("只在微信小程序编译"); // #endif } } </script> <style> .color { /* #ifdef H5 */ background-color: #008000; /* #endif */ /* #ifdef APP-PLUS */ background-color: #FF0000; /* #endif */ /* #ifdef MP */ background-color: orange; /* #endif */ width: 250upx; height: 250upx; } </style>
-
Flex 布局
- 概念
- flexible box : 弹性状布局
- 容器控制内部元素的布局定位
- css3引入的新的布局模型
- 伸缩元素,自由填充,自适应
- 优势
- 可在不同法相排列元素
- 控制元素排列的方向
- 控制元素的对齐方式
- 控制元素的之间等距
- 控制单个元素放大与缩放比例、占比、对齐方式
- 常用术语
- flex container flex容器
- flex item flex项目(元素)
- flex direction 布局方向
- 模型
- 主轴
- 交叉轴
- 容器属性
- flex-direction 设置元素的排列方向
- row 从左向右
- row-reverse 从右向左
- column 从上向下
- column 从下向上
vue文件 <template> <view class="container"> <view class="green txt"> A </view> <view class="red txt"> B </view> <view class="blue txt"> C </view> </view> </template> <script> export default { data() { return { }; } } </script> <style> @import url("flex-direction.css"); </style>
css文件 .container { /* 定义flex容器 */ display: flex; /* 设置容器内部元素的排列方向 row: 定义排列方向 从左到右 row-reverse: 从右到左 column: 从上到下 column-reverse: 从下到上 */ flex-direction: column-reverse; } .txt { font-size: 20px; width: 150upx; height: 150upx; } .red { background-color: #FF0000; } .green { background-color: #008000; } .blue { background-color: blue; }
- flex-direction 设置元素的排列方向
- flex-wrap 使容器内的元素换行
- nowrap 不换行 如果有很多的话,会把宽度进行压缩,默认
- wrap 换行 会进行自适应
- wrap-reverse
- justify-content 设置元素在主轴上的对齐方式
- flex-start
- flex-end
- center
- space-between
- space-around
.container { /* 定义flex容器 */ display: flex; /* 设置容器内部元素的排列方向 row: 定义排列方向 从左到右 row-reverse: 从右到左 column: 从上到下 column-reverse: 从下到上 */ flex-direction: column; /* 设置元素在主轴上的对其方式 flex-start: (默认)左对齐 或者 向上对齐 flex-end: 右对齐 或者 向下对齐 center: 居中对齐 space-between: 两端对齐,元素之间平均等分剩余空白间隙部分 space-around: 元素两边平均等分剩余空白间隙部分,最左(上)或最右(下)和元素之间距离是1:2 */ justify-content: space-between; height: 800upx; background-color: #FFC0CB; } .txt { font-size: 20px; width: 150upx; height: 150upx; } .red { background-color: #FF0000; } .green { background-color: #008000; } .blue { background-color: blue; } .yellow { background-color: yellow; } ```
- align-items 设置元素在交叉轴上的对齐方式
- flex-start
- flex-end
- center
- baseline
- stretch(默认)
.container { /* 定义flex容器 */ display: flex; /* 设置容器内部元素的排列方向 row: 定义排列方向 从左到右 row-reverse: 从右到左 column: 从上到下 column-reverse: 从下到上 */ flex-direction: row; /* 设置容器中元素在交叉轴上的对齐方式 stretch:(默认)当元素的高度没有设置,则元素的高度会拉伸至容器高度一致 flex-start: 在交叉轴上向起点位置(向上/向左)对齐 flex-end: 在交叉轴上向结束位置(向下/向右)对齐 center: 居中对齐 baseline: 保证元素中的文字在同一条基准线(保证每个文字都在同一条线上) */ align-items: baseline; height: 800upx; background-color: #FFC0CB; } .txt { font-size: 20px; width: 150upx; height: 150upx; } .red { background-color: #FF0000; } .green { background-color: #008000; } .blue { background-color: blue; }
- align-content 设置轴线的对齐方式 (轴线当作元素) 在多轴线有效
- flex-start
- flex-end
- center
- stretch
- space-between
- space-around
.container { /* 定义flex容器 */ display: flex; /* 设置容器内部元素的排列方向 row: 定义排列方向 从左到右 row-reverse: 从右到左 column: 从上到下 column-reverse: 从下到上 */ flex-direction: column; /** nowrap: 不换行 wrap: 换行 wrap-reverse: 逆向换行 */ flex-wrap: wrap; /* 当轴线超过1条的时候,flex容器可以把多条轴线视为元素对待,可以进行对齐 center:居中 flex-start: 向左对齐 flex-end: 向右对齐 stretch: 当宽度width没有设置的时候,轴线可以被拉伸 space-between: 两端对齐,元素之间的空白等比切分 space-around: 轴线两边的空白等比切分 */ align-content: space-around; height: 600upx; background-color: gray; } .txt { font-size: 20px; width: 150upx; height: 150upx; } .red { background-color: #FF0000; } .green { background-color: #008000; } .blue { background-color: blue; } .orange { background-color: orange; } .pink { background-color: pink; } .yellow { background-color: yellow; }
- 概念
-
元素的属性
- order 控制元素的顺序 在css中设置 从设置的从小到大排序
- flex-grow 控制元素的放大比例 如果存在空余空间
- flex-shrink 控制元素的缩小比例
- flex-basis 设置元素固定或自动空间占比 不会把全部剩余空间给吃掉 可以放大,也可以进行缩放
- align-self 重写align-items父属性
.container { /* 定义flex容器 */ display: flex; /* 设置容器内部元素的排列方向 row: 定义排列方向 从左到右 row-reverse: 从右到左 column: 从上到下 column-reverse: 从下到上 */ flex-direction: row; } .txt { font-size: 20px; width: 150upx; height: 150upx; } /* order: 用于设置flex容器内部的每个元素的排列顺序,默认是0 排序规则,由小到大 flex-grow: 用于设置元素的放大比例,默认为0 如果为0,则不放大 flex-shrink: 用于定义属性的缩放比例,默认为1 设置为0的时候,不进行缩放 */ .red { background-color: #FF0000; /* order: 0; */ /* flex-grow: 2; */ flex-shrink: 0; flex-basis: 150upx; } .green { background-color: #008000; /* order: 2; */ /* flex-grow: 1; */ flex-shrink: 0; } .blue { background-color: blue; /* order: 1; */ /* flex-grow: 1; */ flex-shrink: 0; }
.container { /* 定义flex容器 */ display: flex; /* 设置容器内部元素的排列方向 row: 定义排列方向 从左到右 row-reverse: 从右到左 column: 从上到下 column-reverse: 从下到上 */ flex-direction: row; /* 设置容器中元素在交叉轴上的对齐方式 stretch:(默认)当元素的高度没有设置,则元素的高度会拉伸至容器高度一致 flex-start: 在交叉轴上向起点位置(向上/向左)对齐 flex-end: 在交叉轴上向结束位置(向下/向右)对齐 center: 居中对齐 baseline: 保证元素中的文字在同一条基准线(保证每个文字都在同一条线上) */ align-items: baseline; height: 800upx; background-color: #FFC0CB; } .txt { font-size: 20px; width: 150upx; height: 150upx; } .txt2 { font-size: 20px; width: 150upx; } .red { background-color: #FF0000; /* 重写容器中元素在交叉轴上的对齐方式 auto: 默认,表示继承父级元素的align-items属性 stretch:当元素的高度没有设置,则元素的高度会拉伸至容器高度一致 flex-start: 在交叉轴上向起点位置(向上/向左)对齐 flex-end: 在交叉轴上向结束位置(向下/向右)对齐 center: 居中对齐 baseline: 保证元素中的文字在同一条基准线(保证每个文字都在同一条线上) */ align-self: stretch; } .green { background-color: #008000; } .blue { background-color: blue; }