HBuilderX:高效IDE,支持多语言,快速构建Web&移动应用。
下载地址:https://www.dcloud.io/hbuilderx.html 下载不需要安装即可打开使用
工具 >> 插件安装
uni-app是一个使用Vue.js开发跨平台应用的前端框架。通过编写Vue.js代码,uni-app能够将其编译到iOS、Android、Web(响应式)、以及各种小程序(如微信、支付宝、百度、头条、QQ、钉钉等)等多个平台,保证应用在这些平台上的正确运行并达到优秀体验。
网址:https://uniapp.dcloud.net.cn/tutorial/
uniapp创建目录并在网页里展示
选择uniapp模板
运行 > Chrome > 在浏览器里查看
发行 > 网站+PC
首先在 manifest.json 中配置微信小程序相关选项:
uniapp创建目录并在网页里展示
{
"mp-weixin": {
"appid": "", // 小程序的 AppID
"setting": {
"urlCheck": false, // 是否检查安全域名
"es6": true, // 是否启用 ES6 转 ES5
"postcss": true, // 是否启用 PostCSS
"minified": true, // 是否启用代码压缩
"uglifyFileName": false, // 是否混淆文件名
"lazyCodeLoading": "requiredComponents" // 开启组件按需注入
},
"usingComponents": true, // 是否启用自定义组件
"requiredComponents": [], // 预加载的组件列表
"lazyCodeLoading": "requiredComponents" // 全局开启按需注入
}
}
整理一些uniapp使用中遇到的问题和解决方法
组合式API:https://uniapp.dcloud.net.cn/tutorial/vue3-composition-api.html
底部菜单教程网址:https://uniapp.dcloud.net.cn/collocation/pages.html#tips-tabbar
"navigationBarBackgroundColor": "#fff"
"tabBar": {
"color": "#535353",
"selectedColor": "#0bb584",
"borderStyle": "white",
"list": [{
"pagePath": "pages/index/index",
"iconPath": "static/resource/images/tab_index.png",
"selectedIconPath": "static/resource/images/tab_index_seled.png",
"text": "首页"
}, {
"pagePath": "pages/order/order",
"iconPath": "static/resource/images/tab_pub.png",
"selectedIconPath": "static/resource/images/tab_pub_seled.png",
"text": "订单"
}, {
"pagePath": "pages/user/user",
"iconPath": "static/resource/images/tab_user.png",
"selectedIconPath": "static/resource/images/tab_user_seled.png",
"text": "我的"
}]
},
vue3版 动态数据案例
<template>
<view>
{{title}}
</view>
</template>
<script setup>
import { ref } from 'vue'
const title = ref('动态数据')
</script>
<style>
</style>
组件教程网址:https://uniapp.dcloud.net.cn/tutorial/vue3-components.html
推荐使用 第 2 种方法
第 1 种方法,全局引入
第 2 种方法,自动引入。创建components目录 > 右键 >
局部使用组件方法
父传子值
组件文件
<template>
<view>
<view>组件的name属性 {{name}}</view>
<view>组件的content属性 {{content}}</view>
</view>
</template>
<script setup>
import {defineProps} from 'vue'
defineProps({
name:{
type:String,
default:()=>{
return 'hello'
}
},
content:{
type:String,
default:()=>{
return '小小明'
}
}
})
</script>
网页文件
<template>
<view>
<navBar name='测试组件' :content='data'/>
</view>
</template>
<script setup>
import { ref} from 'vue'
const data = ref('动态数据')
</script>
vue3版 点击父传子值
组件
<template>
<view>
<view>组件的content属性 {{content}}</view>
<button @click="handleChange">修改content</button>
</view>
</template>
<script setup>
import {defineProps, defineEmits} from 'vue'
// defineProps(['name','content'])
defineProps({
content:{
type:String,
default:()=>{
return '默认值'
}
}
})
const emit = defineEmits(['changData'])
const handleChange=()=>{
emit('changData','修改后的数据')
}
</script>
页面
<template>
<view> order
<navBar :content='data' @changData="changData"/>
</view>
</template>
<script setup>
import { ref, reactive, computed} from 'vue'
const data = ref('动态数据 2')
const changData = (val) => {
data.value = val
}
</script>
vue3版 插槽传值方法
组件
<template>
<view>
<slot></slot>
</view>
</template>
<script setup>
</script>
页面
<template>
<view>
<case1>
<view>111</view>
<view> {{data}} </view>
<view>222</view>
</case1>
</view>
</template>
<script setup>
import { ref} from 'vue'
const data = ref('动态数据')
</script>
顶部导航
页面跳转教程网址:https://doc.dcloud.net.cn/uni-app-x/api/navigator.html#navigateback
组件
<view class="back-icon" @click="backOrHome">
<image v-if="pages > 1" src="../../static/resource/navbar/ic_back.png"></image>
<image v-else src="../../static/resource/navbar/ic_home.png"></image>
</view>
<script setup>
import { ref, onBeforeMount, defineProps } from 'vue';
//页面栈的数量
const pages = ref(getCurrentPages().length)
const backOrHome = () =>{
if(pages.value > 1){
uni.navigateBack()
}else{
uni.switchTab({
url:'/pages/index/index'
})
}
}
</script>
页面
<button style="margin-top: 130rpx;" @click="navigator">跳转到search</button>
<script setup>
import { ref } from 'vue'
const navigator = () =>{
uni.navigateTo({
url: '/pages/search/search'
})
}
</script>
创建自定义模板,创建页面时可直接使用此模板
<!-- 视图层 -->
<template>
<view class="">
</view>
</template>
<!-- 逻辑层 -->
<script setup>
import { ref } from 'vue'
</script>
<!-- 样式层 -->
<style lang="scss" scoped>
</style>
秋云 ucharts echarts 高性能跨全端图表组件
网址:https://ext.dcloud.net.cn/plugin?id=271详细说明
点击安装
<template>
<view class="container">
<qiun-data-charts
type="line"
:opts="opts"
:chartData="chartData"
/>
</view>
</template>
<script setup>
import { ref } from 'vue'
// 图表配置
const opts = ref({
color: ["#1890FF","#91CB74","#FAC858"],
padding: [15,15,0,15],
enableScroll: false,
legend: {
show: true,
position: "top",
float: "center",
padding: 5,
margin: 5
},
xAxis: {
disableGrid: true
},
yAxis: {
gridType: "dash",
dashLength: 2
},
extra: {
line: {
type: "straight",
width: 2
}
}
})
// 图表数据
const chartData = ref({
categories: ["1月","2月","3月","4月","5月","6月"],
series: [{
name: "成交量",
data: [35,8,25,37,4,20]
}]
})
</script>
<style>
.container {
padding: 20rpx;
background: #fff;
}
</style>
Vant 是一个轻量、可靠的移动端 Vue 组件库。
安装: npm install @vant/weapp
// pages.json
{
"easycom": {
"autoscan": true,
"custom": {
"^van-(.*)": "@vant/weapp/dist/$1/index"
}
}
}
vue里使用
<template>
<view>
<van-button type="primary">主要按钮</van-button>
</view>
</template>
网址:https://ask.dcloud.net.cn/article/35777 详细说明
cmd输入下面代码生成证书
inputname 为名称,可自定义,test2.keystore 为生成文件名称,可自定义
keytool -genkey -alias inputname -keyalg RSA -keysize 2048 -validity 36500 -keystore test2.keystore
导入WEB配置,选择hash和./相当路径
uniapp在测试连接服务器的时候需要配置web.config才可连接到服务器
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
</system.web>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
<!-- 允许的头部字段,包含content-type -->
<add name="Access-Control-Allow-Headers" value="Content-Type, token, access-key" />
<!-- 预检请求的缓存时间 -->
<add name="Access-Control-Max-Age" value="1728000" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
目标(明确) >> 容易(上手) >> 兴趣(驱动) >> 规律(省时省力) >> 简单(掌握更多)
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "white", //导航栏标题颜色 white和black
"navigationBarTitleText": "导航栏标题文本内容",
"navigationBarBackgroundColor": "#27BA9B",// 导航栏背景颜色
"backgroundColor": "#F8F8F8"
},
"uniIdRouter": {}
}
注意:uniapp生成微信小程序,提示启用组件按需注入4、创建 pages/user/user 和 pages/category/category 页 (选中pages >> 右键 >> 新建页面 >> 文件名称,创建目录,设置配置,选择空页模板)
uniapp项目 >> manifest.json文件 >> mp-weixin部分 >> 添加"lazyCodeLoading":"requiredComponents"
微信小程序 >> app.json文件 >> "lazyCodeLoading":"requiredComponents"
{
"tabBar": {
"color": "#535353",
"selectedColor": "#0bb584",
"backgroundColor": "#fff",
// "borderStyle": "white",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "static/tabbar/home.png",
"selectedIconPath": "static/tabbar/green/home.png",
"text": "首页"
},
{
"pagePath": "pages/category/category",
"iconPath": "static/tabbar/category.png",
"selectedIconPath": "static/tabbar/green/category.png",
"text": "分类"
},
{
"pagePath": "pages/cart/cart",
"iconPath": "static/tabbar/cart.png",
"selectedIconPath": "static/tabbar/green/cart.png",
"text": "购物车"
},
{
"pagePath": "pages/user/user",
"iconPath": "static/tabbar/user.png",
"selectedIconPath": "static/tabbar/green/user.png",
"text": "我的"
}
]
},
}
6、swiper轮播图
下载uniapp发送请求request资源003 >><script>
import Utils from './common/js/utils.js'
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
},
globalData:{
utils:Utils,
baseUrl : Utils.baseUrl,
}
}
</script>
<style>
/*每个页面公共css */
</style>
7、安装 uni-ui 扩展组件和使用,npm i @dcloudio/uni-ui <template>
<uni-card title="基础卡片" sub-title="副标题" extra="额外信息" thumbnail="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png">
<text>这是一个带头像和双标题的基础卡片,此示例展示了一个完整的卡片。</text>
</uni-card>
<uni-collapse>
<uni-collapse-item title="默认开启" :open="true">
<text>折叠内容</text>
</uni-collapse-item>
</uni-collapse>
<!-- 修改颜色 -->
<uni-countdown color="#FFFFFF" background-color="#00B26A" border-color="#00B26A" :day="1" :hour="2" :minute="30" :second="0"></uni-countdown>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>
pages.json 文件内容
{
// 组件自动引入规则
"easycom": {
// 是否开启自动扫描
"autoscan": true,
"custom": {
// uni-ui 规则如下配置
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
}
},
}
8、页面跳转(navigateTo和switchTab)<template>
<view class="">
<button style="margin-top:30rpx;" @click="navigator(1,'/pages/search/search')">跳转到search</button>
<button style="margin-top:30rpx;" @click="navigator(2,'/pages/user/user')">跳转到user</button>
</view>
</template>
<script setup>
//页面跳转
const navigator = (type,pageUrl) => {
if(type == 1){
uni.navigateTo({ // 保留当前页面,跳转到应用内的某个页面,但不能跳转到 tabBar 页面
url: pageUrl
})
} else if (type === 2) { // 跳转到 tabBar 页面,并关闭其他非 tabBar 页面。
uni.switchTab({
url: pageUrl
})
}
}
</script>
<style lang="scss" scoped>
</style>
9、request发送请求
<template>
<view class="">
<button style="margin-top:30rpx;" @click="login('test')">登录 test</button>
<button style="margin-top:30rpx;" @click="login('admin')">登录 admin</button>
</view>
</template>
<script setup>
const app = getApp()
const login = async (loginId)=>{
app.globalData.utils.request({
url: '/api/vue/admin/login/',
data: {
loginId: loginId
},
showLoading:true,
method:"POST",
success: ({data}) => { // 或 success: res => { console.log('res', res)
uni.showModal({
title:"成功提示",
content:data.msg,
showCancel:false
})
},
fail:({data}) => {
uni.showModal({
title:"失败提示",
content:data.msg,
showCancel:false
})
},
})
}
</script>
<style lang="scss" scoped>
</style>
10、案例1
下载uniapp案例1资源004 >><template>
<view class="container">
<canvas id="qrcode" canvas-id="qrcode" style="width: 200px;height: 200px;"></canvas>
<button style="margin-top:30rpx;" @click="loadUQRCode('https://xiyueta.com/')">生成二级码https://xiyueta.com/</button>
<button style="margin-top:30rpx;" @click="loadUQRCode('https://xiyueta.com/doc')">生成二级码https://xiyueta.com/doc</button>
</view>
</template>
<script setup>
import { ref} from 'vue'
import {
onLoad,onReady
} from '@dcloudio/uni-app'
import UQRCode from 'uqrcodejs'; //
const data = ref('动态数据')
onReady((options) => {
loadUQRCode('222')
})
// 生成二维码
const loadUQRCode = (url) => {
// 获取uQRCode实例
var qr = new UQRCode();
// 设置二维码内容
qr.data = url;
// 设置二维码大小,必须与canvas设置的宽高一致
qr.size = 200;
// 调用制作二维码方法
qr.make();
// 获取canvas上下文
var canvasContext = uni.createCanvasContext('qrcode', this); // 如果是组件,this必须传入
// 设置uQRCode实例的canvas上下文
qr.canvasContext = canvasContext;
// 调用绘制方法将二维码图案绘制到canvas上
qr.drawCanvas();
}
</script>
<style lang="scss" scoped>
.container{padding:10rpx;}
</style>
13、search搜索页面<template>
<view class="container">
<view class="list-cell b-b m-t" @click="navTo('个人资料')" hover-class="cell-hover" :hover-stay-time="50">
<text class="cell-tit">个人资料</text>
<text class="cell-more yticon icon-you"></text>
</view>
<view class="list-cell b-b" @click="navTo('收货地址')" hover-class="cell-hover" :hover-stay-time="50">
<text class="cell-tit">收货地址</text>
<text class="cell-more yticon icon-you"></text>
</view>
<view class="list-cell" @click="navTo('实名认证')" hover-class="cell-hover" :hover-stay-time="50">
<text class="cell-tit">实名认证</text>
<text class="cell-more yticon icon-you"></text>
</view>
<view class="list-cell m-t">
<text class="cell-tit">消息推送</text>
<switch checked color="#fa436a" @change="switchChange" />
</view>
<view class="list-cell m-t b-b" @click="navTo('清除缓存')" hover-class="cell-hover" :hover-stay-time="50">
<text class="cell-tit">清除缓存</text>
<text class="cell-more yticon icon-you"></text>
</view>
<view class="list-cell b-b" @click="navTo('关于Dcloud')" hover-class="cell-hover" :hover-stay-time="50">
<text class="cell-tit">关于Dcloud</text>
<text class="cell-more yticon icon-you"></text>
</view>
<view class="list-cell">
<text class="cell-tit">检查更新</text>
<text class="cell-tip">当前版本 1.0.5</text>
<text class="cell-more yticon icon-you"></text>
</view>
<view class="list-cell log-out-btn" @click="toLogout">
<text class="cell-tit">退出登录</text>
</view>
</view>
</template>
<script setup>
const app = getApp()
//退出登录
const toLogout = () => {
uni.showModal({
content: '确定要退出登录么',
success: (e)=>{
if(e.confirm){
setTimeout(()=>{
uni.navigateBack();
}, 200)
}
}
});
}
//点击
const navTo = (msg) => {
uni.showModal({
title:"提示",
content:msg,
showCancel:false
})
}
//switch
const switchChange = (e) =>{
let statusTip = e.detail.value ? '打开': '关闭';
uni.showModal({
title:"提示",
content:statusTip,
showCancel:false
})
}
</script>
<style lang='scss'>
page{
background: #f8f8f8;
}
.list-cell{
display:flex;
align-items:baseline;
padding: 20upx 30upx;
line-height:60upx;
position:relative;
background: #fff;
justify-content: center;
&.log-out-btn{
margin-top: 40upx;
.cell-tit{
color: #fa436a;
text-align: center;
margin-right: 0;
}
}
&.cell-hover{
background:#fafafa;
}
&.b-b:after{
left: 30upx;
}
&.m-t{
margin-top: 16upx;
}
.cell-more{
align-self: baseline;
font-size:32upx;
color:#909399;
margin-left:10upx;
}
.cell-tit{
flex: 1;
font-size: 28upx + 2upx;
color: #303133;
margin-right:10upx;
}
.cell-tip{
font-size: 28upx;
color: #909399;
}
switch{
transform: translateX(16upx) scale(.84);
}
}
</style>
16、components组件,自动引入方法:右键创建 components目录<template>
<view>
<view>组件的name属性 {{name}}</view>
<view @click="handleChange">组件的content属性 {{content}}</view>
</view>
</template>
<script setup>
import { defineProps,defineEmits } from 'vue'
defineProps({
name:{
type:String,
default:()=>{
return 'hello'
}
},
content:{
type:String,
default:()=>{
return '小小明'
}
}
})
//点击父传子值
const emit = defineEmits(['changData'])
const handleChange=()=>{
emit('changData','修改后的数据')
}
</script>
<style lang="scss" scoped>
</style>
pages\test5\test5.vue 文件内容
<template>
<view>
<myzujian name='测试组件' :content='content' @changData="changData"/>
</view>
</template>
<script setup>
import { ref} from 'vue'
const content = ref('动态数据')
const changData = (val) => {
content.value = val
}
</script>
<style lang="scss" scoped>
</style>
17、播放本地声音,
<template>
<view class="container">
<button @click="playMusic('static/sound/right0.mp3')">播放音乐right0.mp3</button>
<button @click="playMusic('static/sound/right1.mp3')">播放音乐right1.mp3</button>
<button @click="playMusic('static/sound/right2.mp3')">播放音乐right2.mp3</button>
<button @click="playMusic('static/sound/right3.mp3')">播放音乐right3.mp3</button>
<button @click="playMusic('static/sound/wrong0.mp3')">播放音乐wrong0.mp3</button>
<button @click="playMusic('static/sound/wrong1.mp3')">播放音乐wrong1.mp3</button>
<button @click="playMusic('static/sound/wrong2.mp3')">播放音乐wrong2.mp3</button>
<button @click="playMusic('static/sound/wrong3.mp3')">播放音乐wrong3.mp3</button>
</view>
</template>
<script setup>
import { onUnmounted, onMounted } from 'vue'; // 引入Vue的生命周期钩子
const app = getApp()
let audioCtx = null; // 初始化音频上下文对象为null
// 定义一个播放音乐的函数,接受一个可选的src参数
const playMusic = (src = 'static/sound/right0.mp3') => {
if (!audioCtx) {
// 如果音频上下文对象还未创建,则创建它
audioCtx = uni.createInnerAudioContext();
// 监听音频播放过程中的错误事件
audioCtx.onError((res) => {
// 打印错误信息
console.error('音频播放错误:', res.errMsg);
});
}
// 设置音频文件的源地址
audioCtx.src = app.globalData.baseUrl+src;
// 尝试播放音频
const playPromise = audioCtx.play(); // 调用play方法,并尝试获取其返回值
// 检查play方法的返回值是否为Promise,并且是否定义了catch方法
if (playPromise && typeof playPromise.catch === 'function') {
// 如果是Promise且定义了catch方法,则使用catch来捕获播放过程中可能出现的错误
playPromise.catch(error => {
// 打印播放过程中发生的错误
console.error('播放音乐时发生错误:', error);
});
}
// 注意:如果play方法不返回Promise,则上面的catch调用将不会执行,但onError监听器会捕获错误
};
// 组件挂载时自动播放音乐(可以根据需要调整)
onMounted(() => {
playMusic(); // 调用playMusic函数来播放音乐
});
// 组件卸载时停止音频播放并清理资源
onUnmounted(() => {
if (audioCtx) {
// 尝试停止音频播放(注意:在某些平台上,可能需要使用pause代替stop)
audioCtx.stop(); // 调用stop方法来停止播放
// 将音频上下文对象置为null,帮助垃圾回收
audioCtx = null;
}
});
</script>
<style lang="scss" scoped>
button{margin:10rpx;}
</style>
18、案例数一数,
下载uniapp数一数009 >>
<template>
<view class="noticeLayout">
<view class="title">
<view class="tag">
<uni-tag inverted text="置顶" type="error" />
</view>
<view class="font">这个区域填写标题</view>
</view>
<view class="info">
<view class="item">xiyueta官网</view>
<view class="item">
<uni-dateformat :date="Date.now()" format="yyyy-MM-dd hh:mm:ss"></uni-dateformat>
</view>
</view>
<view class="content">
内容区域
</view>
<view class="count">
阅读 5588
</view>
</view>
</template>
<script setup>
</script>
<style lang="scss" scoped>
.noticeLayout{
padding:30rpx;
.title{
font-size: 40rpx;
color:#111;
line-height: 1.6em;
padding-bottom:30rpx;
display: flex;
.tag{
transform: scale(0.8);
transform-origin: left center;
flex-shrink: 0;
}
.font{
padding-left:6rpx;
}
}
.info{
display: flex;
align-items: center;
color:#999;
font-size: 28rpx;
.item{
padding-right: 20rpx;
}
}
.content{
padding:50rpx 0;
}
.count{
color:#999;
font-size: 28rpx;
}
}
</style>