극단적인 경우 처리


이 페이지에서는 구성 요소 기본 사항을 읽었다고 가정합니다. 아직 컴포넌트에 대해 잘 모르신다면 먼저 읽어보시길 권합니다.

여기에 기록된 기능은 모두 엣지 케이스 처리와 관련이 있습니다. 즉, Vue 규칙을 약간 조정해야 하는 특수 케이스입니다. 그러나 이러한 기능에는 모두 단점이나 위험한 시나리오가 있다는 점에 유의하세요. 이는 각각의 경우에 기록되므로 각 기능을 사용할 때 주의하시기 바랍니다.


Directory


요소 및 구성 요소 액세스


대부분의 경우 다른 구성 요소 인스턴스 내부에 접근하거나 수동으로 접근하지 않는 것이 좋습니다 DOM 요소를 조작합니다. 그러나 이러한 일을 하는 것이 적절한 상황이 분명히 있습니다.


속성에서 루트 인스턴스

new Vue 实例的子组件中,其根实例可以通过 $root에 액세스합니다. 예를 들어 다음 루트 인스턴스에서는

// Vue 根实例
new Vue({
  data: {
    foo: 1
  },
  computed: {
    bar: function () { /* ... */ }
  },
  methods: {
    baz: function () { /* ... */ }
  }
})

모든 하위 구성 요소가 이 인스턴스에 액세스하거나 전역 저장소로 사용할 수 있습니다.

// 获取根组件的数据
this.$root.foo

// 写入根组件的数据
this.$root.foo = 2

// 访问根组件的计算属性
this.$root.bar

// 调用根组件的方法
this.$root.baz()

이 기능은 데모나 구성 요소 수가 적은 매우 작은 애플리케이션에 매우 편리합니다. 그러나 이 모델은 중대형 애플리케이션으로 확장되지 않습니다. 따라서 대부분의 경우 Vuex를 사용하여 애플리케이션 상태를 관리하는 것이 좋습니다.


상위 구성 요소 인스턴스에 액세스

$root와 유사하게 $parent 속성을 ​​사용하여 하위 구성 요소에서 상위 구성 요소에 액세스할 수 있습니다. 구성 요소 예. props 형식으로 하위 구성 요소에 데이터를 전달하는 대신 나중에 언제든지 상위 구성 요소에 접근할 수 있는 기회를 제공합니다. $root 类似,$parent 属性可以用来从一个子组件访问父组件的实例。它提供了一种机会,可以在后期随时触达父级组件,以替代将数据以 prop 的方式传入子组件的方式。

在绝大多数情况下,触达父级组件会使得你的应用更难调试和理解,尤其是当你变更了父级组件的数据的时候。当我们稍后回看那个组件的时候,很难找出那个变更是从哪里发起的。

另外在一些可能适当的时候,你需要特别地共享一些组件库。举个例子,在和 JavaScript API 进行交互而不渲染 HTML 的抽象组件内,诸如这些假设性的 Google 地图组件一样:

<google-map>
  <google-map-markers v-bind:places="iceCreamShops"></google-map-markers>
</google-map>

这个 <google-map> 组件可以定义一个 map 属性,所有的子组件都需要访问它。在这种情况下 <google-map-markers> 可能想要通过类似 this.$parent.getMap 的方式访问那个地图,以便为其添加一组标记。你可以在这里查阅这种模式。

请留意,尽管如此,通过这种模式构建出来的那个组件的内部仍然是容易出现问题的。比如,设想一下我们添加一个新的 <google-map-region> 组件,当 <google-map-markers> 在其内部出现的时候,只会渲染那个区域内的标记:

<google-map>
  <google-map-region v-bind:shape="cityBoundaries">
    <google-map-markers v-bind:places="iceCreamShops"></google-map-markers>
  </google-map-region>
</google-map>

那么在 <google-map-markers> 内部你可能发现自己需要一些类似这样的 hack:

var map = this.$parent.map || this.$parent.$parent.map

很快它就会失控。这也是我们针对需要向任意更深层级的组件提供上下文信息时推荐依赖注入的原因。


访问子组件实例或子元素

尽管存在 prop 和事件,有的时候你仍可能需要在 JavaScript 里直接访问一个子组件。为了达到这个目的,你可以通过 ref 特性为这个子组件赋予一个 ID 引用。例如:

