title: [Vue warn]: Error in render: "TypeError: Converting circular structure to JSON
body: <p>I have successfully created a Single File Component in Vue; there are no compilation errors, however, when I attempt to view the component (by navigating to it's route link), the expected page is not displayed, and instead, I get a stack trace printed in the (Chrome) browser - using the Vue Devtools plugin.</p>
  
  <p>Here is the stacktrace output in the Vue Devtools plugin console:</p>
  
  <pre><code>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
      --&gt; starting at object with constructor 'DockPanel'
      |     property '_layout' -&gt; object with constructor 'DockLayout'
      --- property '_parent' closes the circle"
  
  found in
  
  ---&gt; &lt;Demo&gt; at src/components/Demo.vue
         &lt;App&gt; at src/App.vue
           &lt;Root&gt;
  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
      --&gt; starting at object with constructor 'DockPanel'
      |     property '_layout' -&gt; object with constructor 'DockLayout'
      --- property '_parent' closes the circle
      at JSON.stringify (&lt;anonymous&gt;)
      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&amp;type=template&amp;id=09260093&amp;scoped=true&amp; (app.js:2401), &lt;anonymous&gt;: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
  </code></pre>
  
  <h3>package.json</h3>
  
  <pre><code>{
    "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"
    }
  }
  </code></pre>
  
  <h3>router.ts</h3>
  
  <pre><code>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: () =&gt; import(/* webpackChunkName: "about" */ './views/About.vue'),
      },
    ],
  });
  </code></pre>
  
  <h3>Demo.vue</h3>
  
  <pre><code>&lt;template&gt;
    &lt;div class="demo"&gt;
      &lt;h1&gt;{{ title }}&lt;/h1&gt;
      {{ dpanel }}
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script lang="ts"&gt;
  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 {
    }
  }
  &lt;/script&gt;
  
  &lt;!-- Add "scoped" attribute to limit CSS to this component only --&gt;
  &lt;style scoped lang="less"&gt;
  .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 &gt; .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 &gt; .p-TabBar-tabCloseIcon {
    margin-left: 4px;
  }
  
  
  .p-TabBar-tab.p-mod-closable &gt; .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%);
  }
  </code></pre>
  
  <p></p>
  
  <p>What's causing this error, and how do I resolve it (so I can correctly render the widgets for example, as shown <a href="http://phosphorjs.github.io/examples/dockpanel/" rel="nofollow noreferrer">here</a>)?</p>