我已经在Vue中成功创建了单个文件组件;没有编译错误,但是,当我尝试查看组件(通过导航到其路由链接)时,未显示预期的页面,而是在(Chrome)浏览器中打印了堆栈跟踪-使用Vue Devtools插件。
这是Vue Devtools插件控制台中的stacktrace输出:
vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render:
log.js?1afd:24 [HMR] Waiting for update signal from WDS...
vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Converting circular structure to JSON
--> starting at object with constructor 'DockPanel'
| property '_layout' -> object with constructor 'DockLayout'
--- property '_parent' closes the circle"
found in
---> <Demo> at src/components/Demo.vue
<App> at src/App.vue
<Root>
warn @ vue.runtime.esm.js?2b0e:619
logError @ vue.runtime.esm.js?2b0e:1884
globalHandleError @ vue.runtime.esm.js?2b0e:1879
handleError @ vue.runtime.esm.js?2b0e:1839
Vue._render @ vue.runtime.esm.js?2b0e:3544
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
init @ vue.runtime.esm.js?2b0e:3118
merged @ vue.runtime.esm.js?2b0e:3301
createComponent @ vue.runtime.esm.js?2b0e:5972
createElm @ vue.runtime.esm.js?2b0e:5919
createChildren @ vue.runtime.esm.js?2b0e:6047
createElm @ vue.runtime.esm.js?2b0e:5948
patch @ vue.runtime.esm.js?2b0e:6471
Vue._update @ vue.runtime.esm.js?2b0e:3939
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
init @ vue.runtime.esm.js?2b0e:3118
createComponent @ vue.runtime.esm.js?2b0e:5972
createElm @ vue.runtime.esm.js?2b0e:5919
patch @ vue.runtime.esm.js?2b0e:6510
Vue._update @ vue.runtime.esm.js?2b0e:3939
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
(anonymous) @ main.ts?bc82:8
./src/main.ts @ app.js:5941
__webpack_require__ @ app.js:767
fn @ app.js:130
1 @ app.js:6015
__webpack_require__ @ app.js:767
(anonymous) @ app.js:902
(anonymous) @ app.js:905
Show 11 more frames
vue.runtime.esm.js?2b0e:1888 TypeError: Converting circular structure to JSON
--> starting at object with constructor 'DockPanel'
| property '_layout' -> object with constructor 'DockLayout'
--- property '_parent' closes the circle
at JSON.stringify (<anonymous>)
at Proxy.toString (vue.runtime.esm.js?2b0e:94)
at Proxy.render (eval at ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"4105b414-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/components/Demo.vue?vue&type=template&id=09260093&scoped=true& (app.js:2401), <anonymous>:10:25)
at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:3542)
at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:4060)
at Watcher.get (vue.runtime.esm.js?2b0e:4473)
at new Watcher (vue.runtime.esm.js?2b0e:4462)
at mountComponent (vue.runtime.esm.js?2b0e:4067)
at VueComponent.Vue.$mount (vue.runtime.esm.js?2b0e:8409)
at init (vue.runtime.esm.js?2b0e:3118)
logError @ vue.runtime.esm.js?2b0e:1888
globalHandleError @ vue.runtime.esm.js?2b0e:1879
handleError @ vue.runtime.esm.js?2b0e:1839
Vue._render @ vue.runtime.esm.js?2b0e:3544
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
init @ vue.runtime.esm.js?2b0e:3118
merged @ vue.runtime.esm.js?2b0e:3301
createComponent @ vue.runtime.esm.js?2b0e:5972
createElm @ vue.runtime.esm.js?2b0e:5919
createChildren @ vue.runtime.esm.js?2b0e:6047
createElm @ vue.runtime.esm.js?2b0e:5948
patch @ vue.runtime.esm.js?2b0e:6471
Vue._update @ vue.runtime.esm.js?2b0e:3939
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
init @ vue.runtime.esm.js?2b0e:3118
createComponent @ vue.runtime.esm.js?2b0e:5972
createElm @ vue.runtime.esm.js?2b0e:5919
patch @ vue.runtime.esm.js?2b0e:6510
Vue._update @ vue.runtime.esm.js?2b0e:3939
updateComponent @ vue.runtime.esm.js?2b0e:4060
get @ vue.runtime.esm.js?2b0e:4473
Watcher @ vue.runtime.esm.js?2b0e:4462
mountComponent @ vue.runtime.esm.js?2b0e:4067
Vue.$mount @ vue.runtime.esm.js?2b0e:8409
(anonymous) @ main.ts?bc82:8
./src/main.ts @ app.js:5941
__webpack_require__ @ app.js:767
fn @ app.js:130
1 @ app.js:6015
__webpack_require__ @ app.js:767
(anonymous) @ app.js:902
(anonymous) @ app.js:905
Show 10 more frames
Demo.vue?96da:47 *** this actually ran
{
"name": "client",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"@phosphor/widgets": "^1.7.0",
"axios": "^0.19.0",
"core-js": "^2.6.5",
"vue": "^2.6.10",
"vue-class-component": "^7.0.2",
"vue-property-decorator": "^8.1.0",
"vue-router": "^3.0.3",
"vuex": "^3.0.1"
},
"devDependencies": {
"@types/chai": "^4.1.0",
"@types/mocha": "^5.2.4",
"@vue/cli-plugin-babel": "^3.8.0",
"@vue/cli-plugin-eslint": "^3.8.0",
"@vue/cli-plugin-typescript": "^3.8.0",
"@vue/cli-plugin-unit-mocha": "^3.8.0",
"@vue/cli-service": "^3.8.0",
"@vue/eslint-config-airbnb": "^4.0.0",
"@vue/eslint-config-typescript": "^4.0.0",
"@vue/test-utils": "1.0.0-beta.29",
"babel-eslint": "^10.0.1",
"chai": "^4.1.2",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"less": "^3.9.0",
"less-loader": "^5.0.0",
"typescript": "^3.4.3",
"vue-template-compiler": "^2.6.10"
}
}
import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/Home.vue';
import Demo from './components/Demo.vue';
Vue.use(Router);
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home,
},
{
path: '/demo',
name: 'demo',
component: Demo,
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ './views/About.vue'),
},
],
});
<template>
<div class="demo">
<h1>{{ title }}</h1>
{{ dpanel }}
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import { Widget, DockPanel } from '@phosphor/widgets';
@Component
export default class Demo extends Vue {
@Prop() private title!: string;
// apparently with typescript variant of vue, instance variables
// are the equivalent of the vue 'data' object's attributes...
dpanel:DockPanel = new DockPanel();
components:any
constructor() {
super();
this.components = {
DockPanel,
};
}
mounted() {
const widget1 = new Widget();
widget1.addClass('content');
widget1.addClass('blue');
widget1.title.label = 'Blue';
widget1.title.closable = true;
const widget2 = new Widget();
widget2.addClass('content');
widget2.addClass('red');
widget2.title.label = 'Red';
widget2.title.closable = true;
this.dpanel.id = 'main';
this.dpanel.addWidget(widget1);
this.dpanel.addWidget(widget2);
this.dpanel.update();
console.log('*** this actually ran');
}
static setupPanels():void {
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.content {
border: 1px solid black;
min-width: 50px;
min-height: 50px;
}
.red {
background: #E74C3C;
}
.yellow {
background: #F1C40F;
}
.green {
background: #27AE60;
}
.blue {
background: #3498DB;
}
.p-DockTabPanel {
padding-right: 2px;
padding-bottom: 2px;
}
.p-DockTabPanel > .p-StackedPanel {
padding: 10px;
background: white;
border: 1px solid #C0C0C0;
border-top: none;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
}
.p-DockPanel-overlay {
background: rgba(255, 255, 255, 0.6);
border: 1px dashed black;
}
.p-DockPanel-overlay.p-mod-root-top,
.p-DockPanel-overlay.p-mod-root-left,
.p-DockPanel-overlay.p-mod-root-right,
.p-DockPanel-overlay.p-mod-root-bottom,
.p-DockPanel-overlay.p-mod-root-center {
border-width: 2px;
}
.p-TabBar {
min-height: 24px;
max-height: 24px;
}
.p-TabBar-header {
display: none;
}
.p-TabBar-footer {
flex: 0 0 1px;
background: #C0C0C0;
}
.p-TabBar-content {
min-width: 0;
align-items: flex-end;
}
.p-TabBar-tab {
flex: 0 1 125px;
min-height: 20px;
max-height: 20px;
min-width: 35px;
margin-left: -1px;
border: 1px solid #C0C0C0;
border-bottom: none;
padding: 0px 10px;
background: #E5E5E5;
font: 12px Helvetica, Arial, sans-serif;
}
.p-TabBar-tab:first-child {
margin-left: 0;
}
.p-TabBar-tab.p-mod-current {
min-height: 23px;
max-height: 23px;
background: white;
transform: translateY(1px);
}
.p-TabBar-tab:hover:not(.p-mod-current) {
background: #F0F0F0;
}
.p-TabBar-tabIcon,
.p-TabBar-tabText,
.p-TabBar-tabCloseIcon {
line-height: 20px;
}
.p-TabBar-tab.p-mod-closable > .p-TabBar-tabCloseIcon {
margin-left: 4px;
}
.p-TabBar-tab.p-mod-closable > .p-TabBar-tabCloseIcon:before {
content: '\f00d';
font-family: FontAwesome;
}
.p-TabBar-tab.p-mod-drag-image {
min-height: 23px;
max-height: 23px;
min-width: 125px;
border: none;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
transform: translateX(-40%) translateY(-58%);
}
是什么原因导致此错误,以及如何解决(例如,我可以正确呈现窗口小部件,如here所示)?
答案 0 :(得分:1)
我对PhosphorJS并不熟悉,所以我只能对发生的事情进行解释。
您似乎在尝试通过执行{{ dpanel }}
在模板中呈现DockPanel实例。这行不通。这种“胡子语法”用于呈现基本数据类型,例如字符串和数字,如果您以此方式呈现对象,则Vue将通过在其上调用JSON.stringify
来呈现该对象的JSON表示形式;在这种情况下,dpanel
对象包含循环引用,因此将失败。
我刚刚浏览了PhosphorJS docs。看起来PhosphorJS不是Vue组件库,因此您必须自己将DockPanel节点插入DOM中,可能在mounted
钩中。
mounted() {
this.$el.appendChild(this.dpanel.node)
},
destroyed() {
this.dpanel.dispose()
}
同样,我对PhosphorJS并不熟悉,所以这可能不是最正确的建议。