【问题标题】:[Vue warn]: $attrs is readonly. [Vue warn]: $listeners is readonly[Vue 警告]:$attrs 是只读的。 [Vue 警告]:$listeners 是只读的
【发布时间】:2019-02-12 06:13:54
【问题描述】:

我对 Vuejs 比较陌生,每次按键时都会收到以下警告:

[Vue warn]: $attrs is readonly.

found in

---> <RouterLink>
       <HeaderComponent> at src\components\Header_Component.vue
         <App> at src\App.vue
           <Root>

[Vue warn]: $listeners is readonly.

found in

---> <RouterLink>
       <HeaderComponent> at src\components\Header_Component.vue
         <App> at src\App.vue
           <Root>

这些警告似乎根本不会影响可用性。我没有在任何地方调用 $attrs 或 $listeners,我不确定这些警告来自哪里。

这是我的 Header_Component.vue:

<template>
    <header class="header">
        <div class='nav nav-side nav-oneLine'>
            <a class='nav-link' href='#'><router-link @click.native="addClass(), setLogoTrue('project')" to='/Projects'>PROJECTS</router-link></a>
            <a class='nav-link' href='#'><router-link @click.native="addClass(), setLogoTrue('blog')" to='/Blog'>BLOG</router-link></a>
            <a class='nav-link' href='#'><router-link @click.native="addClass(), setLogoTrue('aboutme')" to='/Aboutme'>ABOUT ME</router-link></a>
            <a class='nav-link' href='#'><router-link @click.native="addClass(), setLogoTrue('resume')" to='/Resume'>RESUME</router-link></a>
        </div>
    </header>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
    data() {
        return{
            logoTrue: <Object> {
                'main': true,
                'project': false,
                'blog': false,
                'aboutme': false,
                'resume': false
            },
            main: <boolean>true,
            header: <any>"",
            image: <any>"",
            h1: <any>"",
            h2: <any>"",
            nav: <any>"",
            logos: <any>"",
            break: <any>"",
        }
    },
    components: {
        insta, facebook, github, codepen, mainLogo, mainLogoSmall, test, projectsLogo, blogsLogo, aboutmeLogo, resumeLogo
    }
    methods:{
        addClass(){
            if (document.querySelector('.h2Active') == null && document.querySelector('.header_top') == null) {
                this.add_newClasses()
                this.emit_finished(true)
                setTimeout(() => {
                    this.remove_separators()
                }, 800) 
            } else {
                console.log('classes already exist!')
                this.$emit('reloadBackToTop')
            }        
        },
        remove_separators() {
            let breaker = document.getElementsByClassName('separator')

            while (breaker[0]) {
                this.nav.removeChild(breaker[0])
            }
        },
        setLogoTrue(target) {
            for (var key in this.logoTrue) {
                if (this.logoTrue.hasOwnProperty(key)) {
                    if (key == target) {
                        this.logoTrue[key] = true
                    } else {
                        this.logoTrue[key] = false
                    }
                }
            }
        },
        apply_topClasses() {
            this.header.classList.add('header_top')
            this.image.classList.add('imgStatic_top')
            this.h1.classList.add('h1_name_top')
            this.h2.classList.add('h2_name_top')
            this.logos.classList.add('logo_links_top')
            this.nav.classList.add('nav-side_top')

            this.emit_finished(false)
        },
        add_newClasses() {
            if (window.innerWidth < 1060) {
                this.nav.classList.add('navActive_small')
                this.image.classList.add('imgActive_small')
            } else {
                this.nav.classList.add('navActive')
                this.image.classList.add('imgActive')
            }
            this.logos.classList.add('logo_linksActive')
            this.header.classList.add('headerActive')
            this.h1.classList.add('h1Active')
            this.h2.classList.add('h2Active')

            this.image.classList.remove('imgStatic')
        },
        emit_finished(delay:boolean) {
            if (delay) {
                setTimeout (() => {
                    this.$emit('finishedLoading')
                    console.log('finished_loading')
                }, 2000)
            } else {
                console.log('here')
                this.$emit('finishedLoading')
            }
        },
        adjust_clientWidth() {
            if (window.innerWidth < 1060) {
                // this.remove_separators()
                let bigActive = document.getElementsByClassName('big-nav')
                let navActive = document.getElementsByClassName('navActive')
                if (bigActive.length > 0) {
                    this.nav.classList.add('small-nav')
                    this.nav.classList.remove('big-nav')

                    this.image.classList.add('small-img')
                    this.image.classList.remove('big-img')

                } else if (navActive.length > 0) {
                    this.nav.classList.add('small-nav')
                    this.nav.classList.remove('nav-side')
                    this.nav.classList.remove('navActive')

                    this.image.classList.add('small-img')
                    this.image.classList.remove('imgActive')
                }
            } else {
                let smallActive = document.getElementsByClassName('small-nav')
                let smallnavActive = document.getElementsByClassName('navActive_small')
                if (smallActive.length > 0) {
                    this.nav.classList.add('big-nav')
                    this.nav.classList.remove('small-nav')

                    this.image.classList.add('big-img')
                    this.image.classList.remove('small-img')                     

                } else if (smallnavActive.length > 0) {
                    this.nav.classList.add('big-nav')
                    this.nav.classList.remove('nav-side')
                    this.nav.classList.remove('navActive_small')

                    this.image.classList.add('big-img')
                    this.image.classList.remove('imgActive_small')                    
                }
            }
        }
    },
    created: function() {
        window.addEventListener('resize',this.adjust_clientWidth)
    },
    mounted: function() {
        this.header = document.getElementsByClassName('header')[0]
        this.image = document.getElementsByClassName('img')[0]
        this.h1 = document.getElementsByClassName('h1_name')[0]
        this.h2 = document.getElementsByClassName('h2_name')[0]
        this.nav = document.getElementsByClassName('nav')[0]
        this.logos = document.getElementsByClassName('logo_links')[0]  

        if (window.location.hash != "#/") {
            this.remove_separators()
            if (window.location.hash == "#/Projects") {
                this.setLogoTrue('project')
            } else if (window.location.hash.includes("#/Blog") || window.location.hash.includes("#/blog")) {
                this.setLogoTrue('blog')
            } else if (window.location.hash == "#/Aboutme") {
                this.setLogoTrue('aboutme')
            } else if (window.location.hash == "#/Resume") {
                this.setLogoTrue('resume')
            }
            this.apply_topClasses()
        }
    }
})
</script>

