Ошибка: шаблоны должны отвечать только за сопоставление состояния с пользовательским интерфейсом. Избегайте размещения тегов с побочными эффектами в ваших шаблонах, таких как <script>

Я использую Vuejs, и я продолжаю получать это предупреждение в консоли. Из-за этого предупреждения данные не загружаются. Я проверил код для нежелательных тегов, но не нашел.

Это из-за кода javascript или у меня что-то не так в моем html?

Вот мой код:

HTML

<div class="row">
    <div class="col-sm-12" style="margin-top: 20px;">
        <form class="form-inline" method="GET" action=".">
            <div class="col-sm-3" style="float: right;"><h4>Date:</h4>
                <input class="form-control" style="padding-bottom:0px;" type="text" id="datepicker" readonly="true" name="date" value="2016-06-30">
                <input type="submit" class="btn btn-primary btn-sm" value="Submit" >
            </div>

        </form>
        <div class="col-sm-2" style="float: right; margin-top:40px;">
            <button class="btn btn-info" type="button" id="csv_export">Click to Export</button>
        </div>
    </div>
    <div class="col-sm-12" style="margin:20px;">
        <table class="table table-sm table-striped table-bordered" id="absent-list">
            <thead>
                <tr>
                    <th>#</th>
                    <th style="text-align: center; font-size: 15px;">Full Name</th>
                    <th style="text-align: center; font-size: 15px;">Section</th>
                    <th style="text-align: center; font-size: 15px;">Person Called</th>
                    <th style="text-align: center; font-size: 15px;">Person Relation</th>
                    <th style="text-align: center; font-size: 15px;">Phone Number</th>
                    <th style="text-align: center; font-size: 15px;">Absent Reason</th>
                    <th style="text-align: center; font-size: 15px;">Remarks</th>
                    <th></th>
                </tr>
            </thead>
            <tbody>
                <tr v-show="loading" class="text-center">
                    <td colspan="7">
                        <i class="fa fa-spinner fa-spin fa-4x"></i>
                    </td>
                </tr>
                <tr v-for="record in absent_followback_records">

                    <td style="text-align: center; font-size: 15px;" scope="row"> {{$index + 1}}</td>
                    <td  style="text-align: center; font-size: 15px;">{{record.student_name}}</td>
                    <td  style="text-align: center; font-size: 15px;">{{record.student_section}}</td>
                    <td  style="text-align: center;">{{record.person_called}}</td>
                    <td  style="text-align: center;">{{record.person_relation}}</td>
                    <td  style="text-align: center;">{{record.phone_number}}</td>
                    <td  style="text-align: center;">{{record.absent_reason_name}}</td>
                    <td  style="text-align: center;">{{record.remarks}}</td>
                    <td  style="text-align: center;"><a href="#" v-on:click="editAbsentFollowbackRecord($index)" data-toggle="modal" data-target="#absent-followback-edit"> Edit </a></td>

                </tr>
            </tbody>
        </table>

    </div>
</div>

<script src="/static/js/jquery-ui.min.js"></script>
<script src="/static/js/jquery.plugin.min.js"></script> 
<script src="/static/js/jquery.datepick.min.js"></script>
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
<script src="/static/js/csrftoken.js"></script>
<script src="/static/js/jquery.TableCSVExport.js"></script>

<script type="text/javascript">

    var absentFollowbackListAPiUrl = "/student/api/absent/followback/list/11/";
    var absent_reason = jQuery.parseJSON('[{"model": "studentprofile.absentreason", "pk": 1, "fields": {"created": "2016-05-08T06:09:42.410Z", "modified": "2016-05-08T06:09:42.410Z", "reason_name": "sick"}}, {"model": "studentprofile.absentreason", "pk": 2, "fields": {"created": "2016-05-08T06:09:42.416Z", "modified": "2016-05-08T06:09:42.416Z", "reason_name": "arrived late"}}, {"model": "studentprofile.absentreason", "pk": 3, "fields": {"created": "2016-05-08T06:09:42.419Z", "modified": "2016-05-08T06:09:42.419Z", "reason_name": "work at home"}}, {"model": "studentprofile.absentreason", "pk": 4, "fields": {"created": "2016-05-08T06:09:42.423Z", "modified": "2016-05-08T06:09:42.423Z", "reason_name": "public holiday"}}]');
    var profile_value = false;

</script>
<script type="text/javascript" src="/static/js/student/student-followback.js"></script>

