Приложение Vue извлекает данные API, и объекты кажутся жабами в моем шаблоне, но текст не отображается

#javascript #django #api #vue.js

#javascript #django #API #vue.js

Вопрос:

Я создал приложение Vue, которое извлекает данные из моего Django REST API и отображает их на странице. Данные состоят из списка объектов, которые напоминают {‘name’: портал Уитни, ‘parent’: Национальный лес Иньо’, ‘camp_id’: 232123}

У меня есть поле ввода, в которое пользователи могут вводить текст, и приложение Vue будет динамически отображать все объекты, содержащие вводимый текст.

Похоже, что приложение загружает объекты в шаблон, но ни один из желаемых текстов не отображается. Я хочу показать атрибуты camp, такие как имя для каждого объекта.

Я прикрепил случайную строку «Я ЗДЕСЬ!» в html к каждому сгенерированному объекту, поэтому я могу видеть, сколько объектов отображается одновременно. Однако это единственный текст, отображаемый для каждого объекта.

Когда я ввожу в свое поле ввода, количество объектов (и экземпляров «Я ЗДЕСЬ!») меняется. Объекты реагируют так, как ожидалось (я знаю, какой текст ввести в поле, чтобы отображался только один объект). Например, если я введу ‘Inyo’, останется только один объект (потому что только один из объектов в моей базе данных имеет ‘Inyo National Forest’ в качестве родительского атрибута.

Когда ничего не введено, количество отображаемых объектов совпадает с числом в базе данных. Когда я заглядываю в инструменты разработчика> Сеть, я вижу, что был выполнен успешный запрос API GET, и я вижу все данные в ответе.

Я не получаю ошибок в консоли. Кто-нибудь еще сталкивался с этой проблемой раньше и решал ее?

Я использую Django, Django REST Framework и Vue JS

Приложение Vue

 const App = new Vue({
    el: '#show-camps',
    data() {
        return {
            campgrounds: [],
            search: '',
            test: 'test',
        };
    },
    async created() {
        const response = await fetch('http://localhost:8000/api/campgrounds/');
        this.campgrounds = await response.json();
    },
    methods: {
    },
    computed: {
        filteredCamps: function(){
            return this.campgrounds.filter((camp) => {
                return camp.parent.match(this.search);
            });
        }
    }
})
  

Мой шаблон

 <!DOCTYPE html>
{% extends 'base/base.html' %}
{% load static %}
{% block title %}Campground List{% endblock %}
{% block content %}
<div class="container-fluid">
    <div class="row justify-content-center">
        <div class="head col-12 col-sm-10 col-md-7 text-center solid">
            <h1>List of all campgrounds</h1>
            <p>Here is a list of some campground IDs that I've collected.</p>
            <hr>
        </div>
    </div >

    <!--Campground ID Display-->
    <div class="row justify-content-center">
        <div class=" col-12 col-sm-10 col-md-7 text-center solid">
            <div id="show-camps">
                <input type="text" v-model="search" placeholder="search campgrounds"/>
                <div v-for="camp in filteredCamps">
                    <div>
                        {{camp.name}}
                        {{camp.camp_id}}
                        {{camp.parent}}
                        {{ test }}
                    </div>
                    I'm HERE!
                    {{camp.name}}
                    {{camp.camp_id}}
                    {{camp.parent}}
                    {{ test }}
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}

{% block extra_js %}
    <script type="text/javascript" src="{% static 'js/vue.js' %}"></script>
    <script type="text/javascript" src="{% static 'js/main.js' %}"></script>
{% endblock %}
  

Ответ API

 [
    {
        "camp_id": "232122",
        "name": "WHITE BRIDGE",
        "parent": "Dixie National Forest"
    },
    {
        "camp_id": "232123",
        "name": "WHITNEY PORTAL",
        "parent": "Inyo National Forest"
    }
]
  

Комментарии:

1. К вашему сведению, вы, вероятно, не хотите использовать String.prototype.match() . Попробуйте использовать String.prototype.includes() вместо

2. Я нашел лучший вариант, чем изменение разделителей Vue. Смотрите ниже

Ответ №1:

Проблема в том, что и Vue, и Django используют один и тот же синтаксис шаблона mustache для отображения переменных, поэтому все ваши {{ camp.name }} биты пытаются отобразить переменные на стороне сервера.

Способ исправить это должным образом — сказать Django не обрабатывать теги с помощью verbatim тега

 {% verbatim %}
<div id="show-camps">
  <!-- all your Vue template code goes here -->
</div>
{% endverbatim %}
  

Другой вариант — настроить Vue с помощью delimiters опции. Например

 const App = new Vue({
  el: '#show-camps',
  delimiters: ["[[", "]]"],
  // etc
})
  

а затем в вашем HTML-шаблоне

 <div>
  [[ camp.name ]]
  [[ camp.camp_id ]]
  [[ camp.parent ]]
</div>