<base-input ref="usernameInput"></base-input>

现在在你已经定义了这个 ref

🎜대부분의 경우 상위 구성 요소에 도달하면 특히 상위 구성 요소의 데이터를 변경할 때 애플리케이션을 디버깅하고 이해하기가 더 어려워집니다. 나중에 해당 구성 요소를 다시 살펴보면 해당 변경 사항이 어디서 발생했는지 파악하기 어렵습니다. 🎜🎜🎜또한 적절할 경우 일부 구성 요소 라이브러리를 구체적으로 공유해야 합니다. 예를 들어, 다음과 같은 가상의 Google 지도 구성요소와 같이 HTML을 렌더링하지 않고 JavaScript API와 상호작용하는 추상 구성요소 내에서: 🎜
this.$refs.usernameInput
🎜<google-map> 구성요소는 지도를 정의할 수 있습니다. 속성을 ​​사용하려면 모든 하위 구성요소에 액세스해야 합니다. 이 경우 <google-map-markers>는 마크 세트를 추가하기 위해 this.$parent.getMap과 같은 것을 통해 해당 지도에 액세스할 수 있습니다. 여기 🎜에서 이 패턴을 확인할 수 있습니다. 🎜🎜이에도 불구하고 이 패턴을 통해 구축된 구성 요소의 내부에는 여전히 문제가 발생하기 쉽습니다. 예를 들어, 새로운 <google-map-region> 구성요소를 추가하고 그 안에 <google-map-markers>가 나타나면 해당 영역 내의 마커: 🎜
<input ref="input">
🎜 그런 다음 <google-map-markers> 내부에서 다음과 같은 해킹이 필요할 수 있습니다. 🎜
methods: {
  // 用来从父级组件聚焦输入框
  focus: function () {
    this.$refs.input.focus()
  }
}
🎜 꽤 빨리 제어에서 벗어날 수 있습니다. 이것이 바로 더 깊은 구성요소에 상황별 정보를 제공해야 할 때
종속성 주입🎜을 권장하는 이유입니다. 이유. 🎜🎜🎜🎜

🎜🎜하위 구성 요소 인스턴스 또는 하위 요소 액세스🎜🎜🎜🎜props와 이벤트가 있음에도 불구하고 때로는 JavaScript에서 직접 하위 구성 요소에 액세스해야 할 수도 있습니다. 이를 달성하려면 ref 속성을 ​​통해 하위 구성 요소에 ID 참조를 할당할 수 있습니다. 예: 🎜

this.$refs.usernameInput.focus()
🎜이제 이 ref를 정의한 구성 요소에서 다음을 사용할 수 있습니다. 🎜긴급 상황에 대비해 이 <base-input> 인스턴스에 액세스하려면
<google-map>
  <google-map-region v-bind:shape="cityBoundaries">
    <google-map-markers v-bind:places="iceCreamShops"></google-map-markers>
  </google-map-region>
</google-map>

를 사용하세요. 예를 들어 프로그래밍 방식으로 상위 구성 요소의 입력 상자에 초점을 맞춥니다. 지금의 예에서 <base-input> 구성 요소는 유사한 ref를 사용하여 내부의 지정된 요소에 대한 액세스를 제공할 수도 있습니다. 예: <base-input> 实例,以便不时之需。比如程序化地从一个父级组件聚焦这个输入框。在刚才那个例子中,该 <base-input> 组件也可以使用一个类似的 ref 提供对内部这个指定元素的访问,例如:

provide: function () {
  return {
    getMap: this.getMap
  }
}

甚至可以通过其父级组件定义方法:

inject: ['getMap']

这样就允许父级组件通过下面的代码聚焦 <base-input> 里的输入框:

// 一次性将这个日期选择器附加到一个输入框上
// 它会被挂载到 DOM 上。
mounted: function () {
  // Pikaday 是一个第三方日期选择器的库
  this.picker = new Pikaday({
    field: this.$refs.input,
    format: 'YYYY-MM-DD'
  })
},
// 在组件被销毁之前,
// 也销毁这个日期选择器。
beforeDestroy: function () {
  this.picker.destroy()
}

refv-for 一起使用的时候,你得到的引用将会是一个包含了对应数据源的这些子组件的数组。

$refs 只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组件的“逃生舱”——你应该避免在模板或计算属性中访问 $refs


