Vue 警告 $listeners 和 $attrs 是只读的
Vue warn $listeners and $attrs is readonly
我收到很多 Vue 警告说 $listeners 是只读的或 $attrs 是只读的并且与不同的 Bootstrap 项或 .
例如:
[Vue warn]: $attrs is readonly.
found in
---> <BDropdown>
<Display>
<App>
<Root>
我非常确定它与以某种方式加载 Vue 实例两次有关,但我真的不知道如何以其他方式进行,以便路由仍然有效。
在我的main.js代码如下:
import Vue from 'vue'
import App from './App'
import router from './router'
import firebase from 'firebase';
import './components/firebaseInit';
import store from './store';
import { i18n } from './plugins/i18n.js'
import BootstrapVue from 'bootstrap-vue'
import VueCarousel from 'vue-carousel';
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.use(BootstrapVue);
Vue.use(VueCarousel);
let app;
firebase.auth().onAuthStateChanged(user => {
if(!app) {
app = new Vue({
el: '#app',
router,
store,
i18n,
components: { App },
template: '<App/>'
})
}
})
我的 router/index.js 代码如下所示:
import Vue from 'vue'
import Router from 'vue-router'
import firebaseApp from '@/components/firebaseInit'
Vue.use(Router)
let router = new Router({
routes: [
{
path: '/',
name: 'display',
component: Display
},
...
]
})
// Nav Guards
router.beforeEach((to, from, next) => {
// check for requiredAuth
if(to.matched.some(record => record.meta.requiresAuth)) {
// check if NOT logged in
...
} else {
// proceed to route
next();
}
} else {
next();
}
})
export default router;
由于示例错误来自 Display.vue,这里是该代码的摘录:
<template>
<div>
<b-row>
<b-input-group prepend="Category">
<b-dropdown v-bind:text="currentCategory">
<b-dropdown-item @click="categroyChanged('All')">All</b-dropdown-item>
<b-dropdown-item v-for="c in categories" v-bind:key="c" @click="categoryChanged(c)">{{c}}</b-dropdown-item>
</b-dropdown>
</b-input-group>
</b-row>
<div class="row" v-for="i in Math.ceil(products.length / 3)" v-bind:key="i">
<div v-for="product in products.slice((i - 1) * 3, i * 3)" v-bind:key="product.id" class="col-md-4 col-6 my-1">
<b-card
v-bind:img-src="product.thumbUrl"
img-fluid
img-alt="image"
overlay>
<div slot="footer">
<small class="text-muted">{{product.name}}<br />{{product.price}} VND</small>
</div>
<router-link v-bind:to="{name: 'view-product', params: {product_id: product.product_id}}" class="secondary-content">
<i class="fa fa-eye"></i>
</router-link>
<router-link v-if="isEmployee" v-bind:to="{name: 'edit-product', params: {product_id: product.product_id}}" class="secondary-content">
<i class="fa fa-pencil"></i>
</router-link>
<button @click='addToCart(product)' class='button is-info'><i class="fa fa-cart-arrow-down"></i></button>
</b-card>
</div>
</div>
</div>
</template>
<script>
import firebaseApp from './firebaseInit'
import { mapActions } from 'vuex'
export default {
name: 'display',
data () {
return {
txtSearch: null,
isLoggedIn: false,
currentUser: false,
isEmployee: false,
products: []
}
},
beforeMount () {
var db = firebaseApp.firestore();
db.collection('products').get().then(querySnapshot => {
querySnapshot.forEach(doc => {
const data = {
'product_id': doc.id,
'article_number': doc.data().article_number,
'barcode': doc.data().barcode,
'category': doc.data().category,
'colour': doc.data().colour,
'description': doc.data().description,
'name': doc.data().name,
'name_ger': doc.data().name_ger,
'price': doc.data().price,
'size': doc.data().size,
'thumbUrl': doc.data().thumbUrl,
}
this.products.push(data)
})
})
}
},
methods: {
...mapActions(['addToCart']),
... many methods ...
}
}
</script>
我怎样才能摆脱这些错误?
追了一个小时后,我意识到我拥有 imported
的一个组件也在访问 Vue
。该文件的顶部是 import Vue from 'vue/dist/vue.esm'
。每个其他文件只是在做 import Vue from 'vue'
,这是我的 double-import.
的来源
不同的 javascript 包装商有不同的解决重复问题的方法。对于 WebPack,Resolve Configuration 在依赖项导入不同 Vue 实例的情况下可能会有所帮助。
发生这种情况的常见原因有两个:
多个 Vue 位置
这可能是由于您在不同文件中导入 Vue 的位置相互矛盾,正如其他人所说。例如,您的代码中可能同时包含 import Vue from 'vue'
和 import Vue from 'vue.runtime.esm'
。
但这可以result in multiple instances of Vue,这将导致这些错误。
这种情况下的解决方案是在你的代码中到处使用 import Vue from 'vue'
,然后在你的打包系统(webpack、Parcel、rollup 等)中为其添加别名。 webpack.config.js
或 webpack.renderer.config.js
中的一个示例,如果您使用的是 Electron,则为:
module.exports = {
// ...
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
}
}
// ...
}
见more examples in the Vue documents。
白名单
这也可能是因为需要将 Vue 列入白名单,例如 而不是 webpack 中的 externals
之一。
值得注意的是,Bootstrap Vue 从 2.0 到更高版本的更改,肯定是 2.15(可能更早),导致了同样的问题。
module.exports = {
// ...
externals: [
'fast-glob',
'jquery',
'bunyan',
'yaml',
'vue', // Remove this
'bootstrap-vue', // Remove this
// ...
}
这是我的情况 (),但我会在这里重复一遍以节省您的时间:我从 CDN 导入 vue 。我简单地删除了脚本,问题就解决了。
我收到很多 Vue 警告说 $listeners 是只读的或 $attrs 是只读的并且与不同的 Bootstrap 项或 .
例如:
[Vue warn]: $attrs is readonly.
found in
---> <BDropdown>
<Display>
<App>
<Root>
我非常确定它与以某种方式加载 Vue 实例两次有关,但我真的不知道如何以其他方式进行,以便路由仍然有效。
在我的main.js代码如下:
import Vue from 'vue'
import App from './App'
import router from './router'
import firebase from 'firebase';
import './components/firebaseInit';
import store from './store';
import { i18n } from './plugins/i18n.js'
import BootstrapVue from 'bootstrap-vue'
import VueCarousel from 'vue-carousel';
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
Vue.use(BootstrapVue);
Vue.use(VueCarousel);
let app;
firebase.auth().onAuthStateChanged(user => {
if(!app) {
app = new Vue({
el: '#app',
router,
store,
i18n,
components: { App },
template: '<App/>'
})
}
})
我的 router/index.js 代码如下所示:
import Vue from 'vue'
import Router from 'vue-router'
import firebaseApp from '@/components/firebaseInit'
Vue.use(Router)
let router = new Router({
routes: [
{
path: '/',
name: 'display',
component: Display
},
...
]
})
// Nav Guards
router.beforeEach((to, from, next) => {
// check for requiredAuth
if(to.matched.some(record => record.meta.requiresAuth)) {
// check if NOT logged in
...
} else {
// proceed to route
next();
}
} else {
next();
}
})
export default router;
由于示例错误来自 Display.vue,这里是该代码的摘录:
<template>
<div>
<b-row>
<b-input-group prepend="Category">
<b-dropdown v-bind:text="currentCategory">
<b-dropdown-item @click="categroyChanged('All')">All</b-dropdown-item>
<b-dropdown-item v-for="c in categories" v-bind:key="c" @click="categoryChanged(c)">{{c}}</b-dropdown-item>
</b-dropdown>
</b-input-group>
</b-row>
<div class="row" v-for="i in Math.ceil(products.length / 3)" v-bind:key="i">
<div v-for="product in products.slice((i - 1) * 3, i * 3)" v-bind:key="product.id" class="col-md-4 col-6 my-1">
<b-card
v-bind:img-src="product.thumbUrl"
img-fluid
img-alt="image"
overlay>
<div slot="footer">
<small class="text-muted">{{product.name}}<br />{{product.price}} VND</small>
</div>
<router-link v-bind:to="{name: 'view-product', params: {product_id: product.product_id}}" class="secondary-content">
<i class="fa fa-eye"></i>
</router-link>
<router-link v-if="isEmployee" v-bind:to="{name: 'edit-product', params: {product_id: product.product_id}}" class="secondary-content">
<i class="fa fa-pencil"></i>
</router-link>
<button @click='addToCart(product)' class='button is-info'><i class="fa fa-cart-arrow-down"></i></button>
</b-card>
</div>
</div>
</div>
</template>
<script>
import firebaseApp from './firebaseInit'
import { mapActions } from 'vuex'
export default {
name: 'display',
data () {
return {
txtSearch: null,
isLoggedIn: false,
currentUser: false,
isEmployee: false,
products: []
}
},
beforeMount () {
var db = firebaseApp.firestore();
db.collection('products').get().then(querySnapshot => {
querySnapshot.forEach(doc => {
const data = {
'product_id': doc.id,
'article_number': doc.data().article_number,
'barcode': doc.data().barcode,
'category': doc.data().category,
'colour': doc.data().colour,
'description': doc.data().description,
'name': doc.data().name,
'name_ger': doc.data().name_ger,
'price': doc.data().price,
'size': doc.data().size,
'thumbUrl': doc.data().thumbUrl,
}
this.products.push(data)
})
})
}
},
methods: {
...mapActions(['addToCart']),
... many methods ...
}
}
</script>
我怎样才能摆脱这些错误?
追了一个小时后,我意识到我拥有 imported
的一个组件也在访问 Vue
。该文件的顶部是 import Vue from 'vue/dist/vue.esm'
。每个其他文件只是在做 import Vue from 'vue'
,这是我的 double-import.
不同的 javascript 包装商有不同的解决重复问题的方法。对于 WebPack,Resolve Configuration 在依赖项导入不同 Vue 实例的情况下可能会有所帮助。
发生这种情况的常见原因有两个:
多个 Vue 位置
这可能是由于您在不同文件中导入 Vue 的位置相互矛盾,正如其他人所说。例如,您的代码中可能同时包含 import Vue from 'vue'
和 import Vue from 'vue.runtime.esm'
。
但这可以result in multiple instances of Vue,这将导致这些错误。
这种情况下的解决方案是在你的代码中到处使用 import Vue from 'vue'
,然后在你的打包系统(webpack、Parcel、rollup 等)中为其添加别名。 webpack.config.js
或 webpack.renderer.config.js
中的一个示例,如果您使用的是 Electron,则为:
module.exports = {
// ...
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
}
}
// ...
}
见more examples in the Vue documents。
白名单
这也可能是因为需要将 Vue 列入白名单,例如 而不是 webpack 中的 externals
之一。
值得注意的是,Bootstrap Vue 从 2.0 到更高版本的更改,肯定是 2.15(可能更早),导致了同样的问题。
module.exports = {
// ...
externals: [
'fast-glob',
'jquery',
'bunyan',
'yaml',
'vue', // Remove this
'bootstrap-vue', // Remove this
// ...
}
这是我的情况 (),但我会在这里重复一遍以节省您的时间:我从 CDN 导入 vue 。我简单地删除了脚本,问题就解决了。