环境安装
全局安装vue-cli
npm install -g @vue/cli
创建uni-app
使用正式版(对应HBuilderX最新正式版)
vue create -p dcloudio/uni-preset-vue my-project
使用alpha版(对应HBuilderX最新alpha版)
vue create -p dcloudio/uni-preset-vue#alpha my-alpha-project
此时,会提示选择项目模板,初次体验建议选择 hello uni-app
项目模板,如下所示:
运行、发布uni-app
npm run dev:%PLATFORM%
npm run build:%PLATFORM%
%PLATFORM%
可取值如下:
值 | 平台 |
---|---|
app-plus | app平台生成打包资源(支持npm run build:app-plus,可用于持续集成。不支持run,运行调试仍需在HBuilderX中操作) |
h5 | H5 |
mp-alipay | 支付宝小程序 |
mp-baidu | 百度小程序 |
mp-weixin | 微信小程序 |
mp-toutiao | 字节跳动小程序 |
mp-qq | qq 小程序 |
mp-360 | 360 小程序 |
quickapp-webview | 快应用(webview) |
quickapp-webview-union | 快应用联盟 |
quickapp-webview-huawei | 快应用华为 |
目录结构
一个uni-app工程,默认包含如下目录及文件:
┌─uniCloud 云空间目录,阿里云为uniCloud-aliyun,腾讯云为uniCloud-tcb(详见uniCloud)
│─components 符合vue组件规范的uni-app组件目录
│ └─comp-a.vue 可复用的a组件
├─hybrid App端存放本地html文件的目录,详见
├─platforms 存放各平台专用页面的目录,详见
├─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用的本地静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
├─uni_modules 存放[uni_module](/uni_modules)规范的插件。
├─wxcomponents 存放小程序组件的目录,详见
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
├─manifest.json 配置应用名称、appid、logo、版本等打包信息,详见
└─pages.json 配置页面路由、导航条、选项卡等页面类信息,详见
Tips
- 编译到任意平台时,
static
目录下的文件均会被完整打包进去,且不会编译。非static
目录下的文件(vue、js、css 等)只有被引用到才会被打包编译进去。 static
目录下的js
文件不会被编译,如果里面有es6
的代码,不经过转换直接运行,在手机设备上会报错。css
、less/scss
等资源不要放在static
目录下,建议这些公用的资源放在自建的common
目录下。- HbuilderX 1.9.0+ 支持在根目录创建
ext.json
、sitemap.json
等小程序需要的文件。
用微信小程序导入项目,注意选择dist/dev/mp-weixin这个目录
cmd进入项目路径: run dev:mp-wexin
index.html:uni-app提供的前端模板,
.gitignore:有些目录不需要编译,在这个文件中配置;
babel.config.js:js的版本处理,如es7转es5;
package.json:包的描述文件,定义快速运行的命令,如
"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch",,还有项目用到的第三方的包的依赖;
postcss.config.js:定义你该如何编译你的CSS代码的,添加什么前缀,版本等
README:给人看的,项目该怎么启动,干什么用的
tsconfig.json:当项目使用ts开发的时候,语法规范需要配置时用到
样式和sass
支持小程序的rpx和H5的vw、vh;100vw=屏幕的高度/宽度*/
内置有sass的配置了,只需要安装对应的依赖即可”npm install sass-loader node-sass“
vue组件中,在style标签上加上属性”<style lang='scaa'>"即可
<template>
<view class="content">
<view data-index="11" @click="handleClick(1,$event)">点我试试</view>
<view data-index="22" @click="handleClick(2,$event)">点我试试</view>
<input @input="handleInput">
</view>
</template>
<script>
export default {
data() {
return {
}
},
computed:{
},
onLoad() {
},
methods: {
handleClick(a,event){
console.log(a);
console.log(event);
console.log(event.currentTarget.dataset.index);
},
handleInput(){
console.log("输入中")
}
}
}
</script>
<style lang="scss">
</style>
src/compontens/img-border.vue
<template>
<image class="bor" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202002%2F14%2F20200214221000_xngjk.thumb.400_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628047106&t=40e7542bb72fb39beca59a484dca2ff0">
</template>
<script>
export default {
}
</script>
<style>
.bor{
border-radius: 50%;
}
</style>
pages/index/index.vue
<template>
<view class="content">
<imgBorder></imgBorder>
</view>
</template>
<script>
import imgBorder from '@/compontens/img-border'
export default{
components:{
imgBorder
}
}
</script>
<style lang="scss">
</style>
pages/index/index.vue
<template>
<view class="content">
<!-- <imgBorder></imgBorder> -->
<imgBorder :src="src1"></imgBorder>
<imgBorder :src="src2"></imgBorder>
</view>
</template>
<script>
import imgBorder from '@/compontens/img-border'
export default{
data(){
return {
src1:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fphoto.16pic.com%2F00%2F51%2F75%2F16pic_5175210_b.jpg&refer=http%3A%2F%2Fphoto.16pic.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628060053&t=dcee83ba366d68186a3027538e2cb816",
src2:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_match%2F0%2F12037853768%2F0.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628060053&t=5d580ff1baa2e58ab845c723ccc35e75"
}
},
components:{
imgBorder
}
}
</script>
<style lang="scss">
</style>
src/compontens/img-border.vue
<template>
<!-- <image class="bor" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202002%2F14%2F20200214221000_xngjk.thumb.400_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628047106&t=40e7542bb72fb39beca59a484dca2ff0"> -->
<!--把props中的src看成是data中的变量一样来使用-->
<image class="bor" :src="src">
</template>
<script>
export default {
//申明一下要接送的 父组件传递过来的属性
props:{
src:String
}
}
</script>
<style>
.bor{
border-radius: 50%;
}
</style>
<template>
<!-- <image class="bor" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202002%2F14%2F20200214221000_xngjk.thumb.400_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628047106&t=40e7542bb72fb39beca59a484dca2ff0"> -->
<!--把props中的src看成是data中的变量一样来使用-->
<image @click="handleClick" class="bor" :src="src">
</template>
<script>
export default {
//申明一下要接送的 父组件传递过来的属性
props: {
src: String,
},
methods: {
handleClick() {
//子向父传递数据,通过触发事件
//this.$emit("自定义的事件名称",要传递的参数)
this.$emit("srcChange", this.src);
},
},
};
</script>
<style>
.bor {
border-radius: 50%;
}
</style>
<template>
<view class="content">
<!-- <imgBorder></imgBorder> -->
{{ src }}
<imgBorder @srcChange="handleSrcChange" :src="src1"></imgBorder>
<imgBorder @srcChange="handleSrcChange" :src="src2"></imgBorder>
</view>
</template>
<script>
import imgBorder from "@/compontens/img-border";
export default {
data() {
return {
src: "",
src1: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fphoto.16pic.com%2F00%2F51%2F75%2F16pic_5175210_b.jpg&refer=http%3A%2F%2Fphoto.16pic.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628060053&t=dcee83ba366d68186a3027538e2cb816",
src2: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Finews.gtimg.com%2Fnewsapp_match%2F0%2F12037853768%2F0.jpg&refer=http%3A%2F%2Finews.gtimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1628060053&t=5d580ff1baa2e58ab845c723ccc35e75",
};
},
methods: {
handleSrcChange(e) {
this.src = e;
},
},
components: {
imgBorder,
},
};
</script>
<style>
</style>
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
//定义全局数据,通过Vue的原型来实现
Vue.prototype.baseurl="www.baidu.com"
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
},
globalData:{
baseurl:"www.baidu.com"
}
}
</script>
<style>
/*每个页面公共css */
</style>
onLoad(){
console.log(this.baseurl);
console.log(getApp().globalData.baseurl);
},
当设计表单时不确定是输入框,还是单选框,或者复选框时,可以使用slot占位标签
<template>
<view class="container">
<view class="title">标题</view>
<view class="content">内容</view>
<slot></slot>
</view>
</template>
<script>
export default {
}
</script>
<style lang="scss">
</style>
<template>
<view class="content">
<myForm>
<view class="input">
<input type="text">
<radio></radio>
<checkbox></checkbox>
</view>
</myForm>
</view>
</template>
<script>
import myForm from "@/compontents/my-form"
export default{
components:{
myForm
}
}
</script>
<style>
</style>
https://uniapp.dcloud.io/frame?id=%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f
3 uni-ui
https://uniapp.dcloud.io/component/README?id=uniui
https://www.npmjs.com/package/@dcloudio/uni-ui
安装 uni-ui
npm i @dcloudio/uni-ui 或 yarn add @dcloudio/uni-ui
在 script
中引用组件:
import {uniBadge} from '@dcloudio/uni-ui'
//import uniBadge from '@dcloudio/uni-ui/lib/uni-badge/uni-badge.vue' //也可使用此方式引入组件
export default {
components: {uniBadge}
}
在 template
中使用组件:
<uni-badge text="1"></uni-badge>
<uni-badge text="2" type="success" @click="bindClick"></uni-badge>
<uni-badge text="3" type="primary" :inverted="true"></uni-badge>
注意
CLI
引用方式,H5
端不支持在main.js
中全局注册组件,如有需求请使用(easyCom) 的方式引用组件- 使用 npm 安装的组件,默认情况下 babel-loader 会忽略所有 node_modules 中的文件 ,导致条件编译失效,需要通过配置
vue.config.js
解决:// 在整个项目的根目录创建 vue.config.js 文件,并配置如下 module.exports = { transpileDependencies: ['@dcloudio/uni-ui'] }
使用 npm + easycom
使用 npm
安装好 uni-ui
之后,需要配置 easycom
规则,让 npm
安装的组件支持 easycom
打开项目根目录下的 pages.json
并添加 easycom
节点:
// pages.json
{
"easycom": {
"autoscan": true,
"custom": {
// uni-ui 规则如下配置
"^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue"
}
},
// 其他内容
pages:[
// ...
]
}
这里安装后编译可能会出问题,需要重新安装node-sass及其依赖,才能编译成功。
解决方法一:
cnpm i node-sass sass-loader
npm run dev:mp-weixin (启动uni-app项目)
解决方法二:
或者降低npm版本 npm install npm@9 -g
再npm rebuild node-sass
如果编译没问题了,但是微信小程序界面不显示效果,可以把微信小程序开发工具重启一下。
https://www.bookstack.cn/read/uniapp-component/149772#SegmentedControl%20%E5%88%86%E6%AE%B5%E5%99%A8
uniSegmentedControl 分段器
import { uniSegmentedControl } from '@dcloudio/uni-ui';
<template>
<view>
<uni-segmented-control
:current="current"
:values="items.map(v=>v.title)"
@clickItem="onClickItem"
style-type="text"
active-color="#4cd964"
></uni-segmented-control>
<view class="content">
<view v-show="current === 0"> <home-recommend></home-recommend> </view>
<view v-show="current === 1"> <home-category></home-category> </view>
<view v-show="current === 2"> <home-new></home-new> </view>
<view v-show="current === 3"> <home-album></home-album> </view>
</view>
</view>
</template>
<script>
import homeAlbum from "./home-album";
import homeCategory from "./home-category";
import homeNew from "./home-new";
import homeRecommend from "./home-recommend";
import { uniSegmentedControl } from '@dcloudio/uni-ui';
export default {
components: {
homeAlbum,
homeCategory,
homeNew,
homeRecommend,
uniSegmentedControl,
},
data() {
return {
items: [
{title:"推荐"},
{title:"分类"},
{title:"最新"},
{title:"专辑"}
],
current: 0,
};
},
methods: {
onClickItem(e) {
if (this.current !== e.currentIndex) {
this.current = e.currentIndex;
}
},
},
};
</script>
<style>
</style>