自定義組件:父組件中使用v-model將值傳入子組件,並且子組件也能將值傳回父組件,v-model是雙向傳遞。
而數據綁定:v-bind(縮寫爲:)只能將數值傳給子組件,而無法將值傳給父組件。
大概知道這些就開始寫了。
父組件:
<upload
v-model="this.uploadFileListTest"
:uploadFileData="{'category':'insurance'}">
</upload>
子組件:
<template id="upload">
<div>
<el-upload
action="/api/public/fileUpload"
:data="uploadFileData"
name="files"
listType="picture-card"
multiple
:file-list="uploadFileList"
:on-success = "fileUploadSucc"
:on-remove = "pictureRemove"
:on-preview = "showPic">
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="showPicDialogVisible">
<img width="100%" :src="imageUrl" alt="">
</el-dialog>
</div>
</template>
<script>
export default {
create(){
}
,data:function(){
return {
//uploadFileList:[],
showPicDialogVisible: false
//操作0表示添加,1表示刪除
,operate:0
//用於展示頁面的url
,imageUrl:''
,tempfileList:this.uploadFileList
}
},
props:[
'uploadFileData'
,'listType'
,'uploadFileList'
],
methods:{
fileUploadSucc(response, file, fileList){
console.log(fileList);
this.tempfileList.push({url:response.returnData.list[0].url});
console.log(this.tempfileList);
this.$emit('input', this.tempfileList);
},
pictureRemove(file, fileList){
console.log(fileList);
this.tempfileList = [];
// this.tempfileList = fileList;
console.log(this.tempfileList);
for(var item in fileList){
this.tempfileList.push({url:fileList[item].response.returnData.list[0].url});
}
// this.tempfileList.push({url:file.response.returnData.list[0].url});
this.$emit('input', this.tempfileList);
}
//展示圖片彈窗使能,url賦值
,showPic(file){
this.imageUrl = file.url;
this.showPicDialogVisible = true;
}
},
mounted(){
},
computed: {
}
}
</script>
數據通過父組件中的v-model傳入子組件中props中的同名變量中。不對呀,如果是v-bind:後面接的是子組件中props的中的變量名,等於後面接的是父組件中的變量名,(如::uploadFileData="{'category':'insurance'}")。這樣才能實現父子傳值,但是v-model中並沒有說傳到props 中的哪個變量中,如何匹配呢?
公司的代碼如下:
子組件:
<template>
<div>
<el-upload ref="upload"
action="/api/public/uploadimage"
:data="uploadPicData"
name="upfile"
accept="image/*"
listType="picture-card"
:multiple="false"
:file-list="uploadPicList"
:show-file-list="false"
:on-preview="handlePictureCardPreview"
:on-success="handlePictureSuccess">
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
</div>
</template>
<script>
export default {
data: function () {
return {
uploadPicList: [],
imageUrl: this.value,
dialogImageUrl: '',
dialogVisible: false
}
},
props: ['value',
'uploadPicData',
'show-file-list', 'label'],
methods: {
handlePictureSuccess(res, file, filelist) {
file.name = res.name;
file.url = res.url;
this.imageUrl = file.url;
this.uploadPicList = filelist;
//this.$emit('handleUpload',file.url);
this.$emit('input', file.url);
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
}
},
mounted() {
},
computed: {}
}
</script>
父組件:
</el-form-item>
<el-form-item label="車型視頻" prop="carModelVideo">
<newLifeUploadFile :uploadFileData="uploadPicData"
v-model="tempModel.carModelVideo"></newLifeUploadFile>
</el-form-item>
我們觀察上面的例子可以知道:父組件v-model的變量名和子組件中props沒有相同的,所以肯定不是以同名變量進行匹配,而是將v-mdel中的值傳入props 的value中,後端通過$emit()調用v-model的預設事件input,傳回給父組件,從而實現v-model值的雙向傳遞。
<el-table-column align="center" prop="" label="測試" width="150">
<upload
v-model="this.uploadFileList"
:uploadFileData="{'category':'insurance'}">
</upload>
</el-table-column>
props:[
'uploadFileData'
,'listType'
// ,'uploadFileList'
,'value'
],
methods:{
fileUploadSucc(response, file, fileList){
console.log(this.value);
console.log(fileList);
this.tempfileList.push({url:response.returnData.list[0].url});
console.log(this.tempfileList);
this.$emit('input', this.value);
},
使用emit的時候會報錯:
Cannot use 'in' operator to search for 'uploadFileList' in null"
錯誤原因:The in
operator can only be used to check if a property is in an object. You can't search in strings, or in numbers, or other primitive types.
參考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/in_operator_no_object
emit會在使用的時候用in ,in 操作的不能爲null 或者 undefined。
只要在props 中加多一個和父類同名的變量就不會了
不知道爲什麼
之後又會了,不是很明白
emit改爲:this.event.target.value);
報錯:$event is not defined
如果將this.value通過JSON.parse()轉成json,則報錯如下
VM841:1 Uncaught SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse (<anonymous>)
at VueComponent.fileUploadSucc (0.9ca2d645166ada457aec.hot-update.js:49)
at VueComponent.boundFn (app.js:266086)
at VueComponent.handleSuccess (app.js:116089)
at VueComponent.boundFn (app.js:266086)
at Object.onSuccess (app.js:116611)
at XMLHttpRequest.onload (app.js:116763)
語法部分知道怎麼做了,現在需要將邏輯完善。
圖片的操作只有兩種,刪除和添加
添加:直接將返回的url push到list中即可,如果傳過來的list有初始值也沒有什麼邏輯問題。
刪除:1.將數組清空,再將數據放入:如果初始有值如何處理?
這個時候我們需要知道fileList 和 傳入的value有什麼區別。
value:
fileList:
說明經過fileUploadSucc能夠將push成功,並且fileList只是將包括了所有顯示出來的文件,然後呢?如果想要清空之後再來添加,必須要原來的傳入的list,即value,以及。。想不明白了
情況1:傳入的是null,沒有刪除
情況2:傳入的list有一個項,點擊刪除,清空,fileList放入,因爲fileList已經爲null了,所以不會傳入,循環的時候會報錯嗎?
2.找到對應的項,進行刪除:多用一個項存儲uid