IT이야기

Vuejs 오류:클라이언트측 렌더링된 가상 DOM 트리가 서버에서 렌더링된 트리와 일치하지 않음

cyworld 2022. 3. 14. 21:33
반응형

Vuejs 오류:클라이언트측 렌더링된 가상 DOM 트리가 서버에서 렌더링된 트리와 일치하지 않음

내 앱에 Nuxt.js / Vuejs를 사용하고 있는데, 계속 다른 곳에서 이 오류가 발생하고 있다.

    The client-side rendered virtual DOM tree is not matching server-rendered content. 
This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. 
Bailing hydration and performing full client-side render.

이 오류를 디버깅하는 가장 좋은 방법이 무엇인지 알고 싶다.오류가 있는 위치를 비교하고 찾을 수 있도록 클라이언트 및 서버의 가상 DOM 트리를 기록/획득하는 방법인가?

내 것은 큰 어플리케이션이고 수작업으로 검증하는 것은 어렵다.

부분 답변: Chrome DevTools를 사용하여 문제를 로컬로 만들고 문제의 원인이 무엇인지 정확하게 확인할 수 있다.다음을 수행하십시오(Nuxt 5.6.0 및 Chrome 64.0.3282.186으로 수행).

  1. 크롬으로 DevTools 표시(F12)
  2. 클라이언트측 렌더링된 가상 DOM 트리가 발생하는 페이지를 로드하십시오.경고.
  3. DevTools 콘솔에서 경고로 스크롤하십시오.
  4. 경고의 소스 위치 하이퍼링크를 클릭하십시오(내 경우 vue.runtime.esm.js:574).
  5. 여기서 중단점을 설정하십시오(소스 코드 브라우저에서 라인 번호를 왼쪽 클릭).
  6. 동일한 경고를 다시 표시하십시오.나는 그것이 항상 가능하다고 말하는 것은 아니지만, 내 경우에는 단순히 페이지를 다시 로드했다.경고가 많으면 마우스를 위로 이동하여 메시지를 확인할 수 있다.msg가변의
  7. 메시지를 발견하고 중단점에 멈추면 통화 스택을 보십시오.소스를 열려면 "패치"로 호출하려면 아래 프레임을 클릭하십시오.마우스를 위로 이동hydrate 위 의 함수 콜 ( line)patch. 원본에 대한 하이퍼링크hydrate열릴 것이다.
  8. 에서hydrate에서 약 후, 줄수, 시에로 15줄 이동 설정에 한다.false다음에 반환되다assertNodeMatch돌아온false 중단점을 설정하고 다른 모든 중단점을 제거하십시오.
  9. 같은 경고가 다시 일어나도록 하라.이제 중단점을 맞으면 사형집행이 중단돼야 한다.hydrate기능을 발휘하다DevTools 콘솔로 전환하여 평가elm그 다음에vnode, nodevnodeg가 DOM인 데 비해, elm은 가상 DOM node.vnodeg가 DOM인 데 동인상 elmgo elmau dom이다.Elm은 HTML로 인쇄되어 있어 어디에서 오류가 발생했는지 알 수 있다.

이 이유는 내 것이기 이다. 왜냐하면 배열 목록을 가져오기 때문이다.AsyncData렌더링된<tr>에 의해 꼬리표를 붙이다.v-for, 내가 놓았다.v-for암호를 입력하다<client-only> 해결 해결문

이 오류는 디버깅하기에 정말 고통스러울 수 있다.문제를 일으키는 요소를 빨리 가져오려면 다음과 같이 하십시오.node_modules/vue/dist/vue.esm.js다음 줄을 추가하십시오.

// Search for this line: 
function hydrate (elm, vnode, insertedVnodeQueue, inVPre) {
    var i;
    var tag = vnode.tag;
    var data = vnode.data;
    var children = vnode.children;
    inVPre = inVPre || (data && data.pre);
    vnode.elm = elm;

    // Add the following lines: 
    console.log('elm', elm)
    console.log('vnode', vnode)
    console.log('inVpre', inVPre)
    // ...


고장난 노드를 콘솔에 넣게 될 것이다.

나는 nuxt 버전과 같은 이슈를 가지고 있었다.2.14.0vue-package 패키지를 구현하는 동안.그 해결책은 로 그 태그들을 둘러싸는 것이었다.no-ssr그리고 그것은 문제를 해결했다.

편집:
업데이트된 솔루션 변형(Nuxt 버전이 위에 있는 경우)2.9.0)

<client-only>
  <vue-particles>
  </vue-particles>
</client-only>

기존 솔루션:

<no-ssr>
  <vue-particles>
  </vue-particles>
</no-ssr>

이 문제를 해결할 수 있는 방법은 여러 가지가 있지만, 대부분은 실제적인 해결책이 아니라, 그저 진부한 반창고일 뿐이다.몇 가지 참고 사항:

  • 포장하다<client-only>태그, 몇 가지 중요한 세부사항을 주의하라.
  • a를 사용하여v-showv-if
  • 라이프사이클을 해킹하려고 하는 중
  • 기타...

나는 알렉산더 리히터가 쓴 이 멋진 기사를 읽기를 강력히 추천한다.

https://blog.lichter.io/posts/vue-hydration-error/

왜 이런 일이 일어나는지 진단하고 실제 문제를 고쳐야 한다고 그가 설명해 줄 것이다.
기본적으로 어떤 것이 서버에 생성된 것과 다르며 클라이언트에서 하이드레이팅을 했을 때 사용 가능한 것이 매번 이 오류를 발생시킬 것이다.

