> 웹 프론트엔드 > View.js > Vue 슬롯 변경 사항을 모니터링하는 방법은 무엇입니까? 이 트릭을 시도해 보세요!

Vue 슬롯 변경 사항을 모니터링하는 방법은 무엇입니까? 이 트릭을 시도해 보세요!

青灯夜游
풀어 주다: 2022-09-28 19:53:15
앞으로
2766명이 탐색했습니다.

Vue에서 슬롯 변경 사항을 모니터링하는 방법은 무엇입니까? 다음 글에서는 Vue 슬롯 변경 사항을 모니터링하는 방법을 소개하겠습니다. 도움이 되셨으면 좋겠습니다!

Vue 슬롯 변경 사항을 모니터링하는 방법은 무엇입니까? 이 트릭을 시도해 보세요!

최근에는 구성 요소의 콘텐츠(슬롯, 하위 구성 요소 등)가 변경될 때마다 구성 요소의 상태를 업데이트해야 합니다. 맥락상 입력의 유효성 상태를 추적하는 양식 구성 요소입니다.

아래 코드 조각은 Options API 형식으로 작성되었지만, 지정된 경우를 제외하고는 Vue2 및 Vue2에서 사용할 수 있습니다. [관련 권장사항: vuejs 비디오 튜토리얼Options API格式编写的,但除了指定的地方外可以在Vue2 和 Vue2中使用。【相关推荐:vuejs视频教程

开始

先从控制表单状态开始,根据状态修改一个类,孩子内容使用<slot/>填充:

<template>
  <form :class="{ &#39;--invalid&#39;: isInvalid }">
    <slot />
  </form>
</template>

<script>
export default {
  data: () => ({
    isInvalid: false,
  }),
};
</script>
로그인 후 복사

为了更新isInvalid属性,我们需要添加一个触发的事件,可以使用 sumit 事件 ,但我更喜用 input 事件。

表单事件7个: focus, blur, input, select, change, reset, submit 等,具体详解看这篇文章:https://blog.csdn.net/qq_4379...

表单不会触发 input 事件,但我们可以使用 "事件委托"。我们将监听器附加到父元素(<form>)上,当事件发生在它的子元素(<input><select><textarea>等)上时就会被触发。

任何时候在这个组件的<slot>中触发input事件,表单将捕获该事件。

<template>
  <form :class="{ &#39;--invalid&#39;: isInvalid }" @input="validate">
    <slot />
  </form>
</template>

<script>
export default {
  data: () => ({
    isInvalid: false,
  }),
  methods: {
    validate() {
      // 验证逻辑
    }
  }
};
</script>
로그인 후 복사

验证逻辑可以是简单或复杂的。本文为了演示,用简单的方法,使用form.checkValidity() API 来查看表单是否基于HTML验证属性而有效。

为了访问<form>元素。可以用refs$el属性。为了简单起见,本文使用$el

<template>
  <form :class="{ &#39;--invalid&#39;: isInvalid }" @input="validate">
    <slot />
  </form>
</template>

<script>
export default {
  data: () => ({
    isInvalid: false,
  }),
  methods: {
    validate() {
      this.isInvalid = !this.$el.checkValidity()
    }
  }
};
</script>
로그인 후 복사

问题

这里有一点问题。如果表单的内容改变了,会发生什么?如果一个<input>在表单加载被添加到DOM中,会发生什么?

举个例子,我们把这个表单组件称为 "MyForm",在 App 中,内容如下:

// App.vue
<template>
  <MyForm>
    <input
      v-model="showInput"
      id="toggle-name"
      name="toggle-name"
      type="checkbox"
    />
    <label for="toggle-name">显示其它 input</label> 

    <template v-if="showInput">
      <label for="name">Name:</label>
      <input id="name" name="name" required />
    </template>

    <button type="submit">提交</button>
  </MyForm>
</template>

<script>
import Form from "./components/form.vue";
export default {
  name: "App",
  components: {
    MyForm: Form,
  },
  data: () => ({
    showInput: false,
  }),
};
</script>
로그인 후 복사

App.vue通过条件来隐藏显示某些 input,我们的表单需要知道。在这种情况下,我们会想到在表单内容发生变化时跟踪其有效性,而不仅仅是在 input 事件或mounted生命周期钩子上。否则,可能会显示不正确的信息。

熟悉 Vue的生命周期钩子小伙伴,这里可能会想到使用 update 来跟踪变化。理论上,这听起来不错。在实践中,它会创造一个无限的循环,然后浏览器挂了。

解决方法

经过一番研究和测试,最佳解决方案是使用MutationObserver API。它是浏览器内置的方法,提供了监视对DOM树所做更改的能力,如果节点的增减、属性的变动、文本内容的变动,这个 API 都可以得到通知。

它是原生的方法,所以不受限于框架。

使用时,首先使用MutationObserver构造函数,新建一个观察器实例,同时指定这个实例的回调函数。在每次 DOM 变动后调用,这个回调都被调用。该回调函数接受两个参数,第一个是变动数组,第二个是观察器实例,将我们的 form 组件改写成如下:

<template>
  <form :class="{ &#39;--invalid&#39;: isInvalid }" @input="validate">
    <slot />
  </form>
</template>

<script>
export default {
  data: () => ({
    isInvalid: false,
  }),
  mounted() {
    const observer = new MutationObserver(this.validate);
    observer.observe(this.$el, {
      childList: true,
      subtree: true,
    });
    this.observer = observer;
  },
  methods: {
    validate() {
      this.isInvalid = !this.$el.checkValidity();
    },
  },
  beforeUnmount() {
    this.observer.disconnect();
  },
};
</script>


<style scoped>
</style>
로그인 후 복사

这里还需要使用 beforeUnmount生命周期事件来断开observer的连接,这会清除它所分配的任何内存。

最后,我们将isInvalid状态传递给要访问的内容的插件槽,这也称作用域的槽,它非常有用。

<template>
  <form :class="{ &#39;--invalid&#39;: isInvalid }" @input="validate">
    <slot v-bind="{ isInvalid }" />
  </form>
</template>

<script>
export default {
  data: () => ({
    isInvalid: false,
  }),
  mounted() {
    const observer = new MutationObserver(this.validate);
    observer.observe(this.$el, {
      childList: true,
      subtree: true,
    });
    this.observer = observer;
  },
  methods: {
    validate() {
      this.isInvalid = !this.$el.checkValidity();
    },
  },
  beforeUnmount() {
    this.observer.disconnect();
  },
};
</script>
로그인 후 복사

通过这样的设置,可以在我们的表单组件中添加任意数量的 input,并添加任何它需要的条件渲染逻辑。只要input使用HTML验证属性,表单就会跟踪它是否处于有效状态。

此外,由于使用的是作用域槽,我们将表单的状态提供给父级,所以父级可以对有效性的变化做出反应。

例如,在 App.vue]

