首页 > 解决方案 > 未在实例上定义,但在渲染期间引用。确保此属性是反应性的,无论是在数据中

问题描述

这是下载Excel.vue:

<template>
    <div class="hello2">
    <button @click="downloadExcesl">Sffubmit</button>
    </div>
</template>

<script>
    import Vue from 'vue';
    import JsonExcel from 'vue-json-excel';

    Vue.component('downloadExcel', JsonExcel);

    export default {
        data() {
            return {
                json_fields: {
                    'Complete name': 'name',
                    'City': 'city',
                    'Telephone': 'phone.mobile',
                    'Telephone 2': {
                        field: 'phone.landline',
                        callback: (value) => {
                            return `Landline Phone - ${value}`;
                        }
                    },
                },
                json_data: [
                    {
                        'name': 'Tony Peña',
                        'city': 'New York',
                        'country': 'United States',
                        'birthdate': '1978-03-15',
                        'phone': {
                            'mobile': '1-541-754-3010',
                            'landline': '(541) 754-3010'
                        }
                    },
                    {
                        'name': 'Thessaloniki',
                        'city': 'Athens',
                        'country': 'Greece',
                        'birthdate': '1987-11-23',
                        'phone': {
                            'mobile': '+1 855 275 5071',
                            'landline': '(2741) 2621-244'
                        }
                    }
                ],
                json_meta: [
                    [
                        {
                            'key': 'charset',
                            'value': 'utf-8'
                        }
                    ]
                ],
            }
        }
    }
</script>

这是App.vue:

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>

<span>asdasdas</span>

      <download-excel

              :data   = "json_data"
              :fields = "json_fields"
              worksheet = "My Worksheet"
              name    = "filename.xls">

          Download Excel (you can customize this with html code!)
          <el-button type="warning">导出excel</el-button>
      </download-excel>

      <img src="download_icon.png">

  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import DownloadExcel from './components/DownloadExcel'

