背景
在一pc端的web專案裡,由於某些特性需要由動態語言處理,所以只在有需要使用vue來處理資料的頁面,直接引入vue.js來處理。
由於剛開始並沒有打算使用前端來渲染資料和處理互動,所以使用了一些非vue的ui和外掛,導致後來衝突坑點不少。
非vue模組化下使用vue,雖然不能import vue檔案,使用元件方式也有點噁心,但處理一些事情還是不錯的。
使用formdata提交表單資料
先上程式碼
var that = this;
var myForm = document.getElementById("form_add");
var submitFormData = new FormData(myForm);
submitFormData.append('action', this.action);//新增自定義的引數,這裡是動作,新增或者修改
layer.load(0,{time:500});
$.ajax({
url : apiAddressAdd,
type : 'POST',
dataType : 'json',
cache : false,
processData : false,
contentType : false,
data : submitFormData
})複製程式碼
有2個引數是必須設定processData 和 contentType
這裡要說的是contentType,經實踐,不管是否有包括file上傳檔案或圖片,則必須設定為false, 設定為true或不設定,後臺都不能獲取
jquery賦值不響應input使用v-model繫結的值
在做某個修改資料功能的時候,由於表單的所有資料,使用v-model繫結的, 包括地址。
地址使用了一個jquery地址選擇器, 當選擇器選擇好地址的時候,只是賦值給input,並沒有觸發v-model繫結的資料
檢視了一篇文章,賦值之後,需要觸發input的原生input事件,才會響應v-model:方式如下
$("#city-picker")[0].dispatchEvent(new Event('input'))複製程式碼
商品篩選之引數組選擇元件
這是很常見的一個功能,本處只是記錄一下思路過程,以防日後老年痴呆,請看下圖
如圖中,有4個引數組,每個引數組只能選定一個引數,選中的引數在下面以標籤,點選X可以去掉相應已選擇的標籤
但由於引數組是從後臺輸出的介面得到的,也就是說,不同的種類的商品,有不同的引數組,有的可能只有1組引數,也有可能有4組
本篇實現此處功能的前提,資料庫表應該設計為:
引數組為單獨一張表,如上面的是選擇了茶具種類,有:分類、材質 、風格、擺放空間,四種引數組(不同的商品種類可能會有相同的引數組,但統一新增到此表中,即唯一id值不會重複)
引數組的引數項為單獨一張表,關聯引數組表,和上面情況一樣,有可能和別的商品種類的一樣的引數組中有相同的引數項(名字就算相同,但是同表中唯一id值不會重複)
這2點也是實現本篩選功能的基礎。
以下為程式碼的實現思路:
先看json資料結構
如圖所示,和上面的篩選元件截圖對應,4個引數組,每個引數組不同的id,所有引數項的id也不同,即便name相同也沒有關係。
請求到引數組的時候,做如下處理
res.data.paramGroup.forEach(function(item){
vm.$set(vm_data.param_group_active,'active_'+item.gid,0);
})
//更新資料
that.dataParamsGroup = res.data.paramGroup;複製程式碼
把引數組所有資料原始格式放到一個叫param_group_active中
這個物件,用來標識當前哪組引數選中的哪項引數項,0,當然就是預設沒有選中
然後並遍歷引數組,以引數組的唯一id為標識,建立一個響應式的物件,值為0 (注意,這裡說的是引數組,非引數組下面的引數項)
得到如下物件
然後看引數組dom結構 :
裡面的A標籤,就是引數的詳細項,啟用的狀態,就是常見的tab的那個做法
選中當前標籤,當然是以class來表示了,上面繫結的class,取決於引數項自己的id,對應 param_group_active組中,啟用的值
點選引數項的時候:
引數帶入:引數組和id,當前點選的引數項的id,並且vue的set方法來設定響應資料
比如當我選擇風格中的花鳥之後,風格的唯一id是14,而花鳥是12
很明瞭了,可以理解成動態tab。。。
接下來,選中的引數,都要顯示在下排,並可以取消。結構如下:
根據我們的啟用引數項的資料param_group_active迴圈出來,大於0,當然是有了選擇,
然後你會看到paramsFlattening[item]這個東西,很明顯這是一個object,item一看就知道是當前選中的引數項的id值,
這裡是要顯示所選中的引數項的名稱,所以,這個paramsFlattening裡面肯定放了引數項的資料
但ahax取回來的資料是一個二維object,暫且這麼叫,我們想一個辦法,我們在這例子中暫時叫引數扁平化
看程式碼:
也就是把所有引數項,放到一個新的object中 (注意,我們這裡的paramsFlattening是一個計算屬性)
以引數項的id為鍵名,中文名稱為值,遍歷放進去,得到了這麼個物件:
所以我們在dom結構中直接以插值方式呼叫:{{paramsFlattening[item]}} ,便可以顯示所選中的標籤的對應中文名稱。
接下來是取消選中的標籤
從上面的截圖中可以看到點選了i 標籤(是一個x圖示)呼叫了deleteParam,並帶進了引數item, 是引數項的id
來看這個方法:
遍歷存放啟用狀態的物件,這裡的key,就是這串:
看哪個物件(每個引數組)的id(記得這裡存的是啟用的引數項的id)值 和帶進來的id值一致,就設為0,
這樣,選中的標籤那個地方,是依賴這裡值大於0才顯示的,設為0就不顯示了
最後你可能會問,選中是選中了,但怎麼提交這些引數資料
在本例中,老衲把這些選中的引數項id值,堆成一塊,用,號分隔,開來,當然後臺查詢的時候還要處理這個資料
封裝一個不完美的圖片上傳類
我們暫且稱它為類,雖然不是用es6 class...此處只當充數字量記錄一下,沒什麼難度
使用場景:多個地方需要上傳圖片,於是搞了這麼個東西,有可能直接點file元,也有可能點選的是別的觸發元素,比如換頭像的時候。
依賴jquery和layer訊息,使用formdata資料來當ajax傳送的資料,好像有file元素,就要設定這2項:
contentType : false,
processData : false
複製程式碼
由於專案中api介面直接統一寫進配置檔案,則這裡不做成引數帶進方式
/**
* [圖片上傳類,統一上傳地址]
* @param {[type]} params [description]
* @param {Function} cb [description]
*/
function ClassUploadImage(params,cb){
this.__proxyEl = params.proxyEl;
this.__imgFileInput = params.imgFileInput;
this.__module = params.module;
this.__cb = cb ;
}
//初始化過程
ClassUploadImage.prototype.init = function(){
var that = this
//先判斷是否有layer和jquery
if(!window.$ || !window.jQuery){alert('沒有jquery!'); return false;}
if(typeof layer == 'undefined'){alert('沒有引入layer!'); return false;}
//繫結代理解發file事件的元素
$(that.__proxyEl).on("click",this,function(){
$(that.__imgFileInput).trigger('click');
})
//繫結檔案表單的選擇事件,當選擇了檔案,立即執行上傳
$(that.__imgFileInput).change(function(){
var files = $(this)[0].files[0];
var formObj = new FormData();
formObj.append('image', files);
formObj.append('module', that.__module);
that.upload(formObj);
});
}
//上傳過程
ClassUploadImage.prototype.upload = function(formObj){
var that = this;
console.log('執行上傳!');
layer.load(0, {shade: false,time:300});
$.ajax({
url : apiImageUpload,
type : 'post',
dataType : 'json',
data : formObj,
cache : false,
contentType : false,
processData : false
})
.done(function(res) {
//此處未對返回的報文進行狀態碼判斷
$.lightTip.success(res.msg);
that.__cb(res);
})
.fail(function(e) {
console.log('不知發生了什麼錯誤...');
})
}複製程式碼
使用:
//上傳圖片初始化
var myUploadImg = new ClassUploadImage({
proxyEl:'#proxyuploadbutton,#proxyuploadimg',
imgFileInput:'#image',
module:'headimg'
},function(res){
$(".header_original_img").val(res.img);
$("#proxyuploadimg").attr('src',res.imgurl)
});
myUploadImg.init();複製程式碼
引數__proxyEl為代理input的點選事件元素,如果忽略此引數,就只能直接點選file元素
複製程式碼
data 裡的Object變數中的Array型別屬性值坑人記錄
場景: 產品詳情頁資料返回的物件中,其中有一個是陣列型別,是產品的相簿
{
"code": 0,
"msg": "資料正常!",
"data": {
"id": 1,
"img": "http://dummyimage.com/360x360",
"name": "唐五代耀州窯剔刻蓮瓣水注",
"artist": "藝術家名字",
"authorId": 93,
"price": "250000",
"dsc": "鐮田先生的天目已經燒造幾十年,作品風格古樸自然 ,口部自然露胎,和傳統油滴建盞有很多相似之處。微距下,斑紋底部透明有反射膜 ,膜上斑紋大而立體,表面微有有觸感。胎體輕盈,色為棕,表面略泛光,喝茶之佳物。",
"view": 779,
"pcid": 2,
"album": [
"http://lorempixel.com/600/600/technics/",
"http://lorempixel.com/600/600/technics/",
"http://lorempixel.com/600/600/technics/"
],
"birth": "1986-11-16",
"birthplace": "安徽省 宿州市 埇橋區",
"birthtype": 2,
"awidth": "30",
"aheight": "80",
"liked": 57,
"detail": "事拉我道象特據片四信廠華。種海點支育容量作積鬥眾運進。南界眼參派傳我真音例活術者所。持人較方觀切度題始可做習列。主萬適等自件教相全門話取用。低金色其命麼放從特長拉線經便。",
"selled": 0,
"favorite": 1
}
}複製程式碼
如程式碼中的album,
如果在檢視中直接使用:<img :src="dataProduct.album[0]"/>
可以正常顯示圖片,但是會報錯,並且頁面中其它地方某些純粹的html結構出不來:
如果使用計算屬性:
<div>{{albumFirstImg}}</div>
一樣會報上面那個錯誤
開發工具中檢視,確實是陣列沒錯:
總結應該因為Vue資料包裝的問題,沒有學習研究過vue原始碼,不知怎麼回事,先放一邊
解決辦法:直接把返回資料中的album再賦值到data根物件下的album即可正常使用
文章結束
要不,加老衲微信做個朋友?