[Vue 警告]:$attrs 是只读的.[Vue 警告]:$listeners 是只读的 [英] [Vue warn]: $attrs is readonly. [Vue warn]: $listeners is readonly
问题描述
我对 Vuejs 比较陌生,每次按一个键时都会收到以下警告:
[Vue 警告]:$attrs 是只读的.在发现---><路由器链接><HeaderComponent>在 src\components\Header_Component.vue<应用程序>在 src\App.vue<根>
和
[Vue 警告]:$listeners 是只读的.在发现---><路由器链接><HeaderComponent>在 src\components\Header_Component.vue<应用程序>在 src\App.vue<根>
不过,这些警告似乎根本不会影响可用性.我没有在任何地方调用 $attrs 或 $listeners,我不确定这些警告来自哪里.
这是我的 Header_Component.vue:
<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</路由器链接></a><a class='nav-link' href='#'><router-link @click.native="addClass(), setLogoTrue('blog')" to='/Blog'>BLOG</路由器链接></a><a class='nav-link' href='#'><router-link @click.native="addClass(), setLogoTrue('aboutme')" to='/Aboutme'>关于我</router-link></a><a class='nav-link' href='#'><router-link @click.native="addClass(), setLogoTrue('resume')" to='/Resume'>RESUME</路由器链接></a>
</标题></模板><script lang="ts">从'vue'导入Vue导出默认 Vue.extend({数据() {返回{logoTrue:<对象>{'主要':真的,项目":假,'博客':假,'关于我':假,'简历':假},主要:<布尔值>真,标题:<任何>"",图像:<任何>"",h1: <any>"",h2: <any>"",导航:<任何>"",标志:<any>"",中断:<任何>"",}},成分: {insta, facebook, github, codepen, mainLogo, mainLogoSmall, test, projectsLogo, blogsLogo, aboutmeLogo, resumeLogo}方法:{添加类(){if (document.querySelector('.h2Active') == null && document.querySelector('.header_top') == null) {this.add_newClasses()this.emit_finished(真)setTimeout(() => {this.remove_separators()}, 800)} 别的 {console.log('类已经存在!')this.$emit('reloadBackToTop')}},remove_separators() {让断路器 = document.getElementsByClassName('separator')而(断路器[0]){this.nav.removeChild(breaker[0])}},setLogoTrue(目标){for (var key in this.logoTrue) {如果 (this.logoTrue.hasOwnProperty(key)) {如果(键==目标){this.logoTrue[key] = true} 别的 {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(假)},add_newClasses() {如果(window.innerWidth <1060){this.nav.classList.add('navActive_small')this.image.classList.add('imgActive_small')} 别的 {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')},发射完成(延迟:布尔){如果(延迟){setTimeout (() => {this.$emit('finishedLoading')console.log('finished_loading')}, 2000)} 别的 {console.log('这里')this.$emit('finishedLoading')}},调整客户端宽度(){如果(window.innerWidth <1060){//this.remove_separators()让 bigActive = document.getElementsByClassName('big-nav')让 navActive = document.getElementsByClassName('navActive')如果(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('导航端')this.nav.classList.remove('navActive')this.image.classList.add('small-img')this.image.classList.remove('imgActive')}} 别的 {let smallActive = document.getElementsByClassName('small-nav')let smallnavActive = document.getElementsByClassName('navActive_small')如果(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('导航端')this.nav.classList.remove('navActive_small')this.image.classList.add('big-img')this.image.classList.remove('imgActive_small')}}}},创建:函数(){window.addEventListener('resize',this.adjust_clientWidth)},安装:功能(){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('项目')} else if (window.location.hash.includes("#/Blog") || window.location.hash.includes("#/blog")) {this.setLogoTrue('博客')} else if (window.location.hash == "#/Aboutme") {this.setLogoTrue('aboutme')} else if (window.location.hash == "#/Resume") {this.setLogoTrue('简历')}this.apply_topClasses()}}})<style lang="css" 作用域>(……)</风格>
感谢您的帮助!
正如您可能已经从另一个问题中发现的那样,我在这里发布一个答案以节省其他人的时间.
此类错误的问题通常是因为您多次导入 Vue.首先在您的主应用程序中,然后也在您的组件文件中.因此,从您的 Header_Component.vue 中删除 import Vue from 'vue' 行将解决该问题.但是你必须改变你声明组件的方式:
此处详细介绍了单文件组件.
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!
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.
这篇关于[Vue 警告]:$attrs 是只读的.[Vue 警告]:$listeners 是只读的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!