【问题标题】:"$attrs is readonly","$listeners is readonly","Avoid mutating a prop directly""$attrs 是只读的","$listeners 是只读的","避免直接改变一个 prop"
【发布时间】:2018-09-10 04:03:37
【问题描述】:

我是 Vue 的新手。我正在尝试开发一个聊天应用程序,其中朋友列表将显示在左侧菜单上,聊天框将显示在正文中。我正在使用 ajax 调用加载朋友列表并根据朋友 ID 路由到聊天框。这是代码示例。

<div class="chat-container clearfix" id="chat">
    <div class="people-list" id="people-list">
        <chatlist-component></chatlist-component>
    </div>

    <div class="chat">
       <router-view></router-view>
    </div>
</div> 

聊天列表组件将从服务器加载好友列表。这是我的 app.js 文件;

Vue.use(VueRouter)

const router = new VueRouter({
  routes,
  linkActiveClass: "active"
});


    import ChatComponent from './components/ChatComponent';
    const routes = [
      { path: '/chat/:id/:name', component: ChatComponent , name: 'chat'}
    ];
    Vue.component('chatlist-component', require('./components/ChatlistComponent.vue'));

    const app = new Vue({
        el: '#chat',
        router
    });

及聊天列表组件模板代码

<li class="clearfix" v-for="user in users">
                <img :src="baseUrl+'/img/default_image.jpeg'" alt="avatar" class="chat-avatar rounded-circle" />
                <router-link class="about" :to="{ name: 'chat', params: { id: user.id, name:user.name }}">
                    <div class="name">{{user.name}}</div>
                    <div class="status">
                        <i class="fa fa-circle online"></i> online
                    </div>
                </router-link>

            </li>

在我切换到另一个用户之前它工作正常。当我单击聊天列表组件中的任何路由器列表时,它可以正常工作,但会向控制台抛出以下错误。

app.js:19302 [Vue warn]: $attrs is readonly.

found in

---> <RouterLink>
       <ChatlistComponent> at resources/assets/js/components/ChatlistComponent.vue
         <Root>

app.js:19302 [Vue warn]: $listeners is readonly.

found in

---> <RouterLink>
       <ChatlistComponent> at resources/assets/js/components/ChatlistComponent.vue
         <Root>

