Vue 错误“模板应该只负责将状态映射到 UI。”

Posted

技术标签:

【中文标题】Vue 错误“模板应该只负责将状态映射到 UI。”【英文标题】:Vue error "Templates should only be responsible for mapping the state to the UI." 【发布时间】:2021-04-04 01:45:03 【问题描述】:

我正在使用 Django webpack-loader 在我的 Django 模板中加载 VueJS 组件,基本上我有以下 django 模板:

myTemplate.html(这是我调用 vue 的 Django 模板)

% load render_bundle from webpack_loader %
<!DOCTYPE html>
<html lang="en">

% load static %
% block content %
<head>
...
</head>

<body>
    <div id="app">

    <div id="someDjangoStuff">
      ...
    </div>

    <formComponent></formComponent>
    <anotherVueComponent></anotherVueComponent>
    
    <div id="someDjangoStuff2">
      ...
    </div>

    </div>
<body>

% endblock %

</html>

组件是基本形式,像这样:

<template>
  <div>
        
    <form @submit.prevent="formSubmit()">

    <input type="text" class="form-control" v-model="amount">
    <br>
    <input type="text" class="form-control" v-model="price">

    <button class="btn btn-primary" >Submit</button>
    
     </form>
  </div>

</template>

所以基本上我在这里做的是:

    我加载了一个 Django 模板 我使用 &lt;div id="app"&gt;&lt;/div&gt; 加载 Vue 应用程序 我只加载我需要的组件,而不是加载整个 Vue 应用程序,并在 &lt;div id="app"&gt;&lt;/div&gt; 中加载其他 html。

问题是,在我的控制台中,我会收到以下错误:

[Vue warn]: Error compiling template:

Templates should only be responsible for mapping the state to the UI.

我确定这是因为我正在加载 Vue 应用程序,并且在应用程序内部我还加载了其他 html 标记。现在这个错误没有任何影响,这个设置似乎工作正常,但我怀疑这是否是使用 Vue 的正确方法。

    是否有任何方法可以抑制错误或以其他方式执行此操作而不会出现错误? 它会因为这不是我应该使用 Vue 的方式而产生问题吗?

【问题讨论】:

您的someVueComponentanotherVueComponent 代码是什么? 这是非常基本的组件,只有一些 HTML,但它们没有任何可能导致错误的脚本或东西 可能重复:***.com/questions/38119088/… 您的错误似乎是您在不提交更新的情况下操纵状态。你需要阅读更多关于 Vuex 的信息。 【参考方案1】:

好的!

如果你想在 Vue 编译的应用上下文之外使用 Vue 组件,那么你需要:

在 vue 配置中包含 runTimeCompiler 并注意这将使您的构建增加大约 200kb
// vue.config.js

module.exports = 
  runtimeCompiler: true

不要在构建时渲染 JS 应用程序
// main.js
// Vue 2 
new Vue(
  el:"#app",

  // render: h => h(App) that what triggers your build error
  render: process.env.NODE_ENV === 'development'?h => h(App):'' //render only while testing
);

// Vue3
const app = createApp()
app.mount('#app')

// don't forget to register global components 

在您的基本模板中
<!DOCTYPE html>
<html>
<head>

% load render_bundle from webpack_loader %
% load webpack_static from webpack_loader %
% render_bundle 'app' 'css' %
</head>

<body>

    <div id="app">
    % block content %
    % endblock %
    </div>

    % render_bundle 'app' 'js' %
    % render_bundle 'chunk-vendors' 'js' %

</body>
</html>

然后通常像往常一样从基本模板 Django 扩展
% extends "base.html" %


% block content %
<your-lovely-vue-component></your-lovely-vue-component>
% endblock %

为了完整性:

您可能根本不使用 django-webpack-loader 并且依赖于 collectstatic 命令,只需在 django settings.TEMPLATES.DIRS 中包含您的 vue 应用程序路径,并在 vue.config.js 中将 filenameHashing 设置为 false。

但是我个人使用这个包并且效果很好,注意 webpack-bundle-tracker 最新版本有一些问题,我推荐 ^0.4.3 。

下面的视频并没有完全那样说,但是在某个地方你会更好地理解将 Vue 与 MVC 框架集成。 https://laracasts.com/series/whats-new-in-vue-3/episodes/14

干杯?

【讨论】:

这是一个非常有帮助的答案!万分感谢!如果允许,我有一个问题:所以在这种情况下,我在这个 HMTL 页面中加载 vue 应用程序,这是我的 django 项目中的一个页面。现在假设我需要在同一个项目的另一个页面中使用 Vue:我应该创建一个新的 vue 应用程序,还是可以使用同一个应用程序但只使用我需要的组件?当然我不会用它来做 SPA 所以 TL;DR 是:跨不同的 Django 模板加载相同的 Vue 应用程序是否可以,但在每个页面中我只加载该页面所需的组件? 只要你不需要 spa 就不要渲染应用程序,你可以随意使用它,因为你包含的运行时编译器已经只是扩展了 Django 中的基本模板。换句话说,您已经准备好在 Django 模板中操作 DOM 的 vue 应用程序。是的,如果您仍然想使用 spa,只需在另一个 DOM 元素 id 上渲染,您就可以根据需要创建应用程序。【参考方案2】:

你不能在这样的 Django 模板中使用 Vue 组件。你需要把所有的Vue代码放在一个JS文件中,然后把这个JS文件导入Django。

在您的 Django 模板中,您可能有一个类似的容器

<div id="app"></div>

在您的 Vue 代码中,您将 Vue 应用程序附加到该容器,例如:

new Vue(
  render: h => h(App),
).$mount('#app')

在 django 模板中根本没有放置任何 Vue 代码。这一切都需要在 Vue 中,然后一个链接的 javascript 文件将在容器内插入所有相关代码。

附带说明,django-webpack-loader 不再维护。我创建了一个名为 django-manifest-loader 的包来替换它,它将满足您的需求。不幸的是,我还没有写过关于在 Vue 中使用它的文章,但是如果你使用的是 webpack,那么大部分文档都会保留。 Blog post walking you through setup is here

【讨论】:

非常感谢您的回答!和我在做什么有什么区别?在我的模板中,我有一个 ,就像你说的那样,但不是渲染整个 vue 应用程序,我只在我需要它们的地方渲染特定组件,并且我我已经像你提到的那样将应用程序附加到容器 Webpack-loader 没有被维护确实是一个问题,我很高兴你提供了一个解决方案!您是否打算在未来为 Vue 创建指南?我想移动到清单,但我担心我可能会在我的设置中破坏某些东西 @Jack022 您需要比 *** 提供的更具体的帮助。您无法渲染 vue 应用程序的特定部分。 Vue 应用程序是一个完整的单元,您可以将其嵌入或不嵌入 Django。整个 Vue 应用程序都挂载到 div 中,并且您不能在 Django 模板中嵌入 Vue 标签。当我为 Django/Vue 编写教程时,我会留下另一条评论。 里面应该什么都没有 所以基本上我做错的只是在 中添加其他标签,而我应该只有 或 ?

以上是关于Vue 错误“模板应该只负责将状态映射到 UI。”的主要内容,如果未能解决你的问题,请参考以下文章

Vuejs 和 laravel - 模板应该只负责映射 UI 的状态

vue报以下错误可能原因

Vue.js + vue-resource + vue-router = 词法声明错误?

vue 错误警告?

vue打包之后图片路径错误问题

vue计算属性getter错误=> [Vue警告]:渲染错误:“TypeError:无法读取未定义的属性'periodNum'”[重复]