前言不知道說什麼,可是感受你們都有前言,我也不能輸,那就隨便嘮點好了。本人是一名大三學生,是一個前端小菜雞,這是個人第一篇掘金文章。以前和兩個隊友組隊寫了一個原創小程序——猿簡歷(已上線,但還有不少須要完善的)。最近初學了vue
,又涉及了一下mpvue
,因而就找了個小項目來練練手,既能再找找小程序的感受,又能練練vue的寫法。起初是打算一週練手完成主要功能,因此這真的是一個很小很小的小項目,沒有什麼技術難點,只能分享一些小tips了。還但願各位看官能看的高興。css
由於我第一次寫mpvue的時候,起初沒法下手,不肯定要怎麼構建項目,因此就把本身構建項目的步驟一併寫了上來,但願能幫助到你。html
初始化項目前,請確保本機已經正確裝好node環境前端
下載vue腳手架vue
npm install vue-cli -g
複製代碼
初始化項目node
vue init mpvue/mpvue-quickstart mpvue-zhirent
複製代碼
進入項目根目錄git
cd mpvue-zhirent
複製代碼
根據package.json安裝項目依賴包程序員
npm install
複製代碼
啓動初始化項目github
npm start || npm run dev
複製代碼
當看到職人小程序時,腦子裏第一反應即是基於MVVM(Model-View-ViewModel)系統架構思想。那麼定義數據便成了項目開發最重要的事情。首先搜索了一下職人的相關網站,沒有找到能夠爬取數據的網站(也多是我沒有看到),就只能定義假數據了。而說到定義假數據,第一想法就是用EasyMock(一個可視化,而且能快速生成 模擬數據的持久化服務)定義假數據了。因而手擼假數據擼到懷疑人生,這時候終於懂了程序員那句最美的情話了——「我給你寫接口好嗎?」。
我定義數據時添加了一個"errno":0
,爲的是在請求數據時判斷接口請求的狀態。active和sponsor分別是沙龍數據和主辦方數據。
此次開發我用了axios來請求數據。
首先,安裝axios
$ npm install axios
複製代碼
在build > webpack.base.config.js
文件中找到alias
爲axios添加別名
alias: {
'vue': 'mpvue',
'axios':'axios/dist/axios',
'@': resolve('src')
}
複製代碼
在src > utils
下添加一個axios.js
文件,封裝axios
import axios from 'axios'
import qs from 'qs'
axios.defaults.timeout = 30000;
axios.defaults.baseURL ='';
axios.defaults.headers.post[ 'Content-Type' ] = 'application/x-www-form-urlencoded;charset=UTF-8';
axios.defaults.adapter = function (config) {
return new Promise((resolve, reject) => {
let data = config.method === 'get' ? config.params : qs.stringify(config.data)
wx.request({
url:config.url,
method:config.method,
data:data,
success:(res)=>{
return resolve(res)
},
fail:(err)=>{
return reject(err)
}
})
})
}
//請求攔截器
axios.interceptors.request.use(function ( request ) {
// console.log(request) //請求成功
return request
}, function ( error ) {
// console.log(error); //請求失敗
return Promise.reject(error);
});
// 添加響應攔截器
axios.interceptors.response.use(function ( response ) {
// console.log(response.data.data) //響應成功
return response;
}, function ( error ) {
// console.log(error); //響應失敗
return Promise.reject(error);
});
export function get (url,params) {
return axios({
method:'get',
url:url,
params:params
})
}
複製代碼
在main.js
文件中封裝數據請求
import Vue from 'vue'
import App from './App'
import axios from 'axios'
// 將get請求引入
import {get} from './utils/axios'
// 將get請求掛載上去
Vue.prototype.$get=get;
Vue.prototype.getList = function (){
wx.showLoading({
title:'加載中'
}),
this.$get("https://www.easy-mock.com/mock/5d17149edc925c312db9c9ea/zhirent/zhirent")
.then((res) => {
if (res.data.errno === 0) {
this.active = res.data.data.active;
this.sponsors = res.data.data.sponsors
}
})
wx.hideLoading()
}
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue(App)
app.$mount()
複製代碼
$ npm i stylus stylus-loader -D
複製代碼
build > webpack.base.config.js
文件中添加找到rules,添加文件處理規則{
test: /\.css$/,
loader: 'style-loader!css-loader!stylus-loader'
}
複製代碼
以下圖:
好了,該安裝的也安裝了,該配置的也配置了,終於能夠開始愉快又使人激動的Coding之旅了。職人小程序包含了沙龍、主辦方、個人 三個主要頁面,以及沙龍詳情和主辦方詳情兩個頁面,個人頁面包含了我的的活動報名、主辦方收藏、活動收藏等信息。接下來我將分享一些項目中遇到的坑和一些主要功能的實現。
mpvue添加頁面並不像小程序那樣添加頁面方便。須要瘋狂手動添加文件,手動配置頁面信息,手動添加頁面路徑。每次添加新頁面必定要記得去app.json
裏添加路徑信息!!!
1.建立頁面文件
咱們須要在src/pages
目錄下手動建立頁面文件夾index
,並在index
文件夾下添加 index.vue
和main.js
兩個文件,index.vue
則是咱們的html頁面(可將index改成其它,只需在main.js
中引入便可),main.js
不可更名,若是將main改成其餘名字(相關位置均作修改),都將會出現報錯。
index.vue
在頁面還未寫任何頁面結構時 須要編寫以下基本結構,不然將會出現
pages/mine/main.js 出現腳本錯誤或者未正確調用 Page() 的報錯信息
<template>
<div></div>
</template>
<script>
export default {
}
</script>
<style>
</style>
複製代碼
main.js
的基本結構則爲
import Vue from 'vue'
import App from './index' //若是index.vue更名爲home.vue,這裏則將index改成home
const app = new Vue(App)
app.$mount()
複製代碼
2.添加頁面
每建立一個新頁面都需在src/app.json
文件中的pages手動 添加頁面路徑,不然將會出現
navigateTo:fail page "pages/index/main" is not found的報錯信息
"pages": [
"pages/index/main"
]
複製代碼
3.配置分頁面
能夠經過在onLoad(){}
生命週期中調用wx.setNavigationBarTitle({})
api動態設置分頁面的navigationBarTitle
onLoad(){
wx.setNavigationBarTitle({
title: '受權'
})
}
複製代碼
也能夠手動添加main.json
文件,靜態設置分頁面的navigationBarTitle
{
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#224fa4",
"navigationBarTitleText": "職人",
"navigationBarTextStyle": "white"
}
複製代碼
在src/app.json
下的tabBar下作相應更改便可,和小程序的tabBar自定義過程無異。這裏要注意的是:通常會將tabBar的icon放在static/tabs
目錄下,其餘頁面圖標則放在images目錄下,方便管理。頁面的icon能夠選擇svg格式的話就選擇svg的圖片,這樣有利於節省小程序的空間,但小程序的tabBar-icon暫時還不支持svg格式的圖片。我在webpack.base.config.js
中設置了圖片路徑別名,故圖片路徑可直接寫static/tabs/car1.png
,以下圖:
"tabBar": {
"color": "#999",
"backgroundColor": "#fff",
"selectedColor": "#0c53ab",
"borderStyle": "black",
"list": [{
"text": "沙龍",
"pagePath": "pages/salon/main",
"iconPath": "static/tabs/car1.png",
"selectedIconPath": "static/tabs/car.png"
}, {
"text": "主辦方",
"pagePath": "pages/sponsor/main",
"iconPath": "static/tabs/home1.png",
"selectedIconPath": "static/tabs/home.png"
}, {
"text": "個人",
"pagePath": "pages/mine/main",
"iconPath": "static/tabs/mine1.png",
"selectedIconPath": "static/tabs/mine.png"
}
],
"position": "bottom"
}
複製代碼
進入小程序,跳轉到受權頁面,受權後跳轉到沙龍頁面,若是用戶點擊拒絕則會停留在該頁面,用戶下次進入小程序時,仍是能跳轉到受權頁面。
那麼如何實現受權頁面呢?首先,咱們須要在進入小程序時經過調用wx.getSetting()
來判斷用戶是否已經受權。若是已經受權,那麼咱們就能夠經過調用wx.getUserInfo()
來獲取用戶信息,若是沒有受權,則跳轉到寫好的受權頁面。那麼咱們就須要在App.vue
中的onShow或onLaunch生命週期中進行判斷
// 獲取用戶的當前設置。返回值中只會出現小程序已經向用戶請求過的權限。
wx.getSetting({
success(res){
if (res.authSetting['scope.userInfo']) {
// 若是已經受權,能夠直接調用 getUserInfo獲取用戶信息
wx.getUserInfo({
success: function(res) {
console.log(res.userInfo)
}
})
}else{
// 若是未受權,則跳轉到受權頁面
wx.reLaunch({
url: '/pages/authorize/main',
})
}
}
})
複製代碼
而後,經過小程序<button>
自帶的open-type
屬性開放getUserInfo
能力,進行受權。再經過bindgetuserinfo
屬性返回獲取到的用戶信息,經過判斷是否獲取到用戶信息進行判斷是否受權成功,若是成功,則跳轉到沙龍首頁
<button class="authorize" open-type="getUserInfo" @getuserinfo="getUserInfo">贊成受權</button>
複製代碼
getUserInfo(){
wx.getSetting({
success:(res) => {
if(res.authSetting['scope.userInfo']){
wx.showLoading({
title:'加載中'
})
wx.reLaunch({
url:'/pages/salon/main'
})
wx.hideLoading()
}
}
})
}
複製代碼
受權成功後,刷新頁面,就能夠看到打印出來的用戶信息啦
當時由於本身要作的事情真的太多了,產品經理從0到1,UI從0到1,切圖仔從0到1,加上兩個大佬都出問題了,以爲小菜雞的本身就更不可能會了,也就專心作本身分內的事情。當本身嘗試受權界面後,就很想手動艾特我兩個隊友進來捱打。咋肥事啊小老弟?
。 。 。 。
因此碰見任何難題時,都應該本身動手去嘗試一下,不能以爲別人不會你就必定也不會,必定要本身去嘗試寫一寫!!!
這兩個頁面十分簡單,很直觀的兩個數據渲染頁面。兩個頁面寫法幾乎同樣,我就挑一個代碼少一點的來講了。
首先,咱們區別一下onLoad & onShow
綜上,咱們加載這兩個頁面數據,應該在onLoad生命週期中請求數據。因爲以前咱們已經將數據請求封裝到main.js
文件中了,故直接調用封裝的方法便可。
onLoad(){
this.getList();
}
複製代碼
很明顯,這兩個頁面都須要用到數據循環,須要使用v-for嵌套時。
// 主辦方頁面
<div class="sponsor">
<div v-for="(item,index) in sponsors" :key="index" @click="toSponsorInfo(index)" class="card-container">
<div class="card-content">
<div class="card-icon">
<image class="icon" :src="item.avatar"></image>
</div>
<div class="card-info">
<div class="card-title">{{item.name}}</div>
<div class="card-desc">{{item.info}}</div>
</div>
<button @click.stop="collect(index)" :class="collectList[index] ? 'like' : 'unlike'">{{collectList[index] ? '已關注' : '關注'}}</button>
</div>
<div class="card-footer">
<div class="card-salon-num">共舉辦{{item.salonNum}}場沙龍</div>
<div v-if="item.salonNum>0" class="card-recently">最近沙龍:{{item.salons[0].title}}</div>
</div>
</div>
</div>
複製代碼
而使用v-for嵌套時須要注意:在mpvue中外循環和內循環不能使用同一個index,須要更改一個其中一個的索引值標識,不然將出現
同一組件內嵌套的 v-for 不能連續使用相同的索引,目前爲: index,index 的報錯信息
由於咱們在項目準備時已經將stylus配置好了,即可以直接在index.vue
中使用stylus
<style lang="stylus" scoped>
</style>
複製代碼
這裏scoped表示該樣式是該頁面的私有樣式,不會污染全局。
v-for="(item,index) in sponsors
每個列表的index表明着當前數據的下標值,咱們能夠經過將該值傳遞到詳情頁,再請求數據並經過傳遞的下標值找到對應的數據,最後將拿到的數據渲染到詳情頁就好啦。具體作法以下:
div
標籤,綁定一個事件,並將當前列表的index傳遞過去<div v-for="(item,index) in sponsors" :key="index" @click="toSponsorInfo(index)" class="card-container">
複製代碼
<script>
中添加methods屬性,在methods屬性中建立寫方法。// 接收傳遞進來的index值
toSponsorInfo(index){
// 拼接url,並將接收的index值傳到要跳轉的頁面
const url = `/pages/sponsorInfo/main?index=${index}`
wx.navigateTo({
url
});
複製代碼
onLoad(options){
let i = options.index;
wx.showLoading({
title:'加載中'
}),
this.$http
.get("https://www.easy-mock.com/mock/5d17149edc925c312db9c9ea/zhirent/zhirent")
.then((res) => {
// 拿到對應index的主辦方詳情信息
this.sponsor = res.data.data.sponsors[i];
wx.hideLoading()
});
}
複製代碼
avtive
(沙龍)數據中,給出一個
sponsors
數組,數組中表明着舉辦該沙龍的主辦方列表,每一個主辦方給出一個
name
字段。在
sponsors
(主辦方)數據中,給出一個
salons
數組,數組表明着該主辦方舉辦過的沙龍列表,每一個沙龍給出一個
title
字段。
sponsorsNum
字段,便於判斷,當主辦方數字大於0時,才須要進行數據遍歷查找。
salonNum
字段,當舉辦的沙龍數量大於0時,才進行數據遍歷查找。
以主辦方詳情爲例
this.$http
.get("https://www.easy-mock.com/mock/5d17149edc925c312db9c9ea/zhirent/zhirent")
.then((res) => {
// 拿到對應index的主辦方詳情
this.sponsor = res.data.data.sponsors[i];
// 拿到全部的沙龍數據
let salonsInfos = res.data.data.active
// 經過數組遍歷拿到該主辦方詳情中的舉辦的沙龍列表
// 若是主辦方舉辦的沙龍數量大於0,進行數組遍歷
if(this.sponsor.salonNum>0){
// 遍歷該主辦方的舉辦過的沙龍列表
this.salonList = this.sponsor.salons.map(item=>{
let sal
// 遍歷拿到的全部沙龍數據
salonsInfos.forEach(salon => {
// 當沙龍的主題與主辦方舉辦的沙龍列表中的主題相同時,拿到對應的沙龍信息,並將沙龍信息替換進沙龍列表的title字段
if(salon.title === item.title) sal = salon
})
return sal
})
}
wx.hideLoading()
});
},
複製代碼
這樣,咱們就拿到了對應title
的沙龍列表的詳細數據了,再將列表渲染到頁面便可。從gif圖中能夠看出:個人頁面由三部分組成,頭部展現用戶信息、客服和設置,tab欄選擇選項,tab選項對應的展現頁面。
展現用戶頭像和暱稱有兩種寫法:
經過調用wx.getUserInfo()
來獲取用戶頭像和暱稱,可是須要用戶受權,受權後才能成功獲取用戶頭像和暱稱。
使用官方的<open-data>
標籤直接顯示用戶頭像和暱稱(無需受權)
<open-data type="userAvatarUrl"></open-data> //獲取用戶頭像直接顯示在小程序中
<open-data type="userNickName" ></open-data> //獲取用戶暱稱直接顯示在小程序中
複製代碼
修改<open-data>
標籤中的樣式時需注意,這裏不能像寫img/image的樣式同樣,直接給圖片一個width="50px";height="50px";border-radius="50%"
的樣式,這樣並不會生效。圖片會以下圖同樣,沒有任何改變。
那麼怎樣才能修改 <open-data>
標籤的樣式呢?
咱們能夠添加一個display:flex
屬性使圖片大小可以改變,再添加一個overflow:hidden
屬性使圓角可以出現。
<open-data class="thumb" type="userAvatarUrl"></open-data>
複製代碼
.thumb
width 100%
height 100%
border-radius 50%
overflow hidden
display flex
複製代碼
這樣,一個好看的頭像顯示就完成啦。
由於這裏只是一個小demo項目,加上客服功能還須要配置開發者信息以及添加客服帳號,實在是麻煩,就懶得弄了。可是有個icon在這裏,總感受不能點擊會很難受,因而就添加了個點擊事件,當你好奇是啥的時候彈出一個暫不支持的提示框哈哈哈哈哈。別問、問就是懶,別說、說就是不必。
若是有想要了解一下客服功能怎麼實現的盆友能夠自行查看一些小程序官方文檔:客服消息使用指南、客服帳號管理。
點擊小齒輪就會跳轉到一個設置的頁面,頁面分爲兩項,第一項是職人小程序的%¥%¥?咱也不知道咋描述,他說是關於職人就是關於職人吧。第二項是主辦方中心。這兩項點擊又是一個跳轉頁面,兩個頁面都沒啥操做,就是一個頁面展現。關於職人的頁面我就直接截了個圖上去,畢竟咱也沒有UI小姐姐,只能偷偷懶了,不會偷懶的程序猿不是好程序猿hhhh。
當點擊任意tab時,樣式和展現的內容都會隨之變化。
嘶,這個樣式咋動態顯示啊?經過點擊事件給dom節點添加類名嗎?有點太麻煩了吧。添加一個數據進行判斷嗎?也好麻煩啊。
嘶,這個又要咋操做才能根據我點擊的的內容展現該展現的頁面啊?點擊一個tab就給一個數據,經過數據來判斷是否展現頁面嗎?這也太麻煩了。
這個看似簡單,但又有些許難度的小tab欄應該怎麼實現呢?
首先,咱們在數據源裏定義一個navList
,讓tab欄由數據渲染出來,這樣咱們能夠獲取它的index值,再經過index來賦值。
data(){
return{
//給一個默認的changeNav值,
changeNav:0,
navList: [{name:'參加'},{name:'感興趣'},{name:'關注'}]
}
}
複製代碼
而後,咱們能夠經過html的data-
屬性來自定義數據,並將自定義數據與點擊的index值進行綁定。
<div class="tab-item" v-for="(item,index) in navList" :key="index" :data-current="index" @click="swichNav">
複製代碼
最後,經過定義的點擊事件來獲取自定義的數據
methods:{
swichNav(e){
const current = e.currentTarget.dataset.current
this.changeNav = current
}
}
複製代碼
而樣式問題咱們則經過判斷改變的changeNav
值是否與index
值相等來動態添加一個active
的類名
:class="{active:changeNav == index}"
複製代碼
頁面的轉換則經過v-if
來判斷展現哪個頁面
<Nothing v-if="changeNav==0" :tips="salonTip"></Nothing>
<Interest v-if="changeNav==1" :salon="interestList" @goDetail="goSalonDetail"></Interest>
<Collect v-if="changeNav==2" :sponsors="collectList" @go="goSponDetail"></Collect>
複製代碼
這個小程序的報名要填信息啥啥的,以及畢竟是個活動,感受隨意報名有點不太好,因此就沒有寫報名的小分頁面,就直接展現一個沒有參加的沙龍頁面了。(還不是由於懶)
<button @click.stop="collect(index)" :class="collectList[index] ? 'like' : 'unlike'">{{collectList[index] ? '已關注' : '關注'}}</button>
複製代碼
collectList:[]
,在頁面加載時讀取以前本地緩存的狀態查看是否有關注,若是不存在本地緩存,就把默認數組collectList
添加到本地緩存。若是存在本地緩存,就將本地緩存的數據賦值給collectList
onShow(){
var cache = wx.getStorageSync('collectList')
if(!cache){
wx.setStorage({
key:"collectList",
data:this.collectList
})
}else{
this.collectList = cache
}
}
複製代碼
methods
中編寫點擊事件collect(){}
methods:{
collect(index){
// 防止this指向改變
let self = this
// 拿到緩存區的collectList數組
var cache = wx.getStorageSync('collectList')
// 獲取當前主辦方是否被關注
var currentCache = cache[index]
// 若是沒有被關注
if(!currentCache){
// 將當前列表的關注狀態設置爲關注
currentCache = true
wx.showLoading({
title: '加載中',
})
//將當前列表的關注狀態賦值給本地緩存
cache[index] = currentCache
//從新設置緩存
wx.setStorage({
key:'collectList',
data:cache
})
// 將緩存賦值給數據源
self.collectList = cache
wx.hideLoading()
}else{
//若是存在緩存狀態,則調用操做菜單
wx.showActionSheet({
itemList: ['取消關注'],
success (res) {
wx.showLoading({
title: '加載中',
})
currentCache = false
cache[index] = currentCache
wx.setStorage({
key:'collectList',
data:cache
})
self.collectList = cache
wx.hideLoading()
}
})
}
}
複製代碼
這樣,就實現了點擊哪個主辦方的關注按鈕,哪個主辦方便發生狀態改變的功能了,那麼接下來咱們則須要在詳情頁作相似的處理。isCollected:''
,在頁面加載時讀取緩存狀態並賦值給數據源中的isCollected
onShow(){
// 拿到緩存區的關注信息
var cache = wx.getStorageSync('collectList')
//在頁面接收參數index時將option.index賦值給數據源中的index了,因此這裏直接調用了this.index
this.isCollected = cache[this.index]
},
複製代碼
<button @click="collect" :class="isCollected ? 'like' : 'unlike'">{{isCollected ? '已關注' : '關注'}}</button>
複製代碼
methods: {
// 接下來的操做和上面的操做沒啥區別。。。我就不寫了。。。
collect(){
var cache = wx.getStorageSync('collectList')
let self = this
var currentCache = cache[self.index]
if(!currentCache){
wx.showLoading({
title:'加載中'
})
currentCache = true
cache[self.index] = currentCache
wx.setStorage({
key:'collectList',
data:cache
})
self.isCollected = cache[self.index]
wx.hideLoading()
}else{
wx.showActionSheet({
itemList: ['取消關注'],
success(res){
wx.showLoading({
title:'加載中'
})
currentCache = false
cache[self.index] = currentCache
wx.setStorage({
key:'collectList',
data:cache
})
self.isCollected = cache[self.index]
wx.hideLoading()
}
})
}
},
}
複製代碼
這樣,就實現了基於本地緩存實現列表關注功能惹,細心的盆友可能會發現,在判斷是否存在關注狀態時,if和else都有共同的操做,可是我沒有合在一塊兒寫,而是各自都寫了一遍。是由於,合在一塊兒寫時會產生異步,當else操做還沒執行完時,就執行接下來的賦值操做,致使操做不成功。解決異步能夠用Promise
,可是promise也要重複兩次代碼,能解決問題爲啥不用最簡單直白的方式呢?因此懶人本懶直接在if判斷裏重複兩次代碼了。
因爲以前咱們利用本地緩存實現了將感興趣/關注的功能,那麼咱們如何拿到感興趣與關注的列表詳情數據呢?一樣的,咱們仍是能夠經過數組遍從來獲取到詳細數據。就拿主辦方關注來講,咱們能夠在數據加載時先拿到緩存區的主辦方收藏列表,經過數組遍歷拿到關注了的主辦方的下角標數組,再經過遍歷將對應下角標的主辦方關注詳情拿到。將數據渲染上去便可。
onShow(){
this.$get("https://www.easy-mock.com/mock/5d17149edc925c312db9c9ea/zhirent/zhirent")
.then((res) => {
// 全部的主辦方
wx.showLoading()
this.sponsors = res.data.data.sponsors;
// 拿到緩存中的主辦方收藏列表
var cache = wx.getStorageSync('collectList')
// 拿到收藏的主辦方的下角標數組
this.targetList = []
cache.forEach((item,i) => {
if(item) this.targetList.push(i)
});
// 拿到收藏的主辦方信息列表
this.collectList = this.targetList.map(index => {
let spon
this.sponsors.forEach((item,i) => {
if(index === i) spon = item
})
return spon
})
// console.log(this.collectList)
}
複製代碼
此外,點擊個人頁面上的任意關注/感興趣列表,均可以跳轉到對應的主辦方/沙龍詳情頁面,咱們只須要在編寫頁面跳轉至詳情頁時,將跳轉的index值修改一下便可。
goSponDetail(index){
const url = `/pages/sponsorInfo/main?index=${this.targetList[index]}`
wx.navigateTo({
url
})
}
複製代碼
和主辦方列表關注同樣,列表實現感興趣功能我就不詳細描述了。與主辦方頁面不一樣的是,頁面加載時須要判斷一下是否感興趣,若是感興趣的話,頁面加載時,我的信息就應該出如今頭像列表上。當點擊取消感興趣時,則刪除我的信息。因爲咱們寫了受權頁面,給小程序進行了受權操做,因此能夠直接調用wx.getUserInfo()
來獲取用戶信息
onShow(){
self = this
// 獲取用戶信息
wx.getUserInfo({
success(res){
var userInfo = res.userInfo
var nickName = userInfo.nickName
var avatarUrl = userInfo.avatarUrl
// 將用戶信息賦值給數據源中的user
self.user = {
name:nickName,
avatar:avatarUrl
}
var cache = wx.getStorageSync('interestList')
self.isInterested = cache[self.index]
if(self.isInterested){
self.interestInfo.unshift(self.user)
}
}
})
},
複製代碼
這個調用小程序官方apiwx.previewImage
就好啦。
因爲這個操做菜單並非緊挨着底部的,因此咱們須要本身定義一個share
的組件,並在數據源給定一個isShare:false
的狀態,經過狀態來決定share
組件是否展現。首先,咱們點擊分享按鈕,將數據源中的狀態改變爲true
,而後再在share
組件中的取消按鈕定義一個點擊事件,並經過$emit
將事件傳給父組件,從而實現父子組件間通訊問題。
share
組件,並給對應的item
添加對應的點擊事件。分享給好友或羣直接應用微信官方的button
組件中open-type
屬性,並將open-type
的值設置爲share
,便可實現分享給好友功能。保存沙龍海報會自動生成對應活動的二維碼,沒有上線就沒有二維碼。因此這個功能我就沒有去寫了。這裏有一點要提的是,小程序的button
若是背景色爲白色,就會出現自帶的邊框,給button
添加一個plain="true"
屬性就行了。<div class="container">
<div class="tips" >分享該沙龍</div>
<button plain="true" open-type="share" class="type">分享給好友或羣</button>
<button plain="true" class="type" @click="save">保存沙龍海報</button>
<div class="cancel" @click="cancel">取消</div>
</div>
複製代碼
share:false
的數據data() {
return {
share:false
}
}
複製代碼
cancel(){
this.$emit('cancel',this.share)
}
複製代碼
share
組件,並在數據源中定義isShare:false
,經過isShare
來判斷是否展現操做菜單,並經過v-on
(可簡寫爲@)綁定了一個cancel事件來監聽子組件的觸發事件,<Share v-if="isShare" @cancel="cancelShare"></Share>
複製代碼
<script>
import Share from '@/components/share/share'
export default{
data(){
return:{
isShare:false,
}
},
components:{
Share
},
methods:{
//接收子組件傳遞過來的數據:this.share(false),並將值賦值給isShare
cancelShare(msg){
this.isShare = msg
}
}
}
</script>
複製代碼
就這樣,一個簡單的自定義操做菜單組件就完成了。既然說到了父子組件通訊問題,那我就再說一下vue
中,父組件如何向子組件傳值,以及兄弟組件間通訊問題好了。
因爲沙龍詳情頁面結構實在是太多模塊了,因此我每一個展現模塊都封裝成了組件,提升代碼可讀性。以及有兩個頁面都涉及到了點擊展開詳情,因而我也封裝成了一個組件,提升代碼複用性,這裏就以點擊展開詳情的組件來講一說父組件如何向子組件傳值的問題好了。
<template>
<div>
<div class="info-desc" :class="isEllipsis ?'ellipsis':'unellipsis'">{{info}}</div>
<div class="text-expander" @click="ellipsis" >
<text class="text-expander__content">{{isEllipsis?'展開所有':'所有收起'}}</text>
<image class="text-expander__icon" :src="isEllipsis?'/static/images/down.svg':'/static/images/up.svg'"></image>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isEllipsis:true
}
},
methods: {
ellipsis(){
this.isEllipsis =!this.isEllipsis
}
},
props:[
'info'
]
}
</script>
<style lang="stylus" scoped>
.info-desc
font-size 14px
display -webkit-box
-webkit-box-orient vertical
text-overflow ellipsis
overflow hidden
line-height 26px
text-align left
.ellipsis
-webkit-line-clamp 3
.unellipsis
-webkit-line-clamp 0
.text-expander
margin 0 auto
width 80px
height 20px
.text-expander__content
color #c4c8c7
font-size 16px
.text-expander__icon
width 15px
height 15px
</style>
複製代碼
在不一樣頁面上,文本中展現的內容不同,因此咱們須要向父組件接收數據,父組件向子組件傳遞數據能夠經過props
屬性來傳遞。子組件像父組件要info
數據,經過props
來索取。
v-bind
(能夠簡寫爲@)來綁定數據。<Expander :info="salonInfo"></Expander>
複製代碼
就這樣,子組件就能夠拿到父組件中定義的salonInfo
數據了。有興趣的盆友還能夠了解一下$on
(子組件接收數據),以及非父子組件的兄弟組件間通訊方式(建一個Vue事件bus對象,而後經過bus.$emit
觸發事件,bus.$on
監聽觸發的事件)。
結語也不知道說些啥,但別人也都有,我也不能輸!那仍是隨便嘮點吧QAQ。
原本是打算找個界面簡潔功能稍多的小項目來練手,結果最後仍是百分之八十是在切圖,不得不說,切圖真的很快樂,因此個人同桌老王常常調侃我:「純粹的前端」,固然這裏指的是純粹的切圖。但一隻醬毫不服輸,此次採用的是easy-mock,下次寫小項目就嘗試jsonp請求數據,或者使用萬能的爬蟲爬取數據,或者全棧開發一個小項目。寫項目也是一件很是快樂的一件事情,當你實現一個小功能時,或者本身想到 一個解決的辦法時,真的頗有成就感(雖然這個項目真的沒有什麼技術難點T-T)。最後奉上源碼,但願能幫助到你們一小丟丟。