依赖注入

在此之前,在我们描述访问父级组件实例的时候,展示过一个类似这样的例子:

mounted: function () {
  var picker = new Pikaday({
    field: this.$refs.input,
    format: 'YYYY-MM-DD'
  })
  this.$once('hook:beforeDestroy', function () {
    picker.destroy()
  })
}

在这个组件里,所有 <google-map> 的后代都需要访问一个 getMap 方法,以便知道要跟哪个地图进行交互。不幸的是,使用 $parent 属性无法很好的扩展到更深层级的嵌套组件上。这也是依赖注入的用武之地,它用到了两个新的实例选项:provideinject

provide 选项允许我们指定我们想要提供给后代组件的数据/方法。在这个例子中,就是 <google-map> 内部的 getMap 方法:

mounted: function () {
  this.attachDatepicker('startDateInput')
  this.attachDatepicker('endDateInput')
},
methods: {
  attachDatepicker: function (refName) {
    var picker = new Pikaday({
      field: this.$refs[refName],
      format: 'YYYY-MM-DD'
    })
    this.$once('hook:beforeDestroy', function () {
      picker.destroy()
    })
  }
}

然后在任何后代组件里,我们都可以使用 inject 选项来接收指定的我们想要添加在这个实例上的属性:

name: 'unique-name-of-my-component'

你可以在这里看到完整的示例。相比 $parent 来说,这个用法可以让我们在任意后代组件中访问 getMap,而不需要暴露整个 <google-map> 实例。这允许我们更好的持续研发该组件,而不需要担心我们可能会改变/移除一些子组件依赖的东西。同时这些组件之间的接口是始终明确定义的,就和 props

Vue.component('unique-name-of-my-component', {
  // ...
})

Even 메서드는 상위 구성 요소를 통해 정의할 수 있습니다.

name: 'stack-overflow',
template: '<div><stack-overflow></stack-overflow></div>'

이렇게 하면 상위 구성 요소가 다음 코드를 통해 <base-input>의 입력 상자에 집중할 수 있습니다.

그러나 의존성 주입은 여전히 ​​부정적인 영향을 미칩니다. 이는 애플리케이션의 구성 요소를 현재 구성된 방식에 연결하므로 리팩토링이 더 어려워집니다. 또한 제공된 속성은 응답하지 않습니다. 이는 의도적으로 설계된 것입니다. 중앙 집중식 데이터 규모를 생성하기 위해 이를 사용하는 것은 $root를 사용하여 이 작업을 수행하는 데 충분하지 않기 때문입니다. 공유하려는 속성이 일반이 아닌 애플리케이션에만 해당되거나 상위 구성 요소에서 제공된 데이터를 업데이트하려는 경우 대신 Vuex는 실제 상태 관리 솔루션입니다.

$root做这件事都是不够好的。如果你想要共享的这个属性是你的应用特有的,而不是通用化的,或者如果你想在祖先组件中更新所提供的数据,那么这意味着你可能需要换用一个像 Vuex 这样真正的状态管理方案了。

你可以在 API 参考文档学习更多关于依赖注入的知识。


程序化的事件侦听器


现在,你已经知道了 $emit 的用法,它可以被 v-on 侦听,但是 Vue 实例同时在其事件接口中提供了其它的方法。我们可以:

  • 通过 $on(eventName, eventHandler) 侦听一个事件

  • 通过 $once(eventName, eventHandler) 一次性侦听一个事件

  • 通过 $off(eventName, eventHandler) 停止侦听一个事件

你通常不会用到这些,但是当你需要在一个组件实例上手动侦听事件时,它们是派得上用场的。它们也可以用于代码组织工具。例如,你可能经常看到这种集成一个第三方库的模式:

components: {
  TreeFolderContents: () => import('./tree-folder-contents.vue')
}

这里有两个潜在的问题:

  • 它需要在这个组件实例中保存这个 picker,如果可以的话最好只有生命周期钩子可以访问到它。这并不算严重的问题,但是它可以被视为杂物。

  • 我们的建立代码独立于我们的清理代码,这使得我们比较难于程序化地清理我们建立的所有东西。

你应该通过一个程序化的侦听器解决这两个问题:

<my-component inline-template>
  <div>
    <p>These are compiled as the component's own template.</p>
    <p>Not parent's transclusion content.</p>
  </div>
