道具被变异(在 django 模板和带有 CDN 的 Vue.js 中)

Posted

技术标签:

【中文标题】道具被变异(在 django 模板和带有 CDN 的 Vue.js 中)【英文标题】:Prop being mutated (in django templates and Vue.js with CDN) 【发布时间】:2020-06-16 09:12:21 【问题描述】:

我有一个小型 django 项目,前端是通过 CDN 用 Vue.js 编码的。所以它只有一个用于 django 的服务器。并且vue被放入django模板中。

DRF 是 web api 的来源。

Django 2.2.10、DRF 3.11.0 和 vue 从 CDN 获取最新版本。

Vuetify(同样来自 CDN)使用 v-app-bar、v-navigation-drawer 和 v-footer 提供 Material UI 设计。

Vuetify 的 v-data-table 也用于两个数据集。 (国家及其城市)

我可以在页面第一次响应时显示数据。

但是,当通过单击按钮关闭抽屉或 v-data-table 的“每页行数”发生更改时,数据会消失。我应该刷新页面以将其取回。

错误是:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "tableData"

found in

---> <LocCountry>
       <VContent>
         <VApp>
           <Root>

列表页:

% extends 'locations/index.html' % % load static% % block content %
<loc-country></loc-country>
% endblock %% block extrascript %
<script>
  Vue.component("loc-country", 
    props: ["tableData"],
    template: `
      <v-data-table
        :headers="headers"
        :items="tableData"
        class="elevation-1"></v-data-table>
    `,
    data() 
      return 
        // tableData: null,
        loading: true,
        errored: false,
        headers: [
           text: "Country", value: "name" ,
           text: "ISO-2", value: "iso2" 
        ]
      ;
    ,
    created() 
      axios
        .get("/api/country/")
        .then(res => (this.tableData = res.data.results))
        .catch(error => 
          console.log(error);
          this.errored = true;
        )
        .finally(() => (this.loading = false));
    
  );
</script>
% endblock %

如果你加载数据,你可以在这里找到项目的 repo,其中包含数据: https://github.com/pydatageek/locations

【问题讨论】:

【参考方案1】:

我在任何地方都找不到它,但这个问题的解决方案非常简单。不要将 tableData 用作道具,而是将其放在 data 属性中,并且不要将其初始化为 null。它应该是一个空数组。

改变列表页面如下:

...
// props: ["tableData"],
....
tableData: []
...

P.S:不知道是什么原因!为什么会这样?

【讨论】:

【参考方案2】:

快速解决方法是使用 data 中的新变量与来自 tableData 的相同数据。

试试这样:

Vue.component("loc-country", 
    props: ["tableData"],
    template: `
      <v-data-table
        :headers="headers"
        :items="newTableData"
        class="elevation-1"></v-data-table>
    `,
    data() 
      return 
        newTableData: this.tableData.slice()
      ;
    ,
    created() 
      axios
        .get("/api/country/")
        .then(res => (this.newTableData = res.data.results))
    
  );

这应该可行。

您可以找到here的更多信息。

【讨论】:

谢谢,但之后又出现了另一个错误: Uncaught SyntaxError: Unexpected token u in JSON at position 0 at JSON.parse () 好的,你也可以看看如何克隆数组here。我更新了我的答案@PyDataGeek slice() 也不起作用。错误是:数据()中的错误:“TypeError:无法读取未定义的属性'slice'”等。我认为,它是关于返回一个空数组。如果你玩回购会有问题吗?克隆和加载虚拟数据最多将持续 3-4 分钟。再次感谢您。 解决了,我在下面写了解决方案。谢谢您的帮助。 @mare96

以上是关于道具被变异(在 django 模板和带有 CDN 的 Vue.js 中)的主要内容,如果未能解决你的问题,请参考以下文章

带有 Nginx 和 uWSGI 的 Django CDN

如何使用带有 Django 模板标签的 amp CSS 星级评分?

道具在 vue js 中发生变异

Vue 道具初始化/变异

避免直接改变道具,因为该值将被覆盖

Vue 2 - 变异道具vue-warn