安装全局
npm install -g @vue/cli
创建项目
vue create -p dcloudio/uni-preset-vue my-project
启动项目(微信小程序)
npm run dev:mp-weixin
微信小程序开发者工具导入项目
│ App.vue 应用配置,用来配置App全局样式以及监听
│ main.js Vue初始化入口文件
│ manifest.json 配置应用名称、appid、logo、版本等打包信息
│ pages.json 配置页面路由、导航条、选项卡等页面类信息
│ uni.scss 内置的sass变量,可以直接使用
│
|─pages
│ └─index
│ index.vue 页面组件
│
└─static 静态资源
logo.png
<template>
<view class="content">
<view class="rpx">rpxview>
<view class="vw">vwview>
<view class="sass">sassview>
view>
template>
<script>
export default {
}
script>
<style lang="scss" >
.rpx{
/* rpx 小程序中的单位 750rpx = 屏幕的宽度 */
width: 750rpx;
height: 100px;
background-color: aqua;
}
.vw{
/* vw h5单位 100vw = 屏幕的宽度 100vh = 屏幕的高度 */
width: 50vw;
height: 100px;
background-color: tan;
}
.content{
.sass{
background-color: red;
color: $uni-color-primary;
}
}
style>
1.在 js 的 data 中定义数据
2.在 template中通过 {{ 数据 }} 来显示
3.在标签的属性上通过 :data-index=‘数据’来使用
<template>
<view class="content">
<view>{{ title }}view>
<view class="num">
{{ num }}
view>
<view class="boolean">
{{ flag }}
view>
<view class="obj"> {{ obj.name }}----{{ obj.age }} view>
<view class="a" :data-color="color">colorview>
view>
template>
<script>
export default {
data() {
return {
//字符串
title: "uni-app中的数据展示",
//数字
num: 1000,
//boolean
flag: false,
//对象形式
obj: {
name: "张三",
age: 20,
},
//自定义属性
color: "aqua",
};
},
};
script>
<style lang="scss">style>
1.通过 v-for来指定要循环的数组
2.item 和 index 分别为 循环项 和 循环索引
3.:key 指定唯一的属性,用来提高循环效率
<template>
<view class="content">
<view v-for="(item,index) in list" :key="item.id">
id:{{item.id}} --- 水果:{{item.text}} --- 索引:{{index}}
view>
view>
template>
<script>
export default {
data() {
return {
// 数组
list: [
{
id: 0,
text: "",
},
{
id: 1,
text: "",
},
{
id: 2,
text: "",
},
],
};
},
};
script>
<style lang="scss">style>
1.通过 v-if 来决定显示和隐藏 不适合做频繁的切换显示
2.通过 v-show 来决定显示和隐藏 适合做频繁的切换显示,
3.注意:v-for和v-if不要一起用,循环的优先级更高
<template>
<view class="content">
<view v-if="flag">你看不到我 view>
<view v-else>你可以看到我 view>
<view v-show="flag">你看不到我 view>
view>
template>
<script>
export default {
data() {
return {
//boolean
flag: true,
};
},
};
script>
<style lang="scss">style>
1.可以理解为是对 data中的数据提供了一种加工或者过滤的能力
2.通过 computed 来定义计算属性
3.不会改变data中原有的数据,只是对data中的数据做加工处理,放回新的值,有缓存,data中的值发生变化的时候才会重新计算
<template>
<view class="content">
<view>{{ handleNum }} view>
<view v-for="(item, index) in filterList" :key="index">
id:{{ item.id }} --- 水果:{{ item.text }} --- 索引:{{ index }}
view>
view>
template>
<script>
export default {
data() {
return {
//数字
num: 1000,
// 数组
list: [
{
id: 0,
text: "",
},
{
id: 1,
text: "",
},
{
id: 2,
text: "",
},
],
};
},
//计算属性
computed: {
//把 handleNum 看成是在data中的普通的数据一样来使用即可
handleNum() {
//必须要有返回值,否则拿不到数据
return "¥" + this.num;
},
// 过滤数组
filterList() {
return this.list.filter((v) => v.id <= 0);
},
},
};
script>
<style lang="scss">style>
<template>
<view class="contain">
<view class="click" @click="handleClick">
点我试试
view>
view>
template>
<script>
export default {
//在methods里定义事件的回调
methods:{
handleClick(){
console.log(11)
}
}
};
script>
<style>style>
<template>
<view class="contain">
<view class="click" data-index="11" @click="handleClick(1, $event)">
点我试试
view>
<view class="click" data-index="22" @click="handleClick(2, $event)">
点我试试
view>
view>
template>
<script>
export default {
//在methods里定义事件的回调
methods: {
handleClick(value, e) {
console.log(value);
//获取标签上的自定义属性
const { index } = e.currentTarget.dataset;
console.log(index);
},
},
};
script>
<style>style>
组件的定义
在src目录下新建 文件夹 components 用来存放组件
在 components 目录下直接新建组件 *.vue
组件的引入
在页面中 引入 组件 “import 组件名 from ‘组件路径’”
组件的注册
在页面中的实例中,新增属性 components
属性 components 是一个对象,把组件放进去注册
组件的使用
在页面的标签中,直接使用引入的组件 “<组件>组件>”
实例
在src下新建components目录,在这个目录下创建 .vue结尾的自定义组件
<template>
<image
class="img-border"
src="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"
>image>
template>
<script>
export default {};
script>
<style>
.img-border {
border-radius: 50%;
}
style>
<template>
<view class="content">
<img-border>img-border>
view>
template>
<script>
//引入自定义组件
import imgBorder from "@/components/img-border.vue";
export default {
components: {
imgBorder
},
};
script>
<style>style>
在页面中的实例中,新增属性 components 属性 components 是一个对象,把组件放进去注册,如上所示
注意引入组件的时候不能用短杆的形式,用驼峰的形式(imgBorder),在使用的时候建议用短杆链接的形式( )
父页面向子组件 imgBorder通过属性名src传递了一个字符串
props: {
src: String //值的类型
}
<template>
<image class="img-border" :src="src">image>
template>
<script>
export default {
//用props接受父组件传递过来的值,把这个属性当中是data中的变量使用即可
props: {
src: String //值的类型
},
};
script>
<style>
.img-border {
border-radius: 50%;
}
style>
2.父组件
<template>
<view class="content">
<img-border :src="src">img-border>
view>
template>
<script>
//引入自定义组件
import imgBorder from "@/components/img-border.vue";
export default {
//父组件向子组件传值
data() {
return {
src:
"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",
};
},
components: {
imgBorder,
},
};
script>
<style>style>
子组件通过 触发事件 的方式向父组件传递数据
<template>
<view class="contain">
<image class="img-border" @click="handleClick" :src="src">image>
view>
template>
<script>
export default {
//用props接受父组件传递过来的值,把这个属性当中是data中的变量使用即可
props: {
src: String, //值的类型
},
methods: {
handleClick() {
this.$emit("change", this.src);
},
},
};
script>
<style>
.img-border {
border-radius: 50%;
}
style>
<template>
<view class="content">
<img-border @change="handleChange" :src="src1">img-border>
<img-border @change="handleChange" :src="src2">img-border>
<view class="zdf">子组件传递过来的参数{{ src }} view>
view>
template>
<script>
//引入自定义组件
import imgBorder from "@/components/img-border.vue";
export default {
//父组件向子组件传值
data() {
return {
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",
src: "",
};
},
methods: {
handleChange(e) {
console.log(e);
this.src = e
},
},
components: {
imgBorder,
},
};
script>
<style>style>
通过 Vue的原型共享数据
通过 globalData 共享数据
vuex
本地存储
1.Vue的原型共享数据 :Vue.prototype.xxx = “xxx”
2.获取方式:this.xxx
globalData 共享数据
2.1定义方式
在App.vue中定义一个globalData对象
globalData:{
base:“www.lusji.xyz”
}
2.2获取方式:getApp().globalData.base
标签其实也是数据中的一种,想实现动态的给子组件传递 标签,就可以使用插槽 slot
通过slot 来实现占位符
在子组件中定义一个要占位的slot标签插槽
结果展示
<template>
<view class="myform">
标题
<view class="slot"><slot>slot> view>
view>
template>
<script>
export default {};
script>
<style>style>
<template>
<view class="content">
<my-form>
<view class="slot">
<input type="text">
<radio>radio>
<checkbox>checkbox>
view>
my-form>
view>
template>
<script>
//引入自定义组件
import myForm from "@/components/my-form.vue";
export default {
components:{
myForm
}
};
script>
<style>style>
App.vue中的
<script>
export default {
onLaunch: function() {
console.log('App Launch app启动')
},
globalData:{
base:"www.lusji.xyz"
}
}
script>
<style>
/*每个页面公共css */
style>
2.页面中的生命周期函数
<template>
<view class="content">
<my-form>
<view class="slot">
<input type="text">
<radio>radio>
<checkbox>checkbox>
view>
my-form>
view>
template>
<script>
//引入自定义组件
import myForm from "@/components/my-form.vue";
export default {
components:{
myForm
},
onLoad(){
console.log('页面加载完成')
},
onShow(){
console.log('页面被看到');
}
};
script>
<style>style>
3.组件中的vue生命周期函数
<template>
<view class="myform">
标题
<view class="slot"><slot>slot> view>
view>
template>
<script>
export default {
mounted(){
console.log("组件中的元素加载完成");
}
};
script>
<style>style>
uni-app https://uniapp.dcloud.io/frame?id=生命周期
vue https://cn.vuejs.org/v2/guide/instance.html?#生命周期图示
微信小程序 https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/page-life-cycle.html
uni-app
支持如下应用生命周期函数:
函数名 | 说明 |
---|---|
onLaunch | 当uni-app 初始化完成时触发(全局只触发一次) |
onShow | 当 uni-app 启动,或从后台进入前台显示 |
onHide | 当 uni-app 从前台进入后台 |
onError | 当 uni-app 报错时触发 |
onUniNViewMessage | 对 nvue 页面发送的数据进行监听,可参考 nvue 向 vue 通讯 |
注意
App.vue
中监听,在其它页面监听无效。uni-app
支持如下页面生命周期函数:
函数名 | 说明 | 平台差异说明 | 最低版本 |
---|---|---|---|
onLoad | 监听页面加载,其参数为上个页面传递的数据,参数类型为Object(用于页面传参),参考示例 | ||
onShow | 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面 | ||
onReady | 监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发 | ||
onHide | 监听页面隐藏 | ||
onUnload | 监听页面卸载 | ||
onResize | 监听窗口尺寸变化 | App、微信小程序 | |
onPullDownRefresh | 监听用户下拉动作,一般用于下拉刷新,参考示例 | ||
onReachBottom | 页面上拉触底事件的处理函数 | ||
onTabItemTap | 点击 tab 时触发,参数为Object,具体见下方注意事项 | 微信小程序、百度小程序、H5、App(自定义组件模式) | |
onShareAppMessage | 用户点击右上角分享 | 微信小程序、百度小程序、字节跳动小程序、支付宝小程序 | |
onPageScroll | 监听页面滚动,参数为Object | ||
onNavigationBarButtonTap | 监听原生标题栏按钮点击事件,参数为Object | 5+ App、H5 | |
onBackPress | 监听页面返回,返回 event = {from:backbutton、 navigateBack} ,backbutton 表示来源是左上角返回按钮或 android 返回键;navigateBack表示来源是 uni.navigateBack ;详细说明及使用:onBackPress 详解 | App、H5 | |
onNavigationBarSearchInputChanged | 监听原生标题栏搜索输入框输入内容变化事件 | App、H5 | 1.6.0 |
onNavigationBarSearchInputConfirmed | 监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发。 | App、H5 | 1.6.0 |
onNavigationBarSearchInputClicked | 监听原生标题栏搜索输入框点击事件 | App、H5 | 1.6.0 |
onPageScroll
参数说明:
属性 | 类型 | 说明 |
---|---|---|
scrollTop | Number | 页面在垂直方向已滚动的距离(单位px) |
onTabItemTap
参数说明:
属性 | 类型 | 说明 |
---|---|---|
index | String | 被点击tabItem的序号,从0开始 |
pagePath | String | 被点击tabItem的页面路径 |
text | String | 被点击tabItem的按钮文字 |
注意
onNavigationBarButtonTap
参数说明:
属性 | 类型 | 说明 |
---|---|---|
index | Number | 原生标题栏按钮数组的下标 |
onBackPress
回调参数对象说明:
属性 | 类型 | 说明 |
---|---|---|
from | String | 触发返回行为的来源:‘backbutton’——左上角导航栏按钮及安卓返回键;‘navigateBack’——uni.navigateBack() 方法。 |
export default {
data() {
return {};
},
onBackPress(options) {
console.log('from:' + options.from)
}
}
注意
所有的生命周期钩子自动绑定 this
上下文到实例中,因此你可以访问数据,对 property 和方法进行运算。这意味着你不能使用箭头函数来定义一个生命周期方法 (例如 created: () => this.fetchTodos()
)。这是因为箭头函数绑定了父上下文,因此 this
与你期待的 Vue 实例不同,this.fetchTodos
的行为未定义。
类型:Function
详细:
在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
参考:生命周期图示
类型:Function
详细:
在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),property 和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el
property 目前尚不可用。
参考:生命周期图示
类型:Function
详细:
在挂载开始之前被调用:相关的 render
函数首次被调用。
该钩子在服务器端渲染期间不被调用。
参考:生命周期图示
类型:Function
详细:
实例被挂载后调用,这时 el
被新创建的 vm.$el
替换了。如果根实例挂载到了一个文档内的元素上,当 mounted
被调用时 vm.$el
也在文档内。
注意 mounted
不会保证所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以在 mounted
内部使用 vm.$nextTick:
mounted: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
})
}
该钩子在服务器端渲染期间不被调用。
参考:生命周期图示
类型:Function
详细:
数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。
参考:生命周期图示
类型:Function
详细:
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。
注意 updated
不会保证所有的子组件也都一起被重绘。如果你希望等到整个视图都重绘完毕,可以在 updated
里使用 vm.$nextTick:
updated: function () {
this.$nextTick(function () {
// Code that will run only after the
// entire view has been re-rendered
})
}
该钩子在服务器端渲染期间不被调用。
参考:生命周期图示
类型:Function
详细:
被 keep-alive 缓存的组件激活时调用。
该钩子在服务器端渲染期间不被调用。
参考:
类型:Function
详细:
被 keep-alive 缓存的组件停用时调用。
该钩子在服务器端渲染期间不被调用。
参考:
类型:Function
详细:
实例销毁之前调用。在这一步,实例仍然完全可用。
该钩子在服务器端渲染期间不被调用。
参考:生命周期图示
类型:Function
详细:
实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。
该钩子在服务器端渲染期间不被调用。
参考:生命周期图示
2.5.0+ 新增
类型:(err: Error, vm: Component, info: string) => ?boolean
详细:
当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false
以阻止该错误继续向上传播。
你可以在此钩子中修改组件的状态。因此在捕获错误时,在模板或渲染函数中有一个条件判断来绕过其它内容就很重要;不然该组件可能会进入一个无限的渲染循环。
错误传播规则
config.errorHandler
被定义,所有的错误仍会发送它,因此这些错误仍然会向单一的分析服务的地方进行汇报。errorCaptured
钩子,则它们将会被相同的错误逐个唤起。errorCaptured
钩子自身抛出了一个错误,则这个新错误和原本被捕获的错误都会发送给全局的 config.errorHandler
。errorCaptured
钩子能够返回 false
以阻止错误继续向上传播。本质上是说“这个错误已经被搞定了且应该被忽略”。它会阻止其它任何会被这个错误唤起的 errorCaptured
钩子和全局的 config.errorHandler
。以下内容你不需要立马完全弄明白,不过以后它会有帮助。
下图说明了页面 Page
实例的生命周期。
每个小程序都需要在 app.js
中调用 App
方法注册小程序实例,绑定生命周期回调函数、错误监听和页面不存在监听函数等。
详细的参数含义和使用请参考 App 参考文档 。
// app.js
App({
onLaunch (options) {
// Do something initial when launch.
},
onShow (options) {
// Do something when show.
},
onHide () {
// Do something when hide.
},
onError (msg) {
console.log(msg)
},
globalData: 'I am global data'
})
整个小程序只有一个 App 实例,是全部页面共享的。开发者可以通过 getApp
方法获取到全局唯一的 App 实例,获取App上的数据或调用开发者注册在 App
上的函数。
// xxx.js
const appInstance = getApp()
console.log(appInstance.globalData) // I am global data
对于小程序中的每个页面,都需要在页面对应的 js
文件中进行注册,指定页面的初始数据、生命周期回调、事件处理函数等。
简单的页面可以使用 Page()
进行构造。
代码示例:
//index.js
Page({
data: {
text: "This is page data."
},
onLoad: function(options) {
// 页面创建时执行
},
onShow: function() {
// 页面出现在前台时执行
},
onReady: function() {
// 页面首次渲染完毕时执行
},
onHide: function() {
// 页面从前台变为后台时执行
},
onUnload: function() {
// 页面销毁时执行
},
onPullDownRefresh: function() {
// 触发下拉刷新时执行
},
onReachBottom: function() {
// 页面触底时执行
},
onShareAppMessage: function () {
// 页面被用户分享时执行
},
onPageScroll: function() {
// 页面滚动时执行
},
onResize: function() {
// 页面尺寸变化时执行
},
onTabItemTap(item) {
// tab 点击时执行
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
},
// 事件响应函数
viewTap: function() {
this.setData({
text: 'Set some data for updating view.'
}, function() {
// this is setData callback
})
},
// 自由数据
customData: {
hi: 'MINA'
}
})
详细的参数含义和使用请参考 Page 参考文档 。
基础库 2.9.2 开始支持,低版本需做兼容处理。
页面可以引用 behaviors 。 behaviors 可以用来让多个页面有相同的数据字段和方法。
// my-behavior.js
module.exports = Behavior({
data: {
sharedText: 'This is a piece of data shared between pages.'
},
methods: {
sharedMethod: function() {
this.data.sharedText === 'This is a piece of data shared between pages.'
}
}
})
// page-a.js
var myBehavior = require('./my-behavior.js')
Page({
behaviors: [myBehavior],
onLoad: function() {
this.data.sharedText === 'This is a piece of data shared between pages.'
}
})
具体用法参见 behaviors 。
基础库 1.6.3 开始支持,低版本需做兼容处理。
Page
构造器适用于简单的页面。但对于复杂的页面, Page
构造器可能并不好用。
此时,可以使用 Component
构造器来构造页面。 Component
构造器的主要区别是:方法需要放在 methods: { }
里面。
代码示例:
Component({
data: {
text: "This is page data."
},
methods: {
onLoad: function(options) {
// 页面创建时执行
},
onPullDownRefresh: function() {
// 下拉刷新时执行
},
// 事件响应函数
viewTap: function() {
// ...
}
}
})