uni-app入門教程(3)資料繫結、樣式繫結和事件處理
文章目錄
一、模板語法及資料繫結
1.宣告和渲染變數
在使用變數前,需要先宣告,一般在data塊中進行宣告,如hello uniapp專案中index.vue中定義的title變數如下:
data() {
return {
title: 'Hello'
}
},
可以在script語言塊的data塊中定義多個變數,並且在template語言塊的檢視中用{{}}
呼叫變數,並且可以繫結多種型別的變數,包括基本資料型別、陣列等。
先測試基礎資料呼叫,index.vue如下:
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<view class="red">
hello-{{name}}
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello',
name: 'Corley'
}
},
onLoad() {
console.log('index onload')
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
}
}
</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>
顯示:
可以看到,定義的title和name變數渲染到了檢視中。
需要注意,宣告的變數都是響應式的,即檢視中渲染的結果與變數本身是繫結的,會同步變化,index.vue如下:
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<view class="red">
hello-{{name}}-{{age}}
</view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
title: 'Hello',
name: 'Corley',
age: 18
}
},
onLoad() {
_self = this;
setTimeout(function(){
_self.age = 20
}, 3000);
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
}
}
</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>
顯示:
可以看到,在進入onLoad
階段後,渲染的age變數也發生變化,變為20。
還可以對陣列進行資料繫結,可以獲取陣列的單個元素及其屬性,如下:
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<view class="red">
{{students[0]}}<br>
{{students[0].name}}
</view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
title: 'Hello',
name: 'Corley',
age: 18,
students: [{
name: "張三",
age: 18
},
{
name: "李四",
age: 20
}
]
}
},
onLoad() {
_self = this;
setTimeout(function() {
_self.age = 20
}, 3000);
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
}
}
</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-for進行遍歷。
index.vue如下:
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<view v-for="(item, index) in students">
{{index}} - {{item.name}} : {{item.age}}
</view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
title: 'Hello',
name: 'Corley',
age: 18,
students: [{
name: "張三",
age: 18
},
{
name: "李四",
age: 20
}
]
}
},
onLoad() {
_self = this;
setTimeout(function() {
_self.age = 20
}, 3000);
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
}
}
</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.條件渲染
條件渲染是指滿足某個條件才渲染某個元素,使用v-if。
如下:
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<view v-if="show1">
show1...
</view>
<view v-if="show2">
show2...
</view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
title: 'Hello',
name: 'Corley',
age: 18,
show1: true,
show2: false
}
},
onLoad() {
_self = this;
setTimeout(function() {
_self.age = 20
}, 3000);
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
}
}
</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-if中傳的值判斷是否渲染。
:hidden
屬性用來定義是否隱藏某個元素,如下:
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<view :hidden="show1">
show1...
</view>
<view :hidden="show2">
show2...
</view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
title: 'Hello',
name: 'Corley',
age: 18,
show1: true,
show2: false
}
},
onLoad() {
_self = this;
setTimeout(function() {
_self.age = 20
}, 3000);
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
}
}
</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-if
和:hidden
的效果相反,但是原理上還是有一定區別:
v-if
是根據條件決定是否渲染,:hidden
會渲染但根據條件決定是否展示,可以根據具體需要進行選擇。
二、class和style繫結
前面已經提到過,可以在template語言塊的某個標籤中通過style屬性直接定義樣式,也可以在style語言塊中通過選擇器定義樣式,再在template語言塊中使用。
為節約效能,可以將Class與Style的表示式通過compiler硬編碼到uni-app中,通過條件判斷來決定是否顯示某個樣式。
1.class語法
class支援的語法方式如下:
<!-- 1 -->
<view class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }">111</view>
<!-- 2 -->
<view class="static" v-bind:class="[isActive ? activeClass : '', errorClass]">222</view>
<!-- 3 -->
<view class="static" v-bind:class="[{ active: isActive }, errorClass]">333</view>
<!-- 4 -->
<view :class="{ active: isActive }">333</view>
<!-- 5 -->
<view class="static" :class="[activeClass, errorClass]">3555</view>
其中,前3種為完整形式,後2種為簡寫形式;
isActive ? activeClass : ''
為三元運算子。
index.vue如下:
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<view :class="{'red' : isRed}">
class bind 2...
</view>
<view :class="[isBlue ? 'blue' : 'red']">
class bind 3...
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello',
name: 'Corley',
age: 18,
isRed: true,
isBlue: true
}
},
onLoad() {
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
}
}
</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;
}
.blue {
color: #007AFF;
}
</style>
顯示:
可以看到,在進行編譯選然後,微信開發者工具中wxml顯示的是被渲染後的class值。
2.style語法
style 支援的語法如下:
<!-- 1 -->
<view v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }">111</view>
<!-- 2 -->
<view v-bind:style="[{ color: activeColor, fontSize: fontSize + 'px' }]">222</view>
<!-- 3 -->
<view :style="{ color: activeColor, fontSize: fontSize + 'px' }">333</view>
<!-- 4 -->
<view :style="[{ color: activeColor, fontSize: fontSize + 'px' }]">444</view>
其中,前2種為完整形式,後2種為簡寫形式。
index.vue如下:
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<view style="font-size: 10px;">
style static...
</view>
<view :style="{fontSize: fontSize+'px'}">
class dynamic...
</view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
title: 'Hello',
name: 'Corley',
age: 18,
fontSize: 20
}
},
onLoad() {
_self = this;
setTimeout(function(){
_self.fontSize = 30;
}, 3000)
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
}
}
</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;
}
.blue {
color: #007AFF;
}
</style>
顯示:
顯然,樣式可以動態發生變化。
需要注意,uni-app不支援 Vue官方文件中Class 與 Style 繫結 中的 classObject 和 styleObject 語法,但是可以用 computed 方法生成 class 或者 style 字串,插入到頁面中,如下:
<template>
<view>
<!-- 支援 -->
<view class="container" :class="computedClassStr"></view>
<view class="container" :class="{active: isActive}"></view>
<!-- 不支援 -->
<view class="container" :class="computedClassObject"></view>
</view>
</template>
3.案例–動態選單切換
本案例實現動態切換導航欄。
先展示橫向排列的導航欄,index.vue如下:
<template>
<view>
<view v-for="(item, index) in menus" class="menu">
{{item}}
</view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
menus: [
'新聞', '汽車', '讀書'
]
}
},
onLoad() {
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
}
}
</script>
<style>
.menu {
padding: 10px;
float: left;
margin: 5px;
line-height: 36px;
}
</style>
顯示:
此時已經可以將導航欄橫向展示了。
再實現當前的導航欄顯示不一樣的顏色,如下:
<template>
<view>
<view v-for="(item, index) in menus" class="menu" :class="[activeIndex==index?'menuActive':'']">
{{item}}
</view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
menus: [
'新聞', '汽車', '讀書'
],
activeIndex: 0
}
},
onLoad() {
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
}
}
</script>
<style>
.menu {
padding: 10px;
float: left;
margin: 5px;
line-height: 36px;
}
.menuActive {
color: #FF0000 !important;
}
</style>
顯示:
此時,第1個導航欄變為紅色。
進一步實現點選時,顏色動態變化,如下:
<template>
<view>
<view v-for="(item, index) in menus" class="menu" :class="[activeIndex==index?'menuActive':'']" @click="menuClick" :id="index">
{{item}}
</view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
menus: [
'新聞', '汽車', '讀書'
],
activeIndex: 0
}
},
onLoad() {
_self = this
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
menuClick: function(e){
var aid = e.target.id;
console.log(aid);
_self.activeIndex = aid;
}
}
}
</script>
<style>
.menu {
padding: 10px;
float: left;
margin: 5px;
line-height: 36px;
}
.menuActive {
color: #FF0000 !important;
}
</style>
使用了事件來達到動態切換的效果。
顯示:
可以看到,點選不同的導航欄實現了顏色同步變化的效果。
三、事件和事件繫結
1.uni-app事件
事件對映表定義了WEB事件(左側)和uni-app事件(右側)之間的對應關係,具體如下:
Web事件 | uni-app事件 | 說明 |
---|---|---|
click | ‘tap’ | 被點選 |
touchstart | ‘touchstart’ | 手指開始在元素上觸控時 |
touchmove | ‘touchmove’ | 移動 |
touchcancel | ‘touchcancel’ | 取消 |
touchend | ‘touchend’ | 結束 |
tap | ‘tap’ | 單機 |
longtap | ‘longtap’ | 長按 |
input | ‘input’ | 輸入 |
change | ‘change’ | 改變 |
submit | ‘submit’ | 表單提交 |
blur | ‘blur’ | 失焦 |
focus: ‘focus’ | 聚焦 | |
reset | ‘reset’ | 表單重置 |
confirm | ‘confirm’ | 確認 |
columnchange | ‘columnchange’ | 欄位變化 |
linechange | ‘linechange’ | 行比那花 |
error | ‘error’ | 錯誤 |
scrolltoupper | ‘scrolltoupper’ | 滾動到頂部 |
scrolltolower | ‘scrolltolower’ | 滾動到底部 |
scroll | ‘scroll’ | 滾動 |
說明:
(1)在 input 和 textarea 中 change 事件會被轉為 blur 事件;
(2)列表中沒有的原生事件也可以使用,例如map元件的regionchange 事件直接在元件上新增@regionchange
修飾即可,同時這個事件也非常特殊,它的 event type 有 begin 和 end 兩個,導致我們無法在handleProxy 中區分到底是什麼事件,所以在監聽此類事件的時候同時監聽事件名和事件型別,即<map @regionchange="functionName" @end="functionName" @begin="functionName"><map>
;
(3)由於平臺的差異,bind 和 catch 事件同時繫結時,只會觸發 bind,catch 不會被觸發,使用時需要注意。
- 事件修飾符:
使用stop會阻止冒泡,但是同時繫結了一個非冒泡事件,會導致該元素上的 catchEventName 失效;
prevent 可以直接結束事件,因為uni-app裡沒有什麼預設事件,比如 submit 並不會跳轉頁面;
self 沒有可以判斷的標識;
once 也不能做,因為uni-app沒有 removeEventListener, 雖然可以直接在 handleProxy 中處理,但是並不優雅; - 按鍵修飾符:
uni-app執行在手機端,沒有鍵盤事件,所以不支援按鍵修飾符。
2.事件繫結
使用@
對元素進行事件繫結,當事件被觸發時,會導致相應的操作。
index.vue如下:
<template>
<view>
<view class="demo" @click="clickTest" @longtap="longtap"></view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
}
},
onLoad() {
_self = this
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
clickTest : function(e){
console.log("click")
},
longtap : function(e){
console.log("longtap")
},
}
}
</script>
<style>
.demo {
width: 600rpx;
height: 600rpx;
background: #DD524D;
}
</style>
顯示:
可以看到,在進行點選和長按時,會觸發不同的事件、執行不同的操作。
注意在小程式中觀察對應事件物件,可以利用此物件獲取更多資訊。
3.事件傳參
在觸發事件時,還可以傳入動態引數。
如下:
<template>
<view>
<view v-for="(item, index) in students" class="persons" @click="menuClick" v-bind:id="index">{{index}} - {{item.name}}</view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
students: [{
name: "張三",
age: 18
},
{
name: "李四",
age: 20
}
]
}
},
onLoad() {
_self = this
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
menuClick: function(e) {
console.log(e);
console.log(e.target.id);
},
}
}
</script>
<style>
.demo {
width: 600rpx;
height: 600rpx;
background: #DD524D;
}
</style>
顯示:
可以看到,在進行點選時,控制檯列印出了事件物件和e.target.id
的值。
再如:
<template>
<view>
<view class="demo" id="outid" @click="clickTest" @longtap="longtap">
<view id="inid" style="width: 400rpx;height: 400rpx;background: #007AFF;"></view>
</view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
}
},
onLoad() {
_self = this
},
onShow() {
console.log('index onshow')
},
onHide() {
console.log('index onhide')
},
methods: {
clickTest : function(e){
console.log(e.currentTarget.id)
console.log(e.target.id)
},
longtap : function(e){
console.log("longtap")
},
}
}
</script>
<style>
.demo {
width: 600rpx;
height: 600rpx;
background: #DD524D;
}
</style>
顯示:
可以看到,在點選外部紅色區域時,列印的兩個id值相同;
而在點選內部藍色區域時,e.target
變為內部的view元素,所以列印出的也是inid
,所以在使用屬性傳參時儘量使用e.currentTarget
。
相關文章
- echarts 繫結事件處理函式Echarts事件函式
- 事件繫結和樣式規定的原則事件
- 繫結class樣式和style樣式
- 手摸手帶你入門ionic3(五):樣式繫結
- 模板語法之--強制資料繫結和繫結事件監聽事件
- 事件繫結事件
- 第二講、Vue3.x繫結資料、繫結html、繫結屬性、迴圈資料VueHTML
- 第三講、Vue3.x中的事件方法入門、模板語法模板中類和樣式繫結Vue事件
- vue-class和style樣式繫結Vue
- JSX繫結事件JS事件
- JavaScript 事件繫結JavaScript事件
- js on繫結事件JS事件
- 資料繫結
- 小王的學習筆記(十四)——vue資料渲染、事件處理、表單輸入與繫結筆記Vue事件
- JS的事件繫結和事件流模型JS事件模型
- JS學習之事件和事件繫結JS事件
- React中this值繫結和事件函式傳參React事件函式
- 繫結自定義事件事件
- v-on 繫結事件事件
- JS-事件繫結JS事件
- Vue事件繫結原理Vue事件
- Hooks與事件繫結Hook事件
- Vue 動態繫結CSS樣式VueCSS
- 【測試平臺開發】Vue指令、屬性繫結、事件繫結學習教程Vue事件
- 淺入深出Vue:資料繫結Vue
- React事件優雅繫結React事件
- 元件繫結原生事件元件事件
- IOS繫結touchend事件失效iOS事件
- React事件繫結的方式React事件
- python tkinter如何繫結事件?Python事件
- C#快速入門教程(29)—— ADO.NET離線元件與資料繫結C#元件
- SpringMVC資料繫結demoSpringMVC
- Angular | 理解資料繫結Angular
- Binding(一):資料繫結
- class 和 style 資料動態繫結
- 02 . Vue入門基礎之條件渲染,列表渲染,事件處理器,表單控制元件繫結Vue事件控制元件
- Vue事件獲取觸發事件物件和繫結事件物件Vue事件物件
- Android開發教程-使用DataBinding(五)資料繫結Android