<style lang="css" scoped>
(...)
</style>

感谢您的帮助!

【问题讨论】:

标签: javascript vue.js vuejs2


【解决方案1】:

正如您可能已经从另一个问题中弄清楚的那样,我在这里发布一个答案以节省其他人的时间。

此类错误的问题通常是因为您多次导入 Vue。首先在您的主应用程序中,然后在您的组件文件中。 因此,从 Header_Component.vue 中删除 import Vue from 'vue' 行将解决问题。 但是你必须改变你声明组件的方式:

<script lang="ts">
//import Vue from 'vue' <-- Commented the import line

export default {  // <-- Removed Vue.extend()
    data() {
        return{
            logoTrue: <Object> {
                'main': true,
                'project': false,
                'blog': false,
                'aboutme': false,
                'resume': false
            },
            main: <boolean>true,
            header: <any>"",
            image: <any>"",
            h1: <any>"",
            h2: <any>"",
            nav: <any>"",
            logos: <any>"",
            break: <any>"",
        }
    }
    ...more code...
}
</script>

Here 更多的是关于单个文件组件。

【讨论】:

  • 就我而言,我不得不从我的 index.html 中删除两个脚本:unpkg.com/vueunpkg.com/vue-material,它解决了这个问题,因为我已经从我的 main.js 导入了 Vue
【解决方案2】:

您不一定要删除Vue.extend。发生这种情况可能还有另外两个原因。要么是因为 Vue 是从多个位置导入的。

或者这个问题可能是因为 webpack 没有按应有的方式处理 Vue,并且认为它是外部的。因此,如果您根据需要转到文件 webpack.config.jswebpack.renderer.config.js,并从 externals 部分中删除 Vue,那么它将重新开始工作。

更多信息is here

【讨论】:

    【解决方案3】:

    从 Header_Component.vue 中移除 import Vue from 'vue'

    【讨论】:

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