微信小程序开发入门实战 (二)在熟悉vue的情况下,快速切换为小
虽然小程序和vue二者在底层核心和使用方式上差异很大,但是他们仍然有很多共同点。本篇文章旨在通过对比vue和小程序,实现快速切换开发。如果你没有vue的基础,那么你不需要看这篇。如果你需要详细的了解一下,可能需要:小程序开发指南
WXML 与 template
WXML 全称是 WeiXin Markup Language,是小程序框架设计的一套标签语言,结合小程序的基础组件、事件系统,可以构建出页面的结构。
WXML 文件后缀名是 .wxml ,打开 pages/wxml/index.wxml 文件,有过 HTML 的开发经验的读者应该会很熟悉这种代码的书写方式,简单的 WXML语句在语法上同 HTML 非常相似。
<!--pages/wxml/index.wxml-->
<text>pages/wxml/index.wxml</text>
不带有任何逻辑功能的 WXML 基本语法如下:
<!-- 在此处写注释 -->
<标签名 属性名1="属性值1" 属性名2="属性值2" ...> ...</标签名>
vue功能与之对应的是,<template>
中的内容。Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。如下:
<div id="app">
<p>{{ foo }}</p>
<!-- 这里的 `foo` 不会更新! -->
<button v-on:click="foo = 'baz'">Change it</button>
</div>
数据绑定
vue使用的是模板语法:
<span>Message: {{ msg }}</span>
<!-- 使用 JavaScript 表达式 -->
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<!-- 组件属性(需要在双引号之内,且字符串需要单引号) -->
<div v-bind:id="'list-' + id"></div>
<!-- 动态指令 -->
<a v-bind:['foo' + bar]="value"> ... </a>
WX小程序使用的是:
<view> {{ message }} </view>
<!-- 组件属性(需要在双引号之内) -->
<view id="item-{{id}}"> </view>
<!-- 控制属性(需要在双引号之内) -->
<view wx:if="{{condition}}"> </view>
Page({
data: {
message: 'Hello MINA!',
id: 0,
condition: true
}
})
数据修改
vue的数据修改如下:
data() {
return {
message: '这是一个消息'
}
}
// 数据修改
this.message = '这是一个消息...'
WX小程序的数据修改如下:
WX小程序的数据修改数据使用的是方法:Page.prototype.setData(Object data, Function callback),此方法是异步的。Page.prototype.setData(Object data, Function callback)
字段 | 类型 | 必填 | 描述 |
---|---|---|---|
data | Object | 是 | 这次要改变的数据 |
callback | Function | 否 | setData引起的界面更新渲染完毕后的回调函数 |
<view>{{ msg }}</view>
<button bindtap="clickMe">点击我</button>
Page({
data: {
msg: '这是一个消息...',
},
clickMe: function() {
this.setData({ msg: "Hello World" }, function() {
// 修改完后回调函数
})
}
})
条件渲染
vue使用的是:
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
WX小程序使用的是:
<view wx:if="{{view == 'WEBVIEW'}}"> WEBVIEW </view>
<view wx:elif="{{view == 'APP'}}"> APP </view>
<view wx:else="{{view == 'MINA'}}"> MINA </view>
列表渲染
vue使用的是:
<ul id="example-2">
<li v-for="(item, index) in array" :key="index">
{{ index }} - {{ item.message }}
</li>
</ul>
WX小程序使用的是:
<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName" wx:key="*this">
{{idx}}: {{itemName.message}}
</view>
注意:wx:key 的值以两种形式提供
1.字符串,代表在 for 循环的 array 中 item 的某个 property,该 property 的值需要是列表中唯一的字符串或数字,且不能动态改变。
2.保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。
计算属性和侦听器
vue中通过 computed
和 watch
来实现计算属性和侦听器:
computed: {
now: function () {
return Date.now()
}
}
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
在WX小程序中,则是通过 component 中的 observers
来实现的:
Component({
attached: function() {
this.setData({
numberA: 1,
numberB: 2,
})
},
observers: {
'numberA, numberB': function(numberA, numberB) {
// 在 numberA 或者 numberB 被设置时,执行这个函数
this.setData({
sum: numberA + numberB
})
}
}
})
特别地,仅使用通配符 ** 可以监听全部 setData 。
Component({
observers: {
'**': function() {
// 每次 setData 都触发
},
},
})
更多WX小程序-数据监听器看这里: WX小程序-数据监听器
事件对比
vue事件
vue 用 v-on
指令监听 DOM
事件,并在触发时运行一些 JavaScript
代码:
<button v-on:click="greet">Greet</button>
methods: {
greet: function (event) {
// `this` 在方法里指向当前 Vue 实例
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
if (event) {
alert(event.target.tagName)
}
}
}
内联语句处理器中访问原始的 DOM
事件,用特殊变量 $event
把它传入方法:
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
// ...
methods: {
warn: function (message, event) {
// 现在我们可以访问原生事件对象
if (event) {
event.preventDefault()
}
alert(message)
}
}
以及一些事件修饰符:
- .stop
- .prevent
- .capture
- .self
- .once
- .passive
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
WX小程序事件
WX小程序中,把事件分为冒泡事件和非冒泡事件:
-
冒泡事件:当一个组件上的事件被触发后,该事件会向父节点传递。
-
非冒泡事件:当一个组件上的事件被触发后,该事件不会向父节点传递。
用 bind
监听普通事件绑定:(事件绑定的写法类似于组件的属性)
<view bindtap="handleTap">
Click here!
</view>
阻止事件冒泡,我们需要使用 catch
来绑定事件。
例如在下边这个例子中,点击 inner view 会先后调用handleTap3和handleTap2(因为tap事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递),点击 middle view 会触发handleTap2,点击 outer view 会触发handleTap1。
<view id="outer" bindtap="handleTap1">
outer view
<view id="middle" catchtap="handleTap2">
middle view
<view id="inner" bindtap="handleTap3">
inner view
</view>
</view>
</view>
例子:
<view id="tapTest" data-hi="WeChat" bindtap="tapName"> Click me! </view>
Page({
tapName: function(event) {
console.log(event)
}
})
点击后,参数 event
的 log 出来的信息大致如下:
{
"type":"tap",
"timeStamp":895,
"target": {
"id": "tapTest",
"dataset": {
"hi":"WeChat"
}
},
"currentTarget": {
"id": "tapTest",
"dataset": {
"hi":"WeChat"
}
},
"detail": {
"x":53,
"y":14
},
"touches":[{
"identifier":0,
"pageX":53,
"pageY":14,
"clientX":53,
"clientY":14
}],
"changedTouches":[{
"identifier":0,
"pageX":53,
"pageY":14,
"clientX":53,
"clientY":14
}]
}
常用事件如下:
touchstart、touchmove、touchcancel、touchend、tap、longpress、transitionend、animationstart、animationiteration、animationend、touchforcechange
更多WX小程序事件看这里: WX小程序事件
表单输入绑定
vue采用 v-model
指令在表单 <input>
、<textarea>
及 <select>
元素上创建双向数据绑定。利用的是事件 v-on:input
。
<input v-model="searchText">
等价于:
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
所以,v-model
是如下代码的语法糖:
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
></custom-input>
WX小程序没有 v-model
语法糖,他是使用 bindinput
事件。
<input class="weui-input" maxlength="10" bindinput="bindKeyInput" placeholder="输入同步到view中"/>
bindKeyInput: function (e) {
this.setData({
inputValue: e.detail.value
})
},
父子组件传值
vue 中,父子组件间传值大致如下:
- 通过 Prop 向子组件传递数据
- 监听子组件事件:子组件可以通过调用内建的 $emit 方法并传入事件名称来触发一个事件,使用事件抛出一个值。
- 在组件上使用 v-model
- 通过插槽分发内容
WX小程序中,父子组件间传值大致与vue中一致,不同的是WX小程序没有 v-model
语法糖,以及不是方法 $emit()
而是方法 triggerEvent(String eventName, detail对象, 事件选项)
<!-- 在自定义组件中 -->
<button bindtap="onTap">点击这个按钮将触发“myevent”事件</button>
Component({
properties: {},
methods: {
onTap: function(){
var myEventDetail = {} // detail对象,提供给事件监听函数
var myEventOption = {} // 触发事件的选项
this.triggerEvent('myevent', myEventDetail, myEventOption)
}
}
})
WX小程序不支持函数传值,如果你需要在类似列表渲染的过程中,传递数据子项,我们需要用到 data-
,那么你可能需要这样:
<view
wx:for="{{ list }}"
wx:for-item="item"
wx:key="index"
data-item="{{ item }}"
data-index="{{ index }}"
bind:tap="clickEvent"
></view>
Page({
clickEvent(event) {
// 通过 event.currentTarget.dataset 获取 data- 的值
let item = event.currentTarget.dataset.item
let index = event.currentTarget.dataset.index
console.log(item, index)
}
})
更多WX小程序组件间通信与事件看这里: WX小程序-组件间通信与事件
Class
vue 中,class的渲染语法如下:
<div v-bind:class="[{ active: isActive }, errorClass, 'is-' + isName]"></div>
data: {
isActive: false,
errorClass: 'text-danger',
isName: 'select'
}
WX小程序中,则如下:
<view class="navbar__left-arrow-left {{ isScroll ? '' : 'is-bg' }}" ></view>
生命周期
vue是:
vue生命周期WX小程序是:
WX小程序生命周期结语
提示:后面还有精彩敬请期待,请大家关注我的专题:web前端。如有意见可以进行评论,每一条评论我都会认真对待。