</my-component>

使用了这个策略,我甚至可以让多个输入框元素同时使用不同的 Pikaday,每个新的实例都程序化地在后期清理它自己:

<script type="text/x-template" id="hello-world-template">
  <p>Hello hello hello</p>
</script>
Vue.component('hello-world', {
  template: '#hello-world-template'
})

查阅这个 fiddle 可以了解到完整的代码。注意,即便如此,如果你发现自己不得不在单个组件里做很多建立和清理的工作,最好的方式通常还是创建更多的模块化组件。在这个例子中,我们推荐创建一个可复用的 <input-datepicker>API 참조 문서에 대해 자세히 알아볼 수 있습니다. 의존성 주입.

🎜
🎜

프로그래밍 방식 이벤트 리스너
🎜이제 $emit의 사용법을 이미 알고 있으므로 v-on으로 들을 수 있지만 Vue 인스턴스도 이벤트 인터페이스에 있습니다. 다른 방법은 다음과 같습니다. 제공됩니다. 다음을 수행할 수 있습니다. 🎜
  • 🎜 $on(eventName, eventHandler)🎜🎜
  • 🎜via<를 통해 이벤트 듣기 code>$once(eventName, eventHandler) 한 번에 이벤트 듣기🎜🎜
  • 🎜$off(eventName, eventHandler)🎜🎜🎜🎜를 통해 이벤트 듣기를 중지하세요. 일반적으로 사용되지는 않지만 구성 요소 인스턴스에서 이벤트를 수동으로 수신해야 할 때 유용합니다. 코드 구성 도구에서도 사용할 수 있습니다. 예를 들어, 타사 라이브러리를 통합하는 다음 패턴을 자주 볼 수 있습니다. 🎜
    Vue.component('terms-of-service', {
      template: `
        <div v-once>
          <h1>Terms of Service</h1>
          ... a lot of static content ...
        </div>
      `
    })
    🎜여기에는 두 가지 잠재적인 문제가 있습니다. 🎜
    • 🎜저장이 필요합니다. 가능하면 수명 주기 후크만 액세스할 수 있도록 이 구성요소 인스턴스에 있는 이 선택기입니다. 이는 심각한 문제는 아니지만 혼란스러운 것으로 간주될 수 있습니다. 🎜🎜
    • 🎜우리 빌드 코드는 정리 코드와 독립적이므로 우리가 빌드한 모든 것을 프로그래밍 방식으로 정리하기가 더 어렵습니다. 🎜🎜🎜🎜프로그래밍 방식의 리스너로 두 가지 문제를 모두 해결해야 합니다. 🎜rrreee🎜이 전략을 사용하면 서로 다른 Pikaday를 사용하여 동시에 여러 개의 입력 상자 요소를 가질 수도 있으며 각 새 인스턴스는 프로그래밍 방식으로 나중에 자체적으로 정리됩니다. 🎜rrreee 🎜 전체 코드를 보려면 이 바이올린을 확인하세요. 그럼에도 불구하고 단일 구성 요소에서 많은 설정 및 정리 작업을 수행해야 하는 경우 일반적으로 더 많은 모듈식 구성 요소를 만드는 것이 가장 좋습니다. 이 예에서는 재사용 가능한 <input-datepicker> 구성 요소를 생성하는 것이 좋습니다. 🎜

      프로그래밍 방식 리스너에 대해 자세히 알아보려면 인스턴스 메서드/이벤트 관련 API를 확인하세요.

      Vue의 이벤트 시스템은 브라우저의 EventTarget API와 다릅니다. 유사하게 작동하지만 $emit, $on$offdispatchEvent가 아닙니다. addEventListenerremoveEventListener. $emit$on, 和 $off 并不是 dispatchEventaddEventListener 和 removeEventListener 的别名。


      循环引用


      递归组件

      组件是可以在它们自己的模板中调用自身的。不过它们只能通过 name 选项来做这件事:

      rrreee

      当你使用 Vue.component 全局注册一个组件时,这个全局的 ID 会自动设置为该组件的 name 选项。

      rrreee

      稍有不慎,递归组件就可能导致无限循环:

      rrreee

      类似上述的组件将会导致“max stack size exceeded”错误,所以请确保递归调用是条件性的 (例如使用一个最终会得到 falsev-if)。


      组件之间的循环引用

      假设你需要构建一个文件目录树,像访达或资源管理器那样的。你可能有一个 <tree-folder> 组件,模板是这样的:

      rrreee

      还有一个 <tree-folder-contents> 组件,模板是这样的:

      rrreee

      当你仔细观察的时候,你会发现这些组件在渲染树中互为对方的后代和祖先——一个悖论!当通过 Vue.component


      순환 참조


      재귀 구성요소

      구성요소는 괜찮습니다. 자신만의 템플릿으로 자신을 호출합니다. 그러나 name 옵션을 통해서만 이 작업을 수행할 수 있습니다.

      rrreee🎜 Vue.comComponent를 사용하여 구성 요소를 전역적으로 등록하면 전역 ID가 자동으로 The로 설정됩니다. 이 구성요소의 name 옵션입니다. 🎜rrreee🎜주의하지 않으면 재귀 구성 요소가 무한 루프를 일으킬 수 있습니다. 🎜rrreee🎜 위와 같은 구성 요소는 "최대 스택 크기 초과" 오류를 발생시키므로 재귀 호출이 조건부인지 확인하세요(예: < 코드>v-if 또는 false). 🎜🎜
      🎜

      구성 요소 간 순환 참조🎜🎜가정 필요 Finder나 Explorer와 같은 파일 디렉터리 트리를 구축합니다. <tree-folder> 구성 요소가 있을 수 있으며 템플릿은 다음과 같습니다. 🎜rrreee🎜 <tree-folder-contents> 구성 요소도 있습니다. 템플릿은 다음과 같습니다: 🎜rrreee🎜 자세히 살펴보면 이러한 구성 요소가 렌더 트리에서 서로의 후손이자 조상이라는 것을 알 수 있습니다. 역설입니다! 이 역설은 구성 요소가 Vue.comComponent를 통해 전역적으로 등록되면 자동으로 해결됩니다. 이 작업을 수행하는 경우 건너뛸 수 있습니다. 🎜🎜그러나 webpack이나 Browserify 등을 통해 구성 요소에 의존하거나 가져오기 위해 모듈 시스템을 사용하는 경우 오류가 발생합니다. 🎜rrreee🎜 여기서 무슨 일이 일어나고 있는지 설명하기 위해 먼저 두 구성 요소 A와 B를 호출하겠습니다. . 모듈 시스템은 A가 필요하다는 것을 발견하지만 먼저 A는 B에 의존하지만 B는 A에 의존하지만 A는 B에 의존하는 식입니다. 이것은 루프가 되며 다른 구성 요소를 거치지 않고 구성 요소 중 하나를 완전히 구문 분석하는 방법을 모르겠습니다. 이 문제를 해결하려면 모듈 시스템에 "어쨌든 A에는 B가 필요하지만 B를 먼저 구문 분석할 필요는 없습니다."라는 지점을 제공해야 합니다.

      이 예에서는 <tree-folder> 구성 요소를 해당 지점으로 설정합니다. 역설을 일으키는 하위 구성 요소가 <tree-folder-contents> 구성 요소라는 것을 알고 있으므로 이를 등록하기 위해 수명 주기 후크 beforeCreate가 나올 때까지 기다립니다. <tree-folder> 组件设为了那个点。我们知道那个产生悖论的子组件是 <tree-folder-contents> 组件,所以我们会等到生命周期钩子 beforeCreate 时去注册它:

      rrreee

      或者,在本地注册组件的时候,你可以使用 webpack 的异步 import

      rrreee

      这样问题就解决了!


      模板定义的替代品


      内联模板

      inline-template 这个特殊的特性出现在一个子组件上时,这个组件将会使用其里面的内容作为模板,而不是将其作为被分发的内容。这使得模板的撰写工作更加灵活。

      rrreee

      内联模板需要定义在 Vue 所属的 DOM 元素内。

      不过,inline-template 会让模板的作用域变得更加难以理解。所以作为最佳实践,请在组件内优先选择 template 选项或 .vue 文件里的一个 <template> 元素来定义模板。


      X-Template

      另一个定义模板的方式是在一个 <script> 元素中,并为其带上 text/x-template rrreee

      또는 로컬에서 구성 요소를 등록할 때 webpack의 비동기 import를 사용할 수 있습니다.

      rrreee

      이 문제는 해결되었습니다!


      템플릿 정의 대체

      inline-template



      inline-template <인 경우 /code> 이 특수 속성이 하위 구성 요소에 나타나면 구성 요소는 배포할 콘텐츠로 사용하는 대신 내부 콘텐츠를 템플릿으로 사용합니다. 이는 템플릿 작성을 더욱 유연하게 만듭니다.

      rrreee
      인라인 템플릿은 Vue가 속한 DOM 요소 내에서 정의되어야 합니다.

      그러나 inline-template은 템플릿의 범위를 이해하기 더 어렵게 만듭니다. 따라서 가장 좋은 방법은 구성 요소 내의 template 옵션을 선택하거나 .vue 파일의 <template> 요소를 선택하여 템플릿.

      X-Template

      템플릿을 정의하는 또 다른 방법은 <script> 요소에 text/x-template 유형을 입력한 다음 ID를 통해 템플릿을 참조합니다. 예: rrreeex-template은 Vue가 속한 DOM 요소 외부에서 정의되어야 합니다.

      🎜🎜템플릿이 특히 큰 데모 또는 매우 작은 애플리케이션에 사용할 수 있지만 그렇지 않으면 템플릿을 구성 요소의 다른 정의와 분리하므로 사용하지 마십시오. 🎜🎜🎜🎜🎜🎜🎜🎜업데이트 제어🎜🎜🎜🎜🎜Vue의 반응형 시스템 덕분에 Vue는 항상 업데이트 시기를 알 수 있습니다(올바르게 사용하는 경우). 그러나 반응형 데이터가 변경되지 않은 것처럼 보이더라도 강제로 업데이트하려는 경우가 있습니다. 불필요한 업데이트를 방지하고 싶은 상황도 있습니다. 🎜🎜🎜🎜🎜🎜🎜🎜강제 업데이트🎜🎜🎜🎜🎜Vue에서 99.9%의 경우 강제 업데이트를 수행해야 한다면 어딘가에서 뭔가 잘못하고 있는 것입니다. 🎜🎜🎜 🎜Arrays🎜 또는 🎜Objects🎜에 대한 변경 감지 고려 사항을 인식하지 못했거나 Vue의 반응 시스템에서 추적하지 않는 상태에 의존하고 있을 수 있습니다. 🎜

      그러나 위의 작업을 수행한 후에도 드물게 수동으로 업데이트를 강제해야 하는 경우 $forceUpdate를 통해 이 작업을 수행할 수 있습니다. $forceUpdate 来做这件事。


      通过 v-once 创建低开销的静态组件

      渲染普通的 HTML 元素在 Vue 中是非常快速的,但有的时候你可能有一个组件,这个组件包含了大量静态内容。在这种情况下,你可以在根元素上添加 v-once 特性以确保这些内容只计算一次然后缓存起来,就像这样:

      rrreee

      再说一次,试着不要过度使用这个模式。当你需要渲染大量静态内容时,极少数的情况下它会给你带来便利,除非你非常留意渲染变慢了,不然它完全是没有必要的——再加上它在后期会带来很多困惑。例如,设想另一个开发者并不熟悉 v-once

      v-once를 사용하여 오버헤드가 낮은 정적 구성요소 생성

      Vue에서 일반 HTML 요소를 렌더링하는 것은 매우 빠르지만 때로는 많은 정적 콘텐츠를 포함하는 구성 요소가 있을 수 있습니다. 이 경우 루트 요소에 v-once 속성을 ​​추가하여 다음과 같이 콘텐츠가 한 번만 계산되고 캐시되도록 할 수 있습니다. 🎜rrreee
      🎜다시 시도하지 마세요. 이 패턴을 남용하세요. 드물지만 많은 정적 콘텐츠를 렌더링해야 하는 경우에는 편리함을 제공하지만 렌더링 속도 저하에 대해 매우 주의하지 않는 한 완전히 불필요합니다. 게다가 후반 작업에 많은 문제를 일으킬 수도 있습니다. 예를 들어, 다른 개발자가 v-once에 익숙하지 않거나 템플릿에서 이를 놓쳤다고 가정해 보세요. 그들은 템플릿이 올바르게 업데이트되지 않는 이유를 알아내기 위해 많은 시간을 소비할 수 있습니다. 🎜🎜🎜🎜🎜