目录结构解释:
static
├─cache
│ └─.app-plus
│ └─tsc
│ └─app-android
├─mp-alipay
│ ├─common
│ ├─pages
│ │ └─index
│ └─static
└─mp-weixin
├─common
├─pages
│ └─index
└─static
解释:
commponents: 让用户去构建一些相应的自定义组件的时候,我们会把这些内容组件一个一个放到文件夹内,在我们项目里面,我们也会涉及到一个自定义的组件,那么我们就会把自定义的组件的一些负面内容,都会放在这个目录之下,随后,将来的组件就可以让其它页面去调用了。
pages: 我们创建的所有页面都再pages之下,index.vue 是创建项目的时候,默认的首页文件,我们所有的页面都是 *.vue,因为我们整个框架就是使用的vue.我们所有的页面只要是在pages里面,我们就需要做一个配置,其实就是我们传统意义上的路由。
static: 我们引用的一些静态资源,比如css,js,我们都可以放在static里面,让我们的页面去引用,我们页可以将资源图片放在static文件夹之内
unpackage // 打包
dev // 测试
sourcemap
tmp
app-plus -> 在我们手机端的应用
mp-alipay -> 支付宝小程序
mp-weixin -> 微信小程序
dist // 打包目录
build // 表示我们编译过的代码,我们所有的代码经过编译发布以后,都会在build里面去生成
App.vue 是一个全局的内容
main.js 这是一个项目的入口文件,我们在 main.js 文件里面,我们可以去配置统一的一个对象,数组,函数,我们完全可以去配置全局的变量,全局的变量我们可以在main.js文件里面去配置的,如何去做,我们会在后面的项目中用到,全局的Url,全局定义用户信息的一些内容,设置信息等等。我们设置是针对Vue.
manifest.json 主要是针对项目的配置,主要用于去做一个发布的,运行和调试。
uni-app应用标识(AppID -> 他可以去云端获取,官方在我们创建完项目,默认分配的,是不可更改的)
应用版本名称:1.0.0 以下是版本使用的一种方式:
如果说版本更新非常大,我们的页面布局,内容全部都做了调整,功能性的东西也比较多,那么我们的直接去将第1位累加即可(将 '1' 改为 '2')
如果说改的功能比较多,就去第2位累加即可(将 '0' 改为 '1')
如果只有一些小的改动,就去第3位累加即可(将 '0' 改位 '1')
如果我们的应用要发布到微信小程序,支付宝小程序,百度小程序的时候,我们所调用的接口,全部应该是以HTTPS协议,这样是比较安全的,这也是苹果最先提出的要求,如果不是https协议,我们的审核是不会通过的。https协议是由后端人员去做的,对于我们前端人员来讲,我们只做了解即可。
pages.json
uni.scss
JSON对象和数组的渲染
pages.json
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/Hello/Hello",
"style": {
"navigationBarTitleText": "私有页面标题"
}
},
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
// "navigationBarTitleText": "uni-app",
"navigationBarTitleText": "Hello",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"uniIdRouter": {}
}
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 */
.green {
background-color: green;
}
</style>
Hello.vue
<template>
<view class="green" style="width: 300px;height: 300px;">
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
.green {
background-color: red;
}
</style>
我们可以把一些公用的CSS提取出来,放在我们App.vue里面,全局样式,在项目页面完全可以覆盖他的样式,以Hello.vue为例,当他读取到自己页面的样式是红色的时候,Hello页面的颜色由全局的绿色变成红色,表示hello页面自己的样式会覆盖全局样式的。
main.js
manifest.json
pages.json
uni.scss
注意
编译发布过后的代码:
在 dist 目录下生成 build 文件夹: 表示我们编译过的代码,我们所有的代码经过编译发布以后,都会在 build 里面生成。
main.js 这是一个项目的入口文件
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
main.js vue3 这是一个项目的入口文件
import App from './App'
// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
// #endif
manifest.json该文件主要是针对项目的配置,主要用于去做一个发布的,运行和调式
图标的配置是在发布时使用的
App图标配置 必须是 1024*1024
App启动图配置
App SDK配置 这个一般是我们要使用第三方应用配置
比如登录 微信登录和QQ登录
App模块权限配置
H5配置
默认的端口号:8080
微信小程序
uni.scss 常量
应用的生命周期1,2
函数名 | 说明 |
---|---|
onLaunch | 当 uni-app初始化完成时触发(全局只触发一次),代表我们应用启动了,如果我们将我们应用进程终止, |
onShow | 当 uni-app启动,或从后台进入前台显示 |
onHide | 当 uni-app从前台进入后台 |
onUniNViewMessage | 对nvue页面发送的数据进行监听,可参考nvue向vue通讯 |
微信小程序的生命周期
函数名 | 说明 |
---|---|
onLaunch | 小程序初始化完成时(全局只能触发一次) |
onShow | 小程序启动,或从后台进入前台显示 |
onHide | 小程序从前台进入后台 |
onError | 小程序发生脚本错误,或api调用失败时触发时会带上错误信息 |
onPageNotFound | 小程序要打开的页面不存在时会带上页面信息回调该函数 |
其他 any | 开发者可以添加任意的函数或数据到Object参数中,用this可以访问。 |
支付宝小程序生命周期
函数名 | 说明 |
---|---|
onLaunch | 小程序启动 |
onShow | 小程序切换到前台 |
onHide | 小程序切换到后台 |
onError | 小程序出错 |
uni-app 支持如下页面生命周期函数:
函数名 | 说明 |
---|---|
onLoad | 监听页面加载,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参) |
onShow | 监听页面显示 |
onReady | 监听页面初次渲染完成 |
onHide | 监听页面隐藏 |
onUnLoad | 监听页面卸载 |
onPullDownRefresh | 监听用户下拉动作,一般用于下拉刷新 |
onReachBottom | 页面上拉触底事件的处理函数 |
onShareAppMessage | 用户点击右上角分享 |
onPageScroll | 监听页面滚动,参数为Object |
onNavigationBarButtomTap | 监听原生标题栏按钮点击事件参数为Object |
onBackPress | 监听页面返回,详细说明及使用 |
注意:生命周期对于我们外层来讲,他只是一个属性。
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("页面返回")
}
uni-app自定义返回逻辑
navigator 主要是用于做页面导航
open-type 定义跳转的方式
pages/Hello/Hello.vue
<template>
<navigator url="../index/index" open-type="navigateBack">
<view class="green" style="width: 300px;height: 300px;">
</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>
pages/index/index.vue
<!-- <template><script><style> 这三个标签在每个页面都只能存在一个 -->
<!-- template: View这层 代表的只是一个页面 -->
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text> <br />
<input type="text" :value="title" @input="change" />
</view>
<navigator url="../Hello/Hello">
<view>
I am {{student.age}} years old, <br />
I have skill 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: 18
},
skill: ["Java", "HTML", "CSS", "SpringCloud", "VUE"]
}
},
onLoad() {
},
methods: {
change(e) { // e是触发事件
var txtTitle = e.detail.value; // value是detail里面的一个属性
this.title = txtTitle; // 覆盖data(){}里面现有的数据
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
以上两个文件可以实现页面跳转
屏幕自适应尺寸
style="width: 750rpx;height: 750rpx;"
字体大小都是 px
屏幕自适应尺寸 实现代码
pages/Hello/Hello.vue
<template>
<navigator url="../index/index" open-type="navigateBack">
<view class="green" style="width: 750rpx;height: 750rpx;"></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 scoped>
.green {
background-color: red;
}
</style>
pages/index/index.vue
<!-- <template><script><style> 这三个标签在每个页面都只能存在一个 -->
<!-- template: View这层 代表的只是一个页面 -->
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text> <br />
<input type="text" :value="title" @input="change" />
</view>
<navigator url="../Hello/Hello">
<view>
I am {{student.age}} years old, <br />
I have skill 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: 18
},
skill: ["Java", "HTML", "CSS", "SpringCloud", "VUE"]
}
},
onLoad() {
},
methods: {
change(e) { // e是触发事件
var txtTitle = e.detail.value; // value是detail里面的一个属性
this.title = txtTitle; // 覆盖data(){}里面现有的数据
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
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 */
.green {
background-color: green;
}
</style>
在页面里使用 {{}} 表达式
数据绑定
{{表达式}}
我们所有的表达式都是在data(){}里面所定义的一些属性,这些属性可以是字符串,也可以是一个对象,对象里面可以包含其他类型的属性,{{表达式}}也可以是一个数组,这些内容都是在我们的data(){}里面的。
data(){}是我们MVVM里面的Model,他存储着所有的数据,这些数据都是需要在页面里面去渲染,去展示给用户的。
那么要去渲染,要去展示,我们就需要去使用依托我们的{{表达式}},所以我们在页面里面使用两个大括号{{}}去进行一个相应的使用,既然说他是一个表达式,所以表达式他会针对我们里面的属性,去做一个判断,那么他会去看他是一个整型的,还是一个数组,或是一个字符串,接下来我们来看实例。由于他是表达式,所以我们可以做相应的运算。
1, 字符串拼接
{{title + 'very good'}}
2, 表达式运算
{{student.age+1}}
3, 三元表达式可以去做判断和计算的
{{student.age >= 18 ? '成年' : '未成年'}} 该表达式表示学生的年龄大于等于18岁,则输出成年,如果小于18岁输出未成年 '? :' 代表输出
以上都是基本的一些数据绑定,数据绑定包含了字符串,对象,数组等等,这些内容都是可以再我们页面里面去进行输出的,只要是我们将相应的属性在data(){} 里面进行绑定,我们就可以在页面里面做到相应的渲染和展示。
实现代码如下:pages/index/index.vue
<!-- <template><script><style> 这三个标签在每个页面都只能存在一个 -->
<!-- template: View这层 代表的只是一个页面 -->
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title + 'very good'}}</text> <br />
<input type="text" :value="title" @input="change" />
</view>
<navigator url="../Hello/Hello">
<view>
I am {{student.age >= 18 ? '成年' : '未成年'}} years old, <br />
I have skill 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: 18
},
skill: ["Java", "HTML", "CSS", "SpringCloud", "VUE"]
}
},
onLoad() {
},
methods: {
change(e) { // e是触发事件
var txtTitle = e.detail.value; // value是detail里面的一个属性
this.title = txtTitle; // 覆盖data(){}里面现有的数据
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
v-bind指令对属性的数据绑定
navigator 我们要对这个导航进行一个动态的,进行一个使用的话,动态绑定的话,该如何去做?
v-bind : 组件的属性名
当我们要去 navigator 等标签内部去使用相应的数据绑定的时候,我们要去使用 v-bind这样一个指令,即'v-bind:组件的属性名'。组件的属性名可以是url,class,id等,所有的属性名都是包含在标签里面的。
'v-bind:组件的属性名' :表示他要和我们的data(){}做数据绑定的。
v-bind:组件的属性名 -> :组件的属性名 (缩写)
即使用 : 去替代 v-bind
表达式的这种方式 v-bind:组件的属性名 以及 :组件的属性名 这样的数据绑定的形式,其实是vue里面所使用的指令,那么在vue里面如何去使用呢?
写法
url={{url}} 这是错误写法 v-bind:url="url" 正确写法 我们使用 v-bind 指令去把我们的 url 动态的放进去 我们去组件内部去使用 v-bind 或者是 一个冒号 ':' 去进行一个动态的数据绑定。
v-bind指令对属性的数据绑定 实现代码如下:
1, pages/index/index.vue
<!-- <template><script><style> 这三个标签在每个页面都只能存在一个 -->
<!-- template: View这层 代表的只是一个页面 -->
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title + 'very good'}}</text> <br />
<input type="text" :value="title" @input="change" />
</view>
<navigator v-bind:url="url">
<view>
I am {{student.age >= 18 ? '成年' : '未成年'}} years old, <br />
I have skill 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: 18
},
skill: ["Java", "HTML", "CSS", "SpringCloud", "VUE"],
url: "../Hello/Hello"
}
},
onLoad() {
},
methods: {
change(e) { // e是触发事件
var txtTitle = e.detail.value; // value是detail里面的一个属性
this.title = txtTitle; // 覆盖data(){}里面现有的数据
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
2, pages/Hello/Hello.vue
<template>
<navigator v-bind:url="url" open-type="navigateBack">
<view class="green" style="width: 750rpx;height: 750rpx;"></view>
</navigator>
</template>
<script>
export default {
data() {
return {
url: "../index/index"
}
},
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 scoped>
.green {
background-color: red;
}
</style>
总结
在我们的标签外部,我们所有的数据绑定,都是使用 {{表达式}}
在我们的标签内部,要是动态的数据绑定,我们都要去使用 v-bind 或者他的缩写 : 也可以,和我们的具体属性写在一起,这样就可以形成一个组件内部的数据绑定。:url="url"这种方式也是贯穿我们整个项目的一个课程,在我们的实战里面都会去使用,不管是内部的还是外部的,写得还是比较多的。
比如
在template的view中去 使用
<image class="logo" :src="image"></image>
在script里面data(){}去 绑定 属性名 + 需要绑定的内容
image: "/static/logo.png"
完整代码如下:
<template>
<view class="content">
<image class="logo" :src="image"></image>
<view class="text-area">
<text class="title">{{title + 'very good'}}</text> <br />
<input type="text" :value="title" @input="change" />
</view>
<navigator v-bind:url="url">
<view>
I am {{student.age >= 18 ? '成年' : '未成年'}} years old, <br />
I have skill 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: 18
},
skill: ["Java", "HTML", "CSS", "SpringCloud", "VUE"],
url: "../Hello/Hello",
image: "/static/logo.png"
}
},
onLoad() {
},
methods: {
change(e) { // e是触发事件
var txtTitle = e.detail.value; // value是detail里面的一个属性
this.title = txtTitle; // 覆盖data(){}里面现有的数据
}
}
}
</script>
事件基础1,2,3,4
事件不管是在H5,小程序,或者说是 app 上, 只要是用户和我们的应用发生一些交互的关系,那么这些动作都是一些事件吧。
事件处理器 几乎全支持 Vue官方文档,事件处理器
事件映射表:左侧位WEB事件,右侧为'uni-app'对应的事件
WEB事件与uni-app事件映射表 所有事件都以@开头
@会有提示,这些提示都是我们组件所支持的事件
WEB事件 | 对应的uni-app事件 | 事件说明 |
---|---|---|
click | tap | -Function(Event) 组件被点击时触发 相当于WEB里面的组件单击事件 |
touchstart | touchstart | 生命周期1 -Function(Event) 手指触摸动作开始 |
touchmove | touchmove | 生命周期2-Function(Event) 手指触摸后移动 |
touchcancel | touchcancel | 生命周期4-Function(Event) 手指触摸动作被打断,如来电提醒,弹窗 |
touchend | touchend | 生命周期3-Function(Event) 手指触摸动作结束 |
tap | tap | -Function(Event) 手指触摸后马上离开 手机端事件 |
longtap | longtap | -Function(Event)手指触摸后,超过350ms再离开,如果指定了事件回调的函数并触发了这个事件,tap事件将不被触发。 |
longpress | longpress | -Function(Event) 手指触摸后,超过350ms再离开,(推荐使用longpress事件代替) |
input | input | 当我们用户在编写一些文字的时候,只要是我们的文本框中的一些内容发生了变化,随后就会触发change事件 |
change | change | |
submit | submit | 提交事件 |
blur | blur | -Function(Event) 输入框失去焦点时触发,event.detail={value:value} |
focus | focus | -Function(Event) 输入框聚焦时触发,event.detail={value:height},height为键盘高度,在基础库1.9.90起支持。 |
reset | reset | 重置事件 |
confirm | confirm | -Function(Event) 点击完成按钮触发,event.detail={value:value} |
columnchange | columnchange | 列发生变化 |
linechange | linechange | 换行或者回车发生变化就会触发linechange事件 |
error | error | 组件发生错误所捕获到的异常事件,会在error里面 |
scrolltoupper | scrolltoupper | 向上滚动会触发scrolltoupper事件 |
scrolltolower | scrolltolower | 向下滚动会触发scrolltolower事件 |
scroll | scroll | 上下滚动会触发scroll事件 |
可滚动视图组件里面相对应的事件是scroll/scrolltolower/scrolltoupper这三个事件
在pages创建一个events页面 pages/events/events.vue
<input type="text" :value="title"
@input="change"
@focus="focus" // 获得焦点
@blur="blur" // 失去焦点
/>
然后我们将这两个相应的事件到下方去编写一下,所有的一些开发人员所编写的自定义函数,我们都需要去script里面去编写,我们需要定义一个通用属性 methods:{}这是一个方法对象,我们所有的方法函数都应该写在 methods:{}这个对象里面。
解释
@input
其实就是当我们用户在编写一些文字的时候,只要是我们文本框中的一些内容,发生了变化,随后就会触发 change 事件
@confirm
如果我们在app上使用的话,App 上是会有一个键盘的,是让我们去输入一下文字的,然后在键盘的下方会有一个按键,他可能是Down,也可能是完成,如果你点击了就会触发confirm事件,这个事件值就相当于我们WEB上的一个回车键。
@click 与 @tap
click与tap这两个事件同时写的话,在浏览器里面,我们的tap事件会覆盖到click事件,
在手机端上,tap事件与click事件可以同时触发。
这就是在手机端与web端的区别与差异,如果说我们都要使用的话, 在这里我们通常建议使用tap事件。使用click事件也是没有问题。
事件基础实现代码
pages/events/event.vue
<template>
<view>
<input type="text" style="background-color: #8F8F94;height: 100rpx;" @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("长时间按住")
},
// 不在推荐使用
longtap() {
console.log("长时间触摸")
},
touchstart() {
console.log("触摸开始")
},
touchend() {
console.log("触摸结束")
},
touchmove() {
console.log("手指移动")
},
touchcancel() {
console.log("触摸被打断")
},
}
}
</script>
<style>
</style>
条件渲染 v-if 与 v-show
v-if 和 v-show 的区别:v-if 是否会在DOM中被移除,v-show是 display:none
条件渲染其实就是 if else 的判断
v-bind
vue devtools
动态地绑定一个或多个特性,或一个组件 prop 到表达式。
在绑定 class 或 style 特性时,支持其它类型的值,如数组或对象。可以通过下面的教程链接查看详情。
在绑定 prop 时,prop 必须在子组件中声明。可以用修饰符指定不同的绑定类型。
没有参数时,可以绑定到一个包含键值对的对象。注意此时 class 和 style 绑定不支持数组和对象。
参考:
https://v2.cn.vuejs.org/v2/api/#v-bind
v-cloak - string
这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none } 一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
v-else - string
不需要表达式,前一兄弟元素必须有 v-if 或 v-else-if。
v-else-if - string
前一兄弟元素必须有 v-if 或 v-else-if。
v-for - string
基于源数据多次渲染元素或模板块
v-html - string
更新元素的 innerHTML 。注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译 。如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代。
v-if - string
根据表达式的值的真假条件渲染元素。在切换时元素及它的数据绑定 / 组件被销毁并重建。如果元素是 <template> ,将提出它的内容作为条件块。 当条件变化时该指令触发过渡效果。
v-is - string
在DOM模板中使用时,模板受本机HTML解析规则的约束
v-memo - string
记住一个模板的子树。元素和组件上都可以使用。该指令接收一个固定长度的数组作为依赖值进行记忆比对。如果数组中的每个值都和上次渲染的时候相同,则整个该子树的更新会被跳过。
v-model - string
在表单控件或者组件上创建双向绑定。细节请看下面的教程链接。
v-on - string
绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。
用在普通元素上时,只能监听原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件。
在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 $event 属性:v-on:click="handle('ok', $event)"。
从 2.4.0 开始,v-on 同样支持不带参数绑定一个事件/监听器键值对的对象。注意当使用对象语法时,是不支持任何修饰器的。
v-once - string
只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。
v-pre - string
跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。
v-show - string
根据表达式之真假值,切换元素的 display CSS 属性。 当条件变化时该指令触发过渡效果。
v-slot - string
提供具名插槽或需要接收 prop 的插槽。
v-text - string
更新元素的 textContent。如果要更新部分的 textContent ,需要使用 {{ Mustache }} 插值。
从 2.4.0 开始,v-on 同样支持不带参数绑定一个事件/监听器键值对的对象。注意当使用对象语法时,是不支持任何修饰器的。
Vue v-for
触发字符:v-for
来自:代码块
v-for="(${1:item},${2:index}) in ${3:Data}"
Vue v-on Click
触发字符:v-on
来自:代码块
@click="${1:handler}(${2:arg}, $event)"
v-on click handler with arguments
hover-class - string
指定按下去的样式类。当 hover-class="none" 时,没有点击态效果
hover-start-time - number
按住后多久出现点击态,单位毫秒
hover-stay-time - number
手指松开后点击态保留时间,单位毫秒
hover-stop-propagation - boolean
指定是否阻止本节点的祖先节点出现点击态(祖先节点:指根节点到该节点路径上的所有节点都是这个节点的祖先节点)
mousemove
touchmove
条件渲染 v-if 与 v-show 实现代码
pages/vif/vif.vue
<template>
<navigator v-bind:url="url" open-type="navigateBack">
<view class="green" style="width: 750rpx;height: 750rpx;"></view>
</navigator>
<view>
<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 {
url: "../index/index",
isShow: true,
sex0: 0,
sex1: 1
}
},
methods: {
}
}
</script>
<style>
</style>
条件渲染三元运算
条件渲染三元运算 实现代码
template
<!-- 三元运算 -->
<view v-if="sex1 == 1 ? true : false">
男性
</view>
<view v-if="sex0 == 0 ? true : false">
女性
</view>
<script>
export default {
data() {
return {
url: "../index/index",
isShow: true,
sex0: 0,
sex1: 1
}
},
methods: {
}
}
</script>
列表渲染v-for的使用1,2
我们要去上面的数据进行渲染,我们就得去页面里面定义,首先需要去定义一个view,这个view专门用于写v-for这样的指令,v-for要去做循环了。
列表渲染v-for的使用1实现代码
for循环
pages/vfor/vfoe.vue
<template>
<view>
<view v-for="stuObj in studentArray">
<view>
姓名: {{stuObj.name}},年龄: {{stuObj.age}}
</view>
<view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
studentArray: [{
name: "Jack",
age: 19
},
{
name: "Steve",
age: 20
},
{
name: "Stark",
age: 18
},
{
name: "Jason",
age: 21
},
{
name: "Lucy",
age: 16
}
]
}
},
methods: {
}
}
</script>
<style>
</style>
嵌套列表渲染-
双重循环我们也可以进行编码工作
嵌套列表渲染 实现代码:
<template>
<view>
<view v-for="stuObj in studentArray">
<view>
姓名: {{stuObj.name}},年龄: {{stuObj.age}}
</view>
<view>
擅长技能:
<view v-for="sk in stuObj.skill">
{{sk}},
</view>
</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"]
}
]
}
},
methods: {
}
}
</script>
<style>
</style>
执行代码输出如下数据:
将
<view v-for="sk in stuObj.skill"> {{sk}}, </view>
改为:
<block v-for="sk in stuObj.skill"> {{sk}}, </block>
执行代码 输出如下数据:
注意:block 代表我们循环的时候,页面里面并不会把标签输出。他仅仅是将元素做一个循环。
指令key实现for循环的组件唯一性1,2
通过 v-for 这样一个指令,针对我们的数组去做循环展示,那么现在会有一个小的问题,
:key = "index" 是为了保证每一行循环的元素里面,如果说包含相应的组件的话,这个组件会和我们循环进行一个绑定,保证我们再当前页面全局的唯一性,我们去代码看看:
<template>
<scroll-view v-for="(card,index) in list" :key="index">
<view v-for="(item,itemIndex) in card" :key="itemIndex">
{{item.value}}
</view>
</scroll-view>
</template>
指令key实现for循环的组件 实现代码
<template>
<view>
<view v-for="stu in studentArray">
<checkbox :value="stu.name" checked="" /> {{stu.name}}
</view>
</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: {
}
}
</script>
<style>
</style>
执行代码返回如下数据:
push在数组的尾部进行添加
执行代码返回如下数据
unshift在数组的首部进行添加
执行代码返回如下数据
:key 保证组件和数据捆绑唯一
pages/vforkey/vforkey.vue
<template>
<view>
<view v-for="stu in studentArray" :key="stu.id">
<checkbox :value="stu.name" /> {{stu.name}}
</view>
<botton type="primary" @click="addStu">新增学生</botton>
</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>
总结
以上两级课程我们主要学习了 :key 保证组件和数据捆绑的唯一性,v-for循环其实就是列表渲染,列表渲染里面我们讲的是一个嵌套的循环,双重循环以及是一个使用 :key ,使用这样的值来保证主键与数据的唯一性,在这里,我们在编译的时候,在H5平台我们可以看一下日志。
嵌套循环的下标定义
官方的循环嵌套
<template>
<scroll-view v-for="(card,index) in list" :key="index">
<view v-for="(item,itemIndex) in card" :key="itemIndex">
{{item.value}}
</view>
</scroll-view>
</template>
我们去代码里面去看一下,在代码里面,其实我们并没有指定下标,对于每一个循环来讲,循环的时候,每一行,每一个元素,每一个item,他本身就会有一个下标,这是每一个语言里面使用for循环都会有的这种情况,在官方的文档其实也是这样说的
官方:
注意:嵌套列表渲染,必须指定不同的索引! 还需要填写 :key="xxx"
第一个index是默认的索引,如果你不写的话,他会去给我们加上一个index,是在编译的时候去进行的,下一个循环他使用了itemIndex为索引,这样的话,在循环的时候,他们的下标就不会冲突了。这个道理,在我们任何语言都是相通的。我们在嵌套循环的时候,我们的下标必须要定义为不同的。
总结:
我们在循环的时候,所有的下标必须定义成不一样的。
条件编译-上
跨端兼容
解释:
#ifdef 如果定义了,指令;标识符;判断
#ifndef 如果没有定义,或
#endif 结束条件编译
在C语言中,通过#ifdef,#ifndef,#endif的方式,为 windows,mac等不同OS编译不同的代码,uni-app参考这个思路,为uni-app提供了条件编译手段,在一个工程里优雅的完成了平台的个性化实现。
作为开发者,我们也可以去使用同样的条件编译的手段,那么可以把不同的代码编译到不同的平台,比方说:我们现在有一段代码,这一段代码,我们可以通过条件编译,仅仅只是编译到ios,Android平台,那么相应的在小程序以及H5上,这一段代码是不会出现的,那么这个就是条件编译。
条件编译和不编译,他并不代表我们代码的隐藏和显示,这是两种不同的概念
条件编译是里同特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译代不同的平台。
写法: 以 #ifdef或#ifndef加 %PLATFORM% 开头,以#endif结尾
1,#ifdef: 表示if defined 仅在某平台存在
2, #ifndef: 表示 if not defined 除了某平台内存在
3,%PLATFORM%: 表示平台名称
%PLATFORM% 可取值如下:
值 | 平台 | 说明 |
---|---|---|
APP-PLUS | 5+App | 手机端 |
APP-PLUS-NVUE | 5+APP NVUE | 手机端 |
H5 | H5 | 我们在浏览器中的web端,网页端H5 |
MP | 小程序 | 微信小程序,支付宝小程序,百度小程序 |
MP-WEIXIN | 微信小程序 | |
MP-ALIPAY | 支付宝小程序 | |
MP-BAIDU | 百度小程序 |
条件写法
写法 | 说明 |
---|---|
#ifdef APP-PLUS 需要编译的代码 #endif | 仅出现在5+APP平台下的代码 |
#ifdef H5 需要编译的代码 #endif | 除了H5平台,其他平台均存在的代码 |
#ifdef H5 || MP-WEIXIN 需要编译的代码 #endif | 仅在H5平台或微信小程序平台存在的代码 |
条件编译支持的文件
1,.vue
2, .js
3, .css
4, pages.json
5, 各预编译语言文件,如:scss,less,stylus,ts,pug
注意:条件编译是利用注释实现的,在不同语法里注释写法不一样,js使用 //注释,css 使用 /注释/ vue/nvue模板使用 <!--注释-->
API的条件编译
//#ifdef %PLATFORM% 平台持有的API实现 //#endif
代码提示
在template里面写条件编译 实现代码如下:
pages/ifcompile/ifcompile.vue
<template>
<view>
<!-- #ifdef H5 -->
<view> 只在H5编译 </view>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view>只在 IOS/Android 编译</view>
<!-- #endif -->
<!-- #ifdef MP -->
<view>只在小程序(微信,支付宝,百度)进行编译</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view>只在微信小程序进行编译</view>
<!-- #endif -->
<!-- #ifdef MP-ALIPAY -->
<view>只在支付宝小程序进行编译</view>
<!-- #endif -->
<!--#ifndef MP-->
<view>不在小程序前端编译只在 ios/android/H5编译</view>
<!--#endif-->
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>
条件编译-下
我们不仅可以在template里面写条件编译,还可以去 script/style去写条件编译
在template写条件编译 实现代码如下:
<template>
<view>
<!-- #ifdef H5 -->
<view> 只在H5编译 </view>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view>只在 IOS/Android 编译</view>
<!-- #endif -->
<!-- #ifdef MP -->
<view>只在小程序(微信,支付宝,百度)进行编译</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view>只在微信小程序进行编译</view>
<!-- #endif -->
<!-- #ifdef MP-ALIPAY -->
<view>只在支付宝小程序进行编译</view>
<!-- #endif -->
<!--#ifndef MP-->
<view>不在小程序前端编译只在 ios/android/H5编译</view>
<!--#endif-->
</view>
</template>
去 script 写条件编译 实现代码如下:
<script>
export default {
data() {
return {
}
},
onLoad() {
//#ifdef H5
console.log("只在H5编译");
//#endif
//#ifdef APP-PLUS
console.log("只在 IOS/Android 编译");
//#endif
//#ifdef MP
console.log("只在小程序(微信,支付宝,百度)进行编译");
//#endif
//#ifdef MP-WEIXIN
console.log("只在微信小程序进行编译");
//#endif
//#ifdef MP-ALIPAY
console.log("只在支付宝小程序进行编译");
//#endif
//#ifdef MP
console.log("不在小程序前端编译只在 ios/android/H5编译");
//#endif
},
methods: {
}
}
</script>
去 style写条件编译 实现代码如下:
<style>
.color {
/* #ifdef H5 */
background-color: #008000;
/* #endif */
/* #ifdef APP-PLUS */
background-color: #FF0000;
/* #endif */
/* #ifdef MP */
background-color: orange;
/* #endif */
/* #ifdef MP-WEIXIN */
background-color: orchid;
/* #endif */
/* #ifdef MP-ALIPAY */
background-color: aqua;
/* #endif */
/* #ifdef MP-HARMONY */
background-color: brown;
/* #endif */
width: 250rpx;
height: 250rpx;
}
</style>