그 중 일부는 다음과 같다.

  • 유효하지 않은 HTML(블록 요소를 내부에 포함)<p>,도 마찬가지다.a다른 태그에 중첩된 태그 등)
  • 구성 요소를 건드리는 타사 스크립트
  • 서버와 클라이언트의 다른 상태
  • 임의의 랜덤은 위험하다 (new Date()예를 들어)
  • 인증과 관련된 페이지

나는 알렉산드르 자신의 말로 이런 종류의 문제를 어떻게 다룰 것인가를 이해하기 위해 그 기사를 읽기를 강력히 추천한다.만약 여러분이 급하다면, 여러분은 항상 한 가지 반창고를 사용할 수 있지만, 최상의 성능을 위해 그리고 코드를 깨끗하게 유지하기 위해 실제로 문제를 고치려고 노력한다.

2.10 이상의 Nuxt 버전에서는 설치할 필요가 없으며 기본 구성 요소만 사용하십시오.<client-only>https://nuxtjs.org/api/components-client-only/에서 언급한 바와 같이.

이전 경고를 확인하십시오.

"nuxt": "^2.12.2", 이전의 경고로부터 쉽게 원인을 찾아낼 수 있다.

여기에 이미지 설명을 입력하십시오.

제 경우:

틀렸다

<nuxt-link to="/game42day">
  <a>Game For Today</a>
</nuxt-link>

정답:

<nuxt-link to="/game42day">
  Game For Today
</nuxt-link>

알고 보니, 내 경우에는 HTML 주석 태그가 있었는데, 그것은 이 어리석고 짜증나는 오류를 야기하고 있었다.알아내는데 너무 오래 걸렸지만 누군가에게 도움이 될까봐.

구성 요소를 조건부로 렌더링하는 경우v-if, 그러면 문제를 해결할 수 있는 두 가지 옵션이 있다.

첫 번째는 원소를 감싸는 것이다.<no-ssr></no-ssr>꼬리표를 달다

두 번째 접근방식은 교체하는 것이다.v-if와 함께v-show, 여기에 Vue 문서로 연결되는 링크가 있다.

내 경우에는 이것을 바꿔야 했다.

<v-expansion-panel-header v-text="name" />

이를 위해:

<v-expansion-panel-header>{{ name }}</v-expansion-panel-header>

그래, 이건 바보같이 들릴거야.서버를 재시작하고 .nnxt 디렉토리를 삭제하는 등 약 15분 동안 여러 가지 솔루션을 시도해 보았지만 너무 게을러 @budden73의 큰 뇌 솔루션을 사용할 수 없었다.결국 나한테 효과가 있었던 건 내 컴퓨터를 다시 시작하는 거였어. 한번 시도해봐.

내가 지금까지 관찰에서 발견한 것은 jQuery(특히)와 같은 제3자 패키지를 사용할 때, 그것들은 때때로 돔에 html 태그를 주입한다는 것이다.그래서 Vue/Nuxt는 돔 트리를 추적하지 않고 불평하기 시작한다.

나도 같은 문제를 겪고 있었는데 얼마 후 모든 jQuery를 제거하고 jQuery 기능을 Vuejs로 교체했는데 그 오류는 모두 사라졌다.

DOM을 수정하는 통합(예: Google Analytics 또는 FB Pixel)을 처리하는 방법에 대한 예는 여기를 참조하십시오.기본적으로 플러그인을 생성하고 SSR에서 제외하십시오.

https://nuxtjs.org/faq/ga

다음을 참조하십시오.

extend (config, ctx) {
  config.resolve.symlinks = false
}

다음 [Vue 경고]를 참조하십시오. 클라이언트측 렌더링된 가상 DOM 트리가 서버에서 렌더링된 콘텐츠(Nuxt / Vue / lerna monorepo )와 일치하지 않음

나 또한 이 문제로 인해 많은 실수를 한다.내가 자주 마주치는 두 가지 경우를 나열해보면 희망이 널 도울 수 있어.

  • vuetify 버튼을 사용하여 공통 구성 요소를 생성할 때 다음을 사용하십시오.<v-btn>{{text}}</v-btn>예:
<template>
    <v-btn
      :width="width"
      :color="color"
      :class="[rounded ? 'rounded-pill' : 'rounded-lg',textColor]"
      v-on:click="onClick"
      elevation="0"
      :outlined="outlined"
      :type="type"
      :name="name"
      :form="form"
      :disabled="disabled"
      v-bind="$attrs"
    >{{ text }}</v-btn>
</template>
  • 다음에서 v-html 사용 안 함<p>하지 않음: 태그그제. 사용하지 않음:<p v-html='html'></p>. 사용:<div v-html='html'></div>.

게다가, 만약 당신이<client-only></client-only>, 이 문제는 확실히 해결되었지만, 만약 당신이 SEO 페이지나 구글 광고를 보여줘야 한다면, 그것은 좋은 해결책이 아니다.

인라인 요소 내부에 블록 레벨 요소를 사용한 적이 있는지 확인하십시오.

예: 내부, 내부

HTML 테이블을 사용한 경우 태그를 사용했는지 확인하십시오.

내 경우에는, 나는 내 코드를 바꾸었다.

<p v-html="$md.render(post.content)"></p>

<p>{{ $md.render(post.content) }}</p>

참조URL: https://stackoverflow.com/questions/47862591/vuejs-error-the-client-side-rendered-virtual-dom-tree-is-not-matching-server-re

반응형