시작

양식 상태를 제어하여 시작하고, 상태에 따라 클래스를 수정하고, 하위 콘텐츠를 <slot/><로 채웁니다. /code>:

<template>
  <MyForm>
    <template slot:default="form">
      <label for="name">Name:</label>
      <input id="name" name="name" required>

      <button
        type="submit"
        :class="{ disabled: form.isInvalid }"
      >
        Submit
      </button>
    </template>
  </MyForm>
</template>
로그인 후 복사

isInvalid 속성을 ​​업데이트하려면 트리거된 이벤트를 추가해야 합니다. sumit 이벤트를 사용할 수 있지만 저는 입력 이벤트.

🎜7가지 양식 이벤트: 초점, 흐림, 입력, 선택, 변경, 재설정, 제출 등. 자세한 설명은 다음 문서를 참조하세요: https://blog.csdn.net/qq_4379...🎜🎜
🎜 양식은 입력 이벤트를 실행하지 않지만 "이벤트 위임자"를 사용할 수 있습니다. 리스너를 상위 요소(<form>)에 연결하고 해당 하위 요소(<input>, <select>)에서 이벤트가 발생하면 ; , <textarea> 등)이 트리거됩니다. 🎜🎜이 구성 요소의 <slot>에서 input 이벤트가 트리거될 때마다 양식이 이벤트를 캡처합니다. 🎜rrreee🎜검증 논리는 간단할 수도 있고 복잡할 수도 있습니다. 데모 목적으로 이 기사에서는 form.checkValidity() API를 사용하여 HTML 유효성 검사 속성을 기반으로 양식이 유효한지 확인하는 간단한 방법을 사용합니다. 🎜🎜 <form> 요소에 액세스합니다. refs 또는 $el 속성을 ​​사용할 수 있습니다. 단순화를 위해 이 문서에서는 $el을 사용합니다. 🎜rrreee