файл absent-followback.js

$(function() {
    $( "#datepicker" ).datepick({dateFormat: 'yyyy-mm-dd'});
});

$('#csv_export').click(function (e) {
    e.preventDefault();
    $('#absent-list').TableCSVExport({
        delivery: 'download',
        filename: 'absent-list(' + $( "#datepicker" ).val() + ').csv'
    });
});

var vm = new Vue({
        el: 'body',
        data: {
            absent_followback_records: [],
            followbackRecordIndex: 'off',
            absentReasonList: absent_reason,
            loading: false,
            currentData: {},
            profile: profile_value,
            listApiUrl: absentFollowbackListAPiUrl
        },
        methods: {
            populateData: function(api_url){
                var self = this;
                $.get(api_url, function(data){
                    self.absent_followback_records = data;
                    self.loading = false;
                });
            },
            getAbsentFollowbackRecord: function () {
                var self = this;
                self.loading = true;
                var date = $( "#datepicker" ).val();
                var api_url = self.listApiUrl + '?date=' + date;
                self.populateData(api_url);
            },
            getProfileAbsentFollowbackRecord: function (event) {
                var self = this;
                self.loading = true;
                var expanded = $(event.target).attr('aria-expanded');
                if (expanded == 'false'){
                    $(event.target).html('Hide Details');
                    var studentId = $(event.target).attr('studentId');
                    var api_url = self.listApiUrl + '?student_id=' + studentId;
                    self.populateData(api_url);
                }
                else{
                    $(event.target).html('Show Details');
                }
            },
            editAbsentFollowbackRecord: function (followbackRecordIndex) {
                var self = this;
                self.currentData = self.absent_followback_records[followbackRecordIndex];
                self.followbackRecordIndex = followbackRecordIndex;
            },
            updateAbsentFollowbackRecord: function (followbackRecordIndex){
                var self = this;
                var updateData = self.currentData;
                var absent_date = updateData.date;
                var student_id = updateData.student;
                var post_url = updateData.update_url;
                var person_called = updateData.person_called;
                var person_relation = updateData.person_relation;
                var phone_number = updateData.phone_number;
                var absent_reason = updateData.absent_reason;
                var remarks = updateData.remarks;
                if (person_called){
                    var data = {
                        student: parseInt(student_id),
                        date: absent_date,
                        person_called: person_called,
                        person_relation: person_relation,
                        phone_number: phone_number,
                        absent_reason: parseInt(absent_reason),
                        remarks: remarks
                    };
                    $('#updateAbsentFollowback').html('<i class="fa fa-spinner fa-spin"></i> Saving').attr('class', 'btn btn-primary disabled');
                    $.ajax({
                        url: post_url,
                        type: "PUT",
                        data: JSON.stringify(data),
                        dataType: 'json',
                        contentType: "application/json",
                        success: function(responseData) {
                            $('#updateAbsentFollowback').html('Save').attr('class', 'btn btn-success');
                            if (self.profile == true){
                                api_url = self.listApiUrl + '?student_id=' + student_id;
                                self.populateData(api_url);
                            }
                            else{
                                self.getAbsentFollowbackRecord();
                            }
                        },
                        error: function( xhr, status, errorThrown ) {
                        console.log(errorThrown);
                        }
                    });
                }
            }

        },
        ready() {
            if (this.profile != true){
                this.getAbsentFollowbackRecord();
            }
        }
    })

Ответ 1

Я думаю, что ответ в вашем вопросе. Просто избавьтесь от всех тегов <script> в шаблоне, поместите их вне шаблона.

В этом случае вы используете body в качестве шаблона, и вы помещаете скрипты внутри своего шаблона (body)

Простым решением является изменение el: 'body' на el: '#wrapper' и изменение html на

<body>
<div id="wrapper">
...
</div>
<script ... >
<script ... >
</body>

Ответ 2

Убедитесь, что у вас есть закрывающий тег в корневом элементе. Я просто провел последние 6 часов, систематически снимая вещи и вытягивая волосы. Оказывается, я удалил свое закрытие в какой-то момент, и Vue интерпретировал

Ответ 3

Это связано с тегом script в области приложения. В моем случае это было из-за Google captcha, который был в моем объеме. Google captcha iframe содержит тег script

Ответ 4

пара тегов несоответствия (div, span) может вызвать эту ошибку.

<div id="app">
    <div>{{ a }} </span>
</div>