export default {
  name: 'app',
  components: {
    HelloWorld,
    DownloadExcel

  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

但控制台显示这些错误:

      vue.runtime.esm.js?2b0e:619 [Vue warn]: Property or method "json_data" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: found in

    ---> <App> at src/App.vue
           <Root>

https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

json_fieldsdownloadExcesl相同

请帮我解决这个问题。我怎样才能解决这个问题?我搜索了很多。但无法修复它。

请帮我解决这个问题。我怎样才能解决这个问题?我搜索了很多。但无法修复它。

请帮我解决这个问题。我怎样才能解决这个问题?我搜索了很多。但无法修复它。

这也是HelloWorld.vue:

<template>
    <div class="hello">

        <label>File
            <input type="file" id="file" ref="file" v-on:change="handleFileUpload()"/>
        </label>

        <button v-on:click="submitFile()">Submit</button>




        <select name="bank-dropdown" @change="onBankChange($event)" class="form-control">
            <option value="ziraat">ZIRAAT</option>
            <option value="2">On Demand Leave</option>

        </select>

        <select name="currency-dropdown" @change="onCurrencyChange($event)" class="form-control">
            <option value="euro">EURO</option>
            <option value="2">On Demand Leave</option>
        </select>

        <span id="error" style="color: red;">{{message}}</span>
        <button @click="controlExcel">stsrt controll</button>
        <span  style="color: red;">{{temp}}</span>
        <span  style="color: red;">{{temp2}}</span>
<!--        <button @click="downloadExcel">download after control</button>-->
        <div>
            <json-excel :data="dataForExcel"></json-excel>
        </div>
    </div>


</template>

<script>
    import axios from 'axios';

    export default {

        name: 'HelloWorld',
        props: {
            msg: String
        }
        ,
        data() {
            return {
                dataForExcel: [
                    { colA: "Hello", colB: "World" },
                    {
                        colA: "Multi-line",
                        /* Multi-line value: */
                        colB:
                            "This is a long paragraph\nwith multiple lines\nthat should show in a single cell."
                    },
                    { colA: "Another", colB: "Regular cell" }
                ],
                message: 'qq',
                temp: 'wqeqwe',
                temp2: 'wqeqwe2'
                // ,
                // json_fields: {
                //     'Complete name': 'name',
                //     'City': 'city',
                //     'Telephone': 'phone.mobile',
                //     'Telephone 2' : {
                //         field: 'phone.landline',
                //         callback: (value) => {
                //             return `Landline Phone - ${value}`;
                //         }
                //     },
                // },
                // json_data: [
                //     {
                //         'name': 'Tony Peña',
                //         'city': 'New York',
                //         'country': 'United States',
                //         'birthdate': '1978-03-15',
                //         'phone': {
                //             'mobile': '1-541-754-3010',
                //             'landline': '(541) 754-3010'
                //         }
                //     },
                //     {
                //         'name': 'Thessaloniki',
                //         'city': 'Athens',
                //         'country': 'Greece',
                //         'birthdate': '1987-11-23',
                //         'phone': {
                //             'mobile': '+1 855 275 5071',
                //             'landline': '(2741) 2621-244'
                //         }
                //     }
                // ],
                // json_meta: [
                //     [
                //         {
                //             'key': 'charset',
                //             'value': 'utf-8'
                //         }
                //     ]
                // ],
            }

        },
        created() {

            this.bank = "ziraat";
            this.currency = "euro";
            // this.use(cors());
        },
        methods: {
            onBankChange(event) {
                this.bank = event.target.value;
                console.log(" this.bank" + this.bank)
            },
            onCurrencyChange(event) {
                this.currency = event.target.value;
                console.log(" this.currency" + this.currency)
            }
            // ,
            // downloadExcel(){
            //     // const spread = this._spread;
            //     // const fileName = "SalesData.xlsx";
            //     // // const sheet = spread.getSheet(0);
            //     // const excelIO = new Excel.IO();
            //     // const json = JSON.stringify(spread.toJSON({
            //     //     includeBindingSource: true,
            //     //     columnHeadersAsFrozenRows: true,
            //     // }));
            //     // excelIO.save(json, function(_blob_){
            //     //     saveAs(blob, fileName);
            //     // }, function (_e_) {
            //     //     console.log(e)
            //     // });
            //
            // }
            ,
            controlExcel() {
                const self = this;
                // axios.post('http://localhost:8082/control-excel', {}, {
                //     responseType: 'blob'
                // }).then(res => {
                //     let blob = new Blob([res.data], {type: 'application/ms-excel;charset=utf-8'});
                //     let downloadElement = document.createElement('a');
                //     let href = window.URL.createObjectURL(blob); //创建下载的链接
                //     downloadElement.href = href;
                //     downloadElement.download = 'forbidden-words.xls'; //下载后文件名
                //     document.body.appendChild(downloadElement);
                //     downloadElement.click(); //点击下载
                //     document.body.removeChild(downloadElement); //下载完成移除元素
                //     window.URL.revokeObjectURL(href); //释放掉blob对象
                // })
                this.request = {
                    bank: this.bank,
                    cellValuesOfAllExcel: this.cellValuesOfAllExcel,
                    currency: this.currency
                };
                axios.post('http://localhost:8082/control-excel/',
                  this.request,

                ).then((response) => {
                    console.log('SUCCESS!! + response', response);
                    self.message = "successfully controlled and checked. please download"
                    debugger;
                    this.cellValuesOfAllExcelAfterControl = response.data;
                    this.temp = this.cellValuesOfAllExcelAfterControl;
                    console.log('SUCCESS!! +  this.cellValuesOfAllExcelAfterControl',  this.cellValuesOfAllExcelAfterControl);
                })
                    .catch(function (response) {
                        console.log('FAILURE!!+ response', response);
                        self.message = "errorly uploaded"
                    });
            }
            ,
            handleFileUpload() {
                this.file = this.$refs.file.files[0];
                console.log("this.file", this.file)
            },
            submitFile() {
                const self = this;
                let formData = new FormData();

                /*
                    Add the form data we need to submit
                */
                formData.append('file', this.file); //todo get "file" string from external


                /*
                  Make the request to the POST /single-file URL
                */
                axios.post('http://localhost:8082/import/'
                    + this.bank
                    + '/'
                    + this.currency,
                    formData,
                    {
                        headers: {
                            'Content-Type': 'multipart/form-data'
                        }
                    }
                ).then((response) => {
                    console.log('SUCCESS!! + response', response);
                    self.message = "successfully uploaded please start control process"
                    debugger;
                    this.cellValuesOfAllExcel = response.data;
                    this.temp = this.cellValuesOfAllExcel;
                    console.log('SUCCESS!! +  this.cellValuesOfAllExcel',  this.cellValuesOfAllExcel);
                })
                    .catch(function (response) {
                        console.log('FAILURE!!+ response', response);
                        self.message = "errorly uploaded"
                    });
            }

    }}

</script>

<!--&lt;!&ndash; Add "scoped" attribute to limit CSS to this component only &ndash;&gt;-->
<!--<style scoped>-->
<!--h3 {-->
<!--  margin: 40px 0 0;-->
<!--}-->
<!--ul {-->
<!--  list-style-type: none;-->
<!--  padding: 0;-->
<!--}-->
<!--li {-->
<!--  display: inline-block;-->
<!--  margin: 0 10px;-->
<!--}-->
<!--a {-->
<!--  color: #42b983;-->
<!--}-->
<!--</style>-->

标签: vue.js

解决方案


json_data并且json_fields都在您的DownloadExcel.vue组件中声明data,而不是在您的App.vue. 只需从模板声明中删除它:

<!-- App.vue -->
<download-excel>
  <!-- ... -->
</download-excel>

或者移动到 App.vue

如果您希望将两个字段从父级传递给子级,只需将其声明为道具

我建议你看看 vue 数据流是如何工作的


推荐阅读