构建项目的结构
1.pages.json基础配置
{
"pages": [
{
"path": "pages/index/index", //前面不能加 /
"style": {
"navigationBarTitleText": "主页",
"enablePullDownRefresh":true //开启下拉刷新
}
},
{
"path": "pages/movie/movie",
"style": {
"app-plus":{ //app
"titleNView":{
"type":"transparent", //开启标题栏透明
"buttons":[ //标题栏,添加如下几个功能
{
"type":"share"
},
{
"type":"home"
},
{
"type":"forward"
}
]
}
}
}
},
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#EEFCFF",
"backgroundColor": "#EEFCFF"
},
"tabBar": {
"color": "#8a8a8a",
"selectedColor": "#d4237a",
"backgroundColor": "#fff",
"position": "bottom",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "static/images/icon-indexnor.png",
"selectedIconPath": "static/images/icon-indexnor (1).png"
}
]
}
}
2.公共样式存放处理
1.tabbar图标处理
在static下新建一个images文件夹,将要使用的图片放入其中,在pages.json文件中使用
2.公共样式处理
在static下新建一个css文件夹,将要使用的.css文件放入其中,在app.vue中使用
<style>
/*每个页面公共css */
@import './static/css/iconfont.css';
@import "./static/css/common.css"
</style>
3.使用 animate.css样式库
1.在app.css 将其注册为全局可用
@import './static/css/iconfont.css';
@import "./static/css/common.css";
@import "./static/css/animate.min.css"
- 使用 // 直接在class 中使用也可以
<view class="bck" hover-class="animate__animated animate__backInDown">
456
</view>
3.对请求的简单封装
1.在根目录下新建一个request文件夹,新建一个index.js文件
export const request = (params) => {
const baseUrl = "http://127.0.0.1:3000"
uni.showLoading({
mask:true,
title:'加载中...'
})
return new Promise((res, ref) => {
uni.request({
...params, //传进来的数据会在这儿解构,所以传入的数据必须是object
url: baseUrl + params.url,
success: (data) => {
res(data)
},
fail: (err) => {
ref(err)
},
complete:()=>{
uni.hideLoading()
}
})
})
}
2.在使用时,先导入该文件
import { request } from "../../request/index.js"
3.具体使用
request({
url:'/indexcarousel/movies/likes',
method:'get',
}).then(res=>{
// console.log(res)
this.likeslist=[...this.likeslist,...res.data.data]
})
4.组件的使用
1.在根目录下新建一个components文件夹,再创建组件
2.组件内的生命周期与vue一致
3.组件的其他操作和vue一致
5. watch && computed 的使用 (同vue)
data() {
return {
num: 0,
name:"hjjj"
}
},
watch:{
num:function(newval,oldval){
console.log(newval,oldval)
}
},
computed:{
comName:function(){
return this.name+"456"
}
},
6.如何使用vuex
1.根目录下创建 store , store下创建 index.js
2.index.js 中书写如下
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import createPersistedState from "vuex-persistedstate";
const store = new Vuex.Store({
plugins: [
createPersistedState({
storage: {
getItem: key => uni.getStorageSync(key),
setItem: (key, value) => uni.setStorageSync(key, value),
removeItem: key => uni.removeStorageSync(key)
}
})
],
state: {
name:""
},
mutations: {
setdata(state,data){
state.name=data
}
},
actions: {}
})
export default store
3.main.js 中注册
import Vue from ‘vue’
import App from './App'
//引入vuex
import store from './store'
//把vuex定义成全局组件
Vue.prototype.$store = store
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App,
//挂载
store
})
app.$mount()
4.安装插件 实现vuex 持久化
cnpm install --save vuex-persistedstate
7.uniapp 开发app实现热跟新
1.在app.js下
onShow: function() {
// #ifdef APP-PLUS
plus.runtime.getProperty(plus.runtime.appid, async function(widgetInfo) {
// console.log(widgetInfo.version, widgetInfo.name)
let data = await request("updata")
if (widgetInfo.version !== data[1].data.data.version) {
uni.showLoading({
title: "更新内容中..."
});
uni.downloadFile({
url: data[1].data.data.updataurl,
success: (downloadResult) => {
console.log(downloadResult)
if (downloadResult.statusCode === 200) {
plus.runtime.install(downloadResult.tempFilePath, {
force: false
}, function() {
uni.hideLoading();
plus.runtime.restart();
}, function(e) {
uni.hideLoading();
});
}
},
});
}
});
// #endif
},
2.修改 manifest.json中的应用版本
3.制作 wge更新包 放到服务器端 public下
4.服务端提供接口
app.get("/updata",async (req,res)=>{
res.json({
code:200,
msg:"ok",
data:{
version:'1.0.5',
updataurl:"http://139.155.253.86/uniapp_weg/__UNI__AAD09BF.wgt"
}
})
})
项目中常用的模块
轮播图
1.html部分
<swiper indicator-dots="true" autoplay="true" interval="3000" circular="true" :duration="1000">
<swiper-item class="swiperitem1" v-for="item in swiperlist" :key="item.id">
<image mode="widthFix" :src="item.url"></image>
</swiper-item>
</swiper>
2.css部分
swiper{
width: 100vw;
height:calc(100vw*440/750); //图片的高宽
swiper-item{
image{
width: 100%;
}
}
}
scroll -view 滑动模块
使用竖向滚动时,需要给 一个固定高度,通过 css 设置 height。
<scroll-view scroll-x="true" class="scrollview">
<view class="con"> //这个不能少
<view @click="goitem(item.id)" class="scrollitem" v-for="item in hotlist" :key="item.id">
<image :src="item.imgurl" mode="aspectFill" class="image1"></image>
</view>
</scroll-view>
1.scroll-view 长度 100vw
2.如果没有.con类,就可以使用下面的
scroll-view{
max-width: 100vw;
white-space: nowrap;
display: flex;
border-top: 1px solid #ccc;
image{
padding: 10upx;
width: 280upx;
height: 400upx;
}
}
3.数组预览图片效果
<scroll-view scroll-x="true" >
<image @click="proview(item.id)" :src="item.url" mode="aspectFill" v-for="item in photolist" :key="item.id"></image>
</scroll-view>
//大图预览
proview(index){
//arr就是图片的地址,数组
let arr=this.photolist.map(item=>{
return item.url
})
// console.log(arr)
uni.previewImage({
//index-1 表示当前第几个点入
current:arr[index-1],
urls:arr
})
},
异步ajax防抖操作
//关键字搜索
getsearchlist(){
var that=this
clearTimeout(that.timer) // timer定义在data中null
that.timer=setTimeout(function(){
request({
url:`/search/list?message=${that.message}`,
method:'get',
}).then(res=>{
that.searchlist=res.data.data
})
},1200)
},
页面跳转的方式
<navigator url="navigate/navigate?title=navigate" hover-class="navigator-hover">
<button type="default">跳转到新页面</button>
</navigator>
uni.navigateTo({
url:`../movie/movie?id=${e}`
})
值 说明 平台差异说明
navigate 保留当前页面,非 tabBar 的页面
redirect 非 tabBar 的页面,
switchTab 跳转的 tabBar 页面,并关闭其他所有非 tabBar 页面
reLaunch 对应 uni.reLaunch 的功能 字节跳动小程序不支持
navigateBack 对应 uni.navigateBack 的功能
exit 退出小程序,target="miniProgram"时生效 微信2.1.0+、百度2.5.2+、QQ1.4.7+
7.数据缓存
- uni.setStorage 异步接口
uni.setStorage({
key: 'storage_key',
data: 'hello',
success: function () {
console.log('success');
}
});
uni.getStorage({
key: 'storage_key',
success: function (res) {
console.log(res.data);
}
});
- uni.setStorageSync 同步接口
uni.setStorageSync('storage_key', 'hello');
let value = uni.getStorageSync('storage_key');
页面弹窗提示
1.需要主动关闭的(request请求时可以使用)
uni.showLoading({
title: '加载中'
});
setTimeout(function () {
uni.hideLoading();
}, 2000);
2.定时弹窗提示
uni.showToast({
title:"密码错误",
duration:2000
})
下方弹出功能窗,图片预览,图片上传
uni.showActionSheet({
itemList:["查看头像","从相册上传头像"],
success:res=>{
let index=res.tapIndex
let faceurl=this.userdata.userimg
let faceurllist=[this.userdata.userimg]
if(index==0){ //查看头像
uni.previewImage({
urls:faceurllist,
current:faceurl
})
}else if(index==1){
uni.chooseImage({
count: 1, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: function (res) {
uni.navigateTo({
url:`/pages/me/headerimg?url=${res.tempFilePaths[0]}`
})
}
});
}
}
})
4.可以选择确定和取消的拟态弹窗
uni.showModal({
title: '提示',
content: '这是一个模态弹窗',
success: function (res) {
if (res.confirm) {
console.log('用户点击确定');
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
7.生命周期
1.app的生命周期都只在前后台切换的时候才触发
2.页面的生命周期
onshow 会在进入时重复触发,可以用于刷新页面
8.条件编译
详细可以官网搜索 条件编译
9.组件间的传值
父组件:
引入,注册
<son color1="red" @chanage="chang" /> //如果传递的是data中的值,要使用动态绑定
//子组件传过来
chang(e){
console.log(e)
},
子组件:
props:{
color1:{
type:String,
default:'000' //必须是字符串
}
putMs(){
this.$emit("chanage","hello")
},
在vue中一般使用 props:[“color1”],也可以使用对象的方式,可以指定类型和默认值
10图片上传
//上传图片
putimage(){
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album'],
success:res=>{
// console.log(res.tempFilePaths)
let tempFilePaths=res.tempFilePaths[0]
uniCloud.uploadFile({
filePath: tempFilePaths,
success:res=>{
console.log(res)
this.src1=res.filePath
},
fail:err=>{
console.log(err)
}
})
}
})
},
删除图片,官网查uniCloud.deleteFile
自定义导航栏
1.在pages.json 中关闭原生导航栏
{
"path": "pages/index/index",
"style": {
// "navigationBarTitleText": "主页",
"enablePullDownRefresh": true,
"app-plus": {
"scrollIndicator": "none",
"titleNView":false // 关闭原生导航栏
}
}
},
2.在需要自定义导航栏的页面 自己添加头部
navheader 标签单独固定在头部
.navheader {
background-color: #f1f1f1 !important;
position: sticky;
top: 0;
left: 0;
width: 100vw;
height: 40upx;
z-index: 999;
}