app.js:19302 [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: "to"

提前致谢

【问题讨论】:

    标签: javascript vuejs2 vue-component


    【解决方案1】:

    首先,这些错误仅在非生产版本中出现,但它们表明应该在生产发布之前解决问题。

    如果加载了多个 Vue 实例,则会显示 $attrs、$listeners 和其他警告。据我了解,这通常是由于以下原因之一:

    • 它正在通过 webpack 加载/打包到包中,并且也在外部加载(不是通过 webpack)
    • 它被你包含的东西加载(例如vuetifyvue-test-utilsvue-cli-electron-builder)一种方式和你的webpack配置另一种方式(例如绝对路径与相对路径,common.js与esm.js vue文件, runtime-only vue vs compiler+runtime vue)

    如果您单击该行(在上面的输出中是 app.js:19302)并在消息发出的位置放置一个断点,您可以在堆栈回溯中查看模块列表以查看是否有超过列出了 Vue 的一条路径。例如,看下面的前三个模块有不同的路径(但都是 Vue 的一部分): 如果您看到 Vue 以两种或多种不同的方式出现,则表明加载了多个 Vue 实例。 Vue 只支持单个实例,如果加载多个实例,就会产生这些错误消息。

    上面包含几个问题的链接,Vuetify 问题是我提交的问题。在那种情况下,Vuetify 需要 Vue 并且加载它的方式与我不同。通常修复方法是检查指定(或未指定)Vue 的 webpack 配置,并尝试使其与包含其他副本的方式相匹配(例如,绝对路径与相对路径,或打包与外部)。

    【讨论】:

    • 你也可以运行yarn why vue(如果使用yarn)来查看哪些包可能在复制vue。
    • 这是刚刚添加的付费课程的新部分,但我会包含链接以防有人订阅。另外,值得注意的是,本课的主题是 $attrs 在 Vue 3 中已经完全改变。请参阅新文档和本课程关于从 2 迁移到 3,特别是本课,称为 The New $attrs:@987654325 @
    • 对我来说,问题正是你所说的,我从 index.html 文件中删除了额外的导入,错误消失了,它创建了 2 个实例。谢谢。
    • 也看到了这个,但想补充一下,这是因为我在一个包中进行开发,并使用yarn link 在另一个应用程序中测试该包的实现。最初的包依赖于 Vue 2.x,我的应用程序也是如此。一旦我将包真正更新/导入到我的应用程序中,这就不成问题了。
    【解决方案2】:

    将此添加到 vue.config.js,对我有用。

    const path = require('path')
    
    module.exports = {
      configureWebpack: {
        externals: {
          vue: 'Vue'
        }
      }
    }
    

    【讨论】:

    • 这告诉 webpack 你想把它从捆绑过程中排除。所以做 import Vue from 'vue'; 不会做任何事情。这对你有用,因为你是从其他地方获得 vue,比如你的 html 中的脚本标签。
    【解决方案3】:

    我遇到了同样的问题。对我来说,当我使用

    安装本地模块时
    yarn add ../somemodule --force
    

    似乎这个命令将复制整个模块目录,包括 node_modules 子目录。这会导致相同版本的“vue”模块重复。在浏览器开发工具中,我可以看到模块的多个来源。

    对我来说,解决方案是每次安装本地模块后手动删除 node_modules。

    【讨论】:

    • 这也是我使用npm install &lt;folder&gt;时的问题,例如npm install ../my-local-lib
    【解决方案4】:

    就我而言,我是从一个不使用 VueCLI 的项目迁移而来的。在那个项目中,我从 CDN &lt;script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"&gt;&lt;/script&gt; 导入了 vue。在我的 Vue CLI 项目中,我已将整个 index.html 文件复制并粘贴到 Public 文件夹中。 Vue CLI 有自己的导入 vue 的方式,所以它们发生了冲突。我只是删除了脚本,问题就解决了。

    【讨论】:

      【解决方案5】:

      这个错误发生在我身上,因为我在我的项目中使用了 Git 子模块并且我有以下文件夹:

      • ./node_modules - 这是针对主要项目的。这些 node_modules 中安装了 vue。
      • ./my_git_submodules/vue_design_system/node_modules - 提供基本组件的设计系统(也使用 vue)。 这里也安装了Vue!!

      所以因为两者:

      • ./node_modules/vue
      • ./my_git_submodules/vue_design_system/node_modules/vue

      存在,运行 npm run servevue-cli-service build 下面)构建了两个 Vue 实例。这是 一个非常讨厌的问题,因为它在某些情况下会破坏反应性 (即,您单击一个按钮,没有任何反应 - 您只是得到 $listeners 只读错误)

      快速修复:
      删除子文件夹(vue_design_system)中的 node_modules 并运行 npm run serve 对我有用。

      长期修复:
      您可能需要通过在 vue.config.js 中添加规则来使 Webpack 忽略嵌套的 node_modules 文件夹

      【讨论】:

        【解决方案6】:

        我遇到了和上面一样的问题。我正在使用 git 子模块并且我使用过

        yarn add ./submodule
        

        不知何故,最终在 ./submodule 目录中出现了一个 node_modules 目录,这让一切变得混乱。

        它正在加载两个 Vue 实例。

        【讨论】:

          【解决方案7】:

          这也可能发生,因为您使用 npm link 来使用未发布的 vue 包。与@walnut_salami 的解释基本一致。

          解决此问题的方法是移至 this way 以包含未发布的模块。

          【讨论】:

            【解决方案8】:

            看起来好像有很多可能的答案。

            我手动向节点文件夹添加了一个 npm 包,问题是缺少 npm i 命令。使用 install 命令后,一切正常。

            【讨论】:

              【解决方案9】:

              在我的例子中,这个错误是在模块联合我的组件之后出现的。 我通过将组件接收器中的 vue 共享给组件供应商来解决它。 例如

              webpack.config.js 
              module.exports = { 
                 plugins: [
                      
                  new ModuleFederationPlugin({
                    name: "dashboard",
                    remotes: {
                      web_common: "web_common@http://localhost:8081/remoteEntry.js"
                    },
                    shared: {
                      vue: { // this solved my issue.
                        eager: true,
                        singleton: true,
                        requiredVersion: deps.vue
                      },
                    }
                  }),
                 ]
              
              }
              

              【讨论】:

                猜你喜欢
                • 2021-11-17
                • 2021-07-26
                • 2019-02-12
                • 2019-04-11
                • 2018-09-30
                • 1970-01-01
                • 2020-09-11
                • 2017-07-25
                • 1970-01-01
                相关资源
                最近更新 更多