11

I’m relatively new to Vuejs and I’m getting the following warnings every time I press a key:

[Vue warn]: $attrs is readonly.

found in

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

and

[Vue warn]: $listeners is readonly.

found in

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

These warnings do not seem to be affecting the usability at all though. I'm invoking neither $attrs or $listeners anywhere, I'm not sure where these warnings are coming from.

Here is my 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>

Thank you for your help!

Meko Deng
  • 435
  • 1
  • 5
  • 10
  • 1
    related to: https://stackoverflow.com/questions/52209717/vuejs-uncaught-typeerror-cannot-redefine-property-router Fixed! – Meko Deng Sep 07 '18 at 00:23
  • Unless anyone has firsthand experience with this specific problem, it's going to be difficult to help you without a [MCVE](https://stackoverflow.com/help/mcve). – Decade Moon Sep 07 '18 at 01:52

3 Answers3

8

As you probably already figured out from another question, I am posting an answer here to save some time everybody else.

The issue with these kind of errors is usually because you import Vue more than once. First in your main app and then also in your component file. So removing the line import Vue from 'vue' from your Header_Component.vue will resolve the issue. But you will have to change the way you are declaring the component to this:

<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 is more about single file components.

tony19
  • 125,647
  • 18
  • 229
  • 307
papa zulu
  • 317
  • 5
  • 16
  • In my case, I had to delete two scripts from my index.html: https://unpkg.com/vue and https://unpkg.com/vue-material and it solved the problem because I had already imported Vue from my main.js – Lucas Oct 14 '21 at 16:49
  • In my case, micro-frontends, needed to add the Vue to the share modules – Bordalo Jun 02 '22 at 10:01
1

You don't necessarily have to remove Vue.extend. There can be two other reasons why this is happening. Either because Vue is imported from multiple locations.

Or this problem can be because webpack isn't handling Vue as it should and thinks it is an external. So if you go to the file webpack.config.js or webpack.renderer.config.js, as appropriate, and remove Vue from the externals section, then it will start working again.

More information is here.

Paul F. Wood
  • 1,453
  • 16
  • 19
0

remove import Vue from 'vue' from Header_Component.vue