uniapp介绍
小结
脚手架搭建项目
-
全局安装,安装一次就可以
npm install -g @vue/cli安装报错:
卸载旧版本(npm uninstall vue-cli -g) 执行 npm cache clean --force 清除缓存 安装Vue CLI 3(npm install -g @vue/cli) npm -V 查看是否安装成功
后续运行创建命令若报错
这两个版本不一样,需要做更新
执行
npm update
或者如下图安装相同版本的:↓
- 创建项目
vue create -p dcloudio/uni-preset-vue my-project选择uniapp默认模板,my-project的名字可以修改 - 启动项目
npm run dev:mp-weixin
4.微信小程序开发者工具导入项目
到这一步的时候就说明项目创建成功了。
微信开发者工具导入以下路径的文件夹:
vscode设置左边菜单栏目大小
-
在vscode安装目录下
D:\360Downloads\Microsoft VS Code\resources\app\out\vs\workbench找到
workbench.main.css文件 -
搜索
.monaco-workbench .part>.content,之后改字体大小
解决VSCode显示“Code安装似乎损坏。请重新安装。”、标题栏显示“不受支持”
vscode设置左边菜单栏目大小最简便方式
static里面不要放样式,无法解析
样式和sass
-
支持小程序的rpx 和 h5的vw、vh
-
内置有sass的配置了,只需要 安装对应的依赖即可
npm i node-sass sass-loader -
vue组件中,在 style 标签上加入属性
<style lang='scss' >即可
Node Sass version 5.0.0 is incompatible with^4.0.0 问题解决
一、 uniapp基础-基本语法【重点】
一、数据展示
基本语法
1、在js的data中定义数据;
2、在template中通过{{ 数据 }}来显示;
3、在标签的属性上通过 :data-index= '数据' 来使用。
<view class="content">
<!-- 2.使用数据{{ msg }} -->
<view>{{ msg }}</view>
<view>{{ money }}</view>
<view>{{ isRich }}</view>
<view>{{ person.name }}</view>
<view>{{ person.skill }}</view>
<!-- 在标签上,通过属性的方式来使用数据,:data-color="color",color是red -->
<view :data-color="color"> color </view>
</view>
<script>
export default {
//1.data定义数据
data() {
return{
//存放数据
msg:"hm程序员",
//数字
money:1000,
//boll类型
isRich:false,
//对象
person:{
name:"孙悟空",
skill:"72变"
},
//颜色
color:"aqua"
},
},
}
</script>
二、数据循环
基本语法
1.通过v-for来指定要循环的数组;
2.item和index分别为 循环项 和 循环索引;
3.:key指定唯一的属性,用来提高循环效率。
<view
v-for="(item,index) in list" :key="item.id">
{{ item.text }}
</view>
<view>
<!-- list 通过 view标签显示出来 -->
<view v-for="(item,index)" in list :key="item.id">{{item.id}} --- {{item.text}} --- {{index}}</view>
</view>
<script>
export default{
//1.data定义数据
data (){
money:1000,
//数组
list: [
{
id:0,
text:"苹果"
},
{
id:1,
text:"香蕉"
},
{
id:1,
text:"樱桃"
}
]
},
}
</script>
三、条件编译
- 通过 v-if 来决定显示和隐藏,不适合做频繁的切换显示(操作标签,将标签删除)
- 通过 v-show来决定显示和隐藏,适合做频繁的切换显示(操作样式)
<view v-if="true">显示</view>
<view v-if="isShow">显示或者隐藏</view>
<view v-show="false">隐藏</view>
<view v-if="false">v-if</view>
<view v-show="false">v-if</view>
v-if和v-for不建议搭配一起使用,建议使用computed进行过滤
四、计算属性
- 可以理解为是对 data 中的数据提供了一种 加工 或者 过滤的能力
- 通过 computed 来定义计算属性
computed:{
//过滤
filterList() {
return this.list.filter(v => v.id >= 5);
},
//加工
processList() {
return this.list.map(
v => {
v.color = "red";
return v;
}
)
}
}
<view>¥{{money}}</view>
<view>{{cnMoney}}</view>
<!-- 过滤能力 -->
<view v-for="item in filterList" :key="item.id">
{{item.text}} <!-- 只显示id<0的 苹果 -->
</view>
<script>
export default{
//1.data定义数据
data (){
money:1000,
//数组
list: [
{
id:0,
text:"苹果"
},
{
id:1,
text:"香蕉"
},
]
},
//2.计算属性
computed:{
//把cnMoney看成是在data中的普通数据一样来使用即可
cnMoney(){
return "¥" +this.money
},
//过滤数组
filterList(){
//只要 ID > 0 都不要显示,v代表每个元素
return this.list.filter(v => v.id <= 0);
}
}
}
</script>
二、事件
事件的使用
- 注册事件 @click= "handleClick"
- 定义事件监听函数,需要在 "methods" 中定义
- 事件的传参
给view绑定点击事件
<view class="con">
<view @click="handleClick">点击我试试</view>
</view>
<script>
export default {
//2.在methods里面定义事件的回调
methods: {
handleClick() {
console.log("handleClick点击事件")
}
}
}
</script>
事件传参
<view class="con">
<view data-index="11" @click="handleClick(1,$event)">点击我试试1</view>
<view data-index="22" @click="handleClick(2,$event)">点击我试试2</view>
</view>
<script>
export default {
//2.在methods里面定义事件的回调
methods: {
handleClick(event) {//event事件传参
console.log(event)
}
}
}
</script>
$event截图打错字母
三、组件
组件的简单使用
组件的定义
- 在src目录下新建文件夹 components 用来存放组件
- 在 components 目录下直接新建组件 xxx.vue
组件的引入
- 在页面中引入组件 "important 组件名 from '组件路径' " 组件名不能加横线"----:img-border",采用驼峰命名:imgBorder
组件的注册
- 在页面的实例中,新增属性 components
- 属性 components 是一个对象,把组件放进去注册
export default {
components: {
//完整的写法是: 属性名:属性值,如果两者名字相同,写一个就可
imgBorder
}
}
组件的使用
- 在页面的标签中,直接使用引入的组件 "<组件></组件>"
//uniapp不推荐驼峰标签组件
<img-border></img-border>
组件传参
父向子 传递参数,通过 属性 的方式
:src="src"
- 父页面向子组件 ul-com 通过属性名 list 传递了一个数组数据
- 子组件通过 props 进行接收数据
<ul-com :list="[1,2,3,4]">
props: {
list: Array
},
引用组件的vue页面------父组件
<view class="content">
<!-- 4、使用组件 -->
<img-border :src="src1"></img-border>
<img-border :src="src2"></img-border>
</view>
<script>
//2、引入自定义组件
import imgBorder from "@/components/img-border";
export default{
data(){
return {
src1:"1.jpg",
src2:"2.jpg"
}
},
//3、注册组件
components: {
imgBorder
}
}
</script>
components里面的组件------子组件
<!-- 把props中的src看成是 data 中的变量一样来使用-->
<image class="img-border" :src="src"></image>
<script>
export default {
// 1、声明一下要接收的 父组件传递过来的属性,props是必须的
props:{
src:String, //src是父组件的属性名
}
}
</script>
子向父 传递参数,通过 触发事件 的方式
- 子组件 通过 触发事件 的方式向父组件传递数据
- 父组件 通过 监听事件 的方式来接收数据
- 子组件——
this.$emit固定写法,srcChange事件名称,this.src是要传递的参数,参数类型根据需求来;
- 父组件——事件
@srcChange触发后就执行事件回调handleSrcChange
this.src=e把点击获取的图片地址e赋值给return中的src:""
儿子img-border.vue
<template>
<!-- 把 props中的src看成是 data中的变量一样 来使用 -->
<image @click="handleClick" class="img-border" :src="src"></image>
</template>
<script>
export default {
// 声明一下要接收的 父组件传递过来的属性
props:{
src:String
},
methods:{
handleClick(){
// console.log("超人救人的时候为什么都要穿紧身衣?? 救人要紧!!");
// 子向父 传递数据 通过触发事件
// this.$emit("自定义的事件名称","要传递的参数");
this.$emit("srcChange",this.src);
}
}
}
</script>
<style>
.img-border{
border-radius: 50%;
}
</style>
父亲index.vue
<template>
<view class="content">
<!-- 4 使用组件 -->
<!-- <imgBorder></imgBorder> -->
<view>
子组件传递过来的路径:{{src}}
</view>
<img-border @srcChange="handleSrcChange" :src="src1" ></img-border>
<img-border @srcChange="handleSrcChange" :src="src2" ></img-border>
</view>
</template>
<script>
// 2 引入自定义组件
import imgBorder from "@/components/img-border";
export default {
data(){
return {
src:"",
src1:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1579239184865&di=baf9e09d575b059aea0d5ae174d683a9&imgtype=0&src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn20%2F720%2Fw1920h1200%2F20180324%2F1c34-fysnevm7014244.jpg",
src2:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1579239193423&di=fa972bcd0caf295cc995b6a3c2f42bc4&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201510%2F23%2F20151023144158_jn3P4.jpeg"
}
},
// 3 注册组件
components: {
imgBorder
},
methods:{
handleSrcChange(e){
// console.log("父组件的自定义事件被触发了");
// console.log(e);
this.src=e;
}
},
// onLoad 页面加载完毕就会触发 生命周期
onLoad(){
console.log(this.baseurl);
// 获取 globaldata
console.log(getApp().globalData.base);
// getApp().globalData.base=123;
}
};
</script>
<style lang="scss" >
</style>
使用全局数据传递参数-在组件之间分享数据
有大写
Vue的地方,都可以用来定义数据
- 通过 挂载 vue 的原型上
在vue实例页面通过
this.baseurl获取
- 通过 globalData 的方式
组件插槽
代码演示
四、生命周期
组件里面使用
onLoad是没有效果的,只能用mounted
完整生命周期
五、项目实战
-
我使用的是hbuilder,开发简便快捷。
-
hbuilder左侧选择 文件-新建-项目-uniapp项目-uni-ui,输入项目名称;
-
找到
pages,右键新建目录-home(名称自定义)-home文件夹右键新建文件index.vue;pages.json配置项目路径; -
static里面放静态资源,icon里面是tabBar里面的小图标,在App.vue中全局引入字体图标,在这里引入不能使用 @,微信小程序中样式不支持*通配符; -
在HBuilderX新建uni-app项目的模板中,选择uni ui模板 由于uni-app独特的easycom技术,可以免引用、注册,直接使用各种符合规则的vue组件。在代码区键入
u,拉出各种内置或uni ui的组件列表,选择其中一个,即可使用该组件。 光标放在组件名称上,按F1,可以查阅组件的文档。
/* base.wxss */
view,
text,
navigator,
input,
image,
swiper,
swiper-item,
scroll-view,
page {
/* 微信小程序中 不支持 * 通配符 */
margin: 0;
padding: 0;
box-sizing: border-box;
}
page{
font-size: 28rpx;
color: #666;
}
image{
width: 100%;
display: block;
}
tabBar底部导航栏配置
"color": "#8a8a8a", //字体颜色
"selectedColor": "#d4237a", //选中颜色
"backgroundColor": "#fff", //背景颜色
"position": "bottom", //位置
"borderStyle": "black", //菜单栏上面那条线颜色
iconPath//默认图标
selectedIconPath//选中之后的图标
page.json
"tabBar": {
"color": "#8a8a8a",
"selectedColor": "#d4237a",
"backgroundColor": "#fff",
"position": "bottom",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/home/index",
"text": "首页",
"iconPath": "./static/icon/_home.png",
"selectedIconPath": "./static/icon/home.png"
},
{
"pagePath": "pages/horizontal/index",
"text": "横屏",
"iconPath": "./static/icon/_img.png",
"selectedIconPath": "./static/icon/img.png"
},
{
"pagePath": "pages/video/index",
"text": "精美视频",
"iconPath": "./static/icon/_videocamera.png",
"selectedIconPath": "./static/icon/videocamera.png"
},
{
"pagePath": "pages/search/index",
"text": "搜索",
"iconPath": "./static/icon/_search.png",
"selectedIconPath": "./static/icon/search.png"
},
{
"pagePath": "pages/mine/index",
"text": "我的",
"iconPath": "./static/icon/_my.png",
"selectedIconPath": "./static/icon/my.png"
}
]
}
封装自己的异步请求
技术点:es6, promise,微信小程序API
1、新建一个utils文件夹,里面新建一个request.js文件
export default (params)=>{
// 加载中
uni.showLoading({
title:"加载中"
})
return new Promise((resolve,reject)=>{
wx.request({
...params,
success(res){
resolve(res.data);
},
fail(err){
reject(err);
},
complete(){
uni.hideLoading();
}
})
})
}
2、main.js全局引入,并且挂载到 vue的原型对象上 重命名为request(自定义名字)
import request from 'utils/request.js' //导入封装的请求文件
Vue.prototype.request = request //挂载在vue对象上
import App from './App'
import request from "./utils/request";
Vue.config.productionTip = false
Vue.prototype.request=request;
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
3、然后去页面(组件)中使用请求 因为挂载到Vue原型上了,所以在其他组件直接this.request就能相当于调用请求文件里面的方法了
vscode安装
css tree插件,选择一大段嵌套的完整代码,ctrl+shift+p可以批量生成样式结构