질문

🎜여기에 약간의 문제가 있습니다. 양식의 내용이 변경되면 어떻게 되나요? 양식이 로드될 때 <input>이 DOM에 추가되면 어떻게 되나요? 🎜🎜예를 들어 이 양식 구성 요소를 "MyForm"이라고 부릅니다. App에서 내용은 다음과 같습니다. 🎜rrreee🎜 App.vue가 조건을 통해 표시를 숨길 때 거기 우리 양식이 알아야 할 특정 입력입니다. 이 경우 input 이벤트나 mounted 수명 주기 후크뿐만 아니라 변경 시 양식 콘텐츠의 유효성을 추적하는 것을 고려할 것입니다. 그렇지 않으면 잘못된 정보가 표시될 수 있습니다. 🎜🎜Vue의 라이프 사이클 후크에 익숙한 친구라면 update를 사용하여 변경 사항을 추적하는 것을 고려할 수 있습니다. 이론적으로 이것은 훌륭하게 들립니다. 실제로는 무한 루프가 발생하고 브라우저가 중단됩니다. 🎜

솔루션

🎜몇 가지 연구와 테스트를 거친 후 가장 좋은 솔루션은 MutationObserver API를 사용하는 것입니다. DOM 트리의 변경 사항을 모니터링하는 기능을 제공하는 브라우저에 내장된 방법입니다. 이 API는 노드가 추가되거나 제거되거나, 속성이 변경되거나, 텍스트 콘텐츠가 변경되는 경우 알림을 받을 수 있습니다. 🎜🎜네이티브 방식이므로 프레임워크에 국한되지 않습니다. 🎜🎜사용할 때는 먼저 MutationObserver 생성자를 사용하여 새로운 관찰자 인스턴스를 만들고 이 인스턴스의 콜백 함수를 지정합니다. DOM이 변경될 때마다 호출되며 이 콜백이 호출됩니다. 콜백 함수는 두 개의 매개변수를 허용합니다. 첫 번째는 변경 배열이고 두 번째는 관찰자 인스턴스입니다. form 구성 요소를 다음과 같이 다시 작성하세요. 🎜rrreee🎜또한 여기서 beforeUnmount를 사용해야 합니다. /code>수명주기 이벤트를 통해 <code>관찰자의 연결을 끊고 할당된 메모리를 모두 지웁니다. 🎜🎜마지막으로 액세스하려는 콘텐츠의 플러그인 슬롯에 isInvalid 상태를 전달합니다. 이는 범위 슬롯이라고도 하며 매우 유용합니다. 🎜rrreee🎜이 설정을 사용하면 양식 구성 요소에 입력을 원하는 만큼 추가하고 필요한 조건부 렌더링 논리를 추가할 수 있습니다. 입력이 HTML 유효성 검사 속성을 사용하는 한 양식은 유효한 상태인지 추적합니다. 🎜🎜 또한 범위가 지정된 슬롯을 사용하므로 양식의 상태를 부모에게 제공하므로 부모는 유효성 변경에 반응할 수 있습니다. 🎜🎜예를 들어 App.vue에서 양식이 유효하지 않은 경우 제출 버튼을 "비활성화"하려면 다음과 같이 작성하면 됩니다.🎜rrreee🎜nice~.🎜🎜이 기사가 되길 바랍니다. 귀하의 향후 발전에 도움이 될 수 있습니다. 🎜

(학습 영상 공유: 웹 프론트엔드 개발, 기본 프로그래밍 영상)

위 내용은 Vue 슬롯 변경 사항을 모니터링하는 방법은 무엇입니까? 이 트릭을 시도해 보세요!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:segmentfault.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