사용자 정의 지시어


목차


소개


핵심 기능 외에도 기본 내장 명령어(v-modelv-show< /code>), Vue에서는 사용자 정의 지시어 등록도 허용합니다. Vue2.0에서 코드 재사용 및 추상화의 주요 형태는 구성 요소입니다. 그러나 어떤 경우에는 여전히 일반 DOM 요소에 대해 낮은 수준의 작업을 수행해야 하며, 이 경우 사용자 지정 지시문이 사용됩니다. 다음과 같이 입력 상자에 초점을 맞추는 예를 들어보세요. v-modelv-show),Vue 也允许注册自定义指令。注意,在 Vue2.0 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令。举个聚焦输入框的例子,如下:

4.gif

当页面加载时,该元素将获得焦点 (注意:autofocus 在移动版 Safari 上不工作)。事实上,只要你在打开这个页面后还没点击过任何内容,这个输入框就应当还是处于聚焦状态。现在让我们用指令来实现这个功能:

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时……
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

如果想注册局部指令,组件中也接受一个 directives 的选项:

directives: {
  focus: {
    // 指令的定义
    inserted: function (el) {
      el.focus()
    }
  }
}

然后你可以在模板中任何元素上使用新的 v-focus 属性,如下:

<input v-focus>


钩子函数


一个指令定义对象可以提供如下几个钩子函数 (均为可选):

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

  • update4.gif

  • 페이지가 로드되면 요소에 포커스가 부여됩니다(참고: autofocus는 모바일 Safari에서 작동하지 않음). 실제로 이 페이지를 연 후 아무 것도 클릭하지 않는 한 입력 상자에는 여전히 초점이 맞춰져 있어야 합니다. 이제 지시문을 사용하여 이 기능을 구현해 보겠습니다.
<div id="hook-arguments-example" v-demo:foo.a.b="message"></div>
로컬 지시문을 등록하려는 경우 구성 요소는 지시문 옵션도 허용합니다.

Vue.directive('demo', {
  bind: function (el, binding, vnode) {
    var s = JSON.stringify
    el.innerHTML =
      'name: '       + s(binding.name) + '<br>' +
      'value: '      + s(binding.value) + '<br>' +
      'expression: ' + s(binding.expression) + '<br>' +
      'argument: '   + s(binding.arg) + '<br>' +
      'modifiers: '  + s(binding.modifiers) + '<br>' +
      'vnode keys: ' + Object.keys(vnode).join(', ')
  }
})

new Vue({
  el: '#hook-arguments-example',
  data: {
    message: 'hello!'
  }
})
그런 다음 템플릿 v-focus 속성, 다음과 같습니다:
<div id="baseexample">
  <p>Scroll down the page</p>
  <p v-pin="200">Stick me 200px from the top of the page</p>
</div>

🎜🎜Hook function🎜🎜🎜🎜🎜A 명령 정의 개체는 다음 후크 기능을 제공할 수 있습니다. (모두 선택 사항): 🎜🎜🎜🎜🎜bind: 명령이 처음으로 요소에 바인딩될 때 한 번만 호출됩니다. 여기에서 일회성 초기화 설정을 수행할 수 있습니다. 🎜🎜🎜🎜삽입: 바인딩된 요소가 상위 노드에 삽입될 때 호출됩니다(상위 노드만 존재하도록 보장되지만 반드시 문서에 삽입될 필요는 없습니다). 🎜🎜🎜🎜update: 구성 요소의 VNode가 업데이트될 때 호출되지만 🎜하위 VNode가 업데이트되기 전에 발생할 수도 있습니다🎜. 지시어의 값은 변경되었을 수도 있고 변경되지 않았을 수도 있습니다. 하지만 업데이트 전과 후의 값을 비교하여 불필요한 템플릿 업데이트를 무시할 수 있습니다(자세한 후크 기능 매개 변수는 아래 참조). 🎜🎜🎜🎜🎜VNodes에 대한 자세한 내용은 🎜나중에🎜 🎜렌더링 기능🎜에 대해 논의할 때 소개하겠습니다. 🎜

  • comComponentUpdated: 명령어가 위치한 구성 요소의 모든 VNode componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。

接下来我们来看一下钩子函数的参数 (即 elbindingvnode 和 oldVnode)。


钩子函数参数


指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM 。

  • binding:一个对象,包含以下属性:

    • name:指令名,不包括 v- 前缀。

    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2

    • oldValue:指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。

    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"

    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"

    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }

  • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。

  • oldVnode:上一个虚拟节点,仅在 updatecomponentUpdated 钩子中可用。

除了 el 之外,其它参数都应该是只读的,切勿进行修改。如果需要在钩子之间共享数据,建议通过元素的 dataset 및 해당 하위 VNode가 업데이트된 후에 호출됩니다.

unbind: 명령이 요소에서 바인딩 해제될 때 한 번만 호출됩니다.

다음으로 후크 함수의 매개변수(예: el, bind, vnode)를 살펴보겠습니다. 및 < code>oldVnode). 1.jpg


후크 기능 매개변수


명령 후크 기능이 전달됩니다 매개변수:

el: 명령어에 바인딩된 요소를 사용하여 DOM을 직접 작동할 수 있습니다. 🎜🎜🎜바인딩: 다음 속성을 포함하는 개체: 🎜
    🎜🎜name: v- 접두사를 제외한 명령어 이름입니다. 🎜🎜🎜value: 명령의 바인딩 값입니다. 예를 들어 v-my-directive="1 + 1"에서 바인딩 값은 다음과 같습니다. <코드 >2. 🎜🎜🎜oldValue: 명령 바인딩의 이전 값으로, updatecomComponentUpdated 후크에서만 사용할 수 있습니다. 값이 변경되었는지 여부에 관계없이 사용할 수 있습니다. 🎜🎜🎜표현: 문자열 형식의 명령어 표현입니다. 예를 들어 v-my-directive="1 + 1"에서 표현식은 "1 + 1"입니다. 🎜🎜🎜arg: 명령에 전달되는 매개변수, 선택사항. 예를 들어 v-my-directive:foo에서 매개변수는 "foo"입니다. 🎜🎜🎜modifiers: 수정자를 포함하는 개체입니다. 예: v-my-directive.foo.bar에서 수정자 개체는 { foo: true, bar: true }입니다. 🎜
🎜🎜vnode: Vue 컴파일로 생성된 가상 노드입니다. 자세한 내용을 알아보려면 VNode API🎜로 이동하세요. . 🎜🎜🎜oldVnode: 이전 가상 노드이며 updatecomComponentUpdated 후크에서만 사용할 수 있습니다. 🎜
🎜el을 제외한 다른 모든 매개변수는 읽기 전용이어야 하며 수정하면 안 됩니다. 후크 간에 데이터를 공유해야 하는 경우 요소의 dataset🎜 계속 진행하세요. 🎜🎜🎜다음은 이러한 속성을 사용하는 사용자 정의 후크의 예입니다. 🎜
Vue.directive('pin', {
  bind: function (el, binding, vnode) {
    el.style.position = 'fixed'
    el.style.top = binding.value + 'px'
  }
})
new Vue({
  el: '#baseexample'
})
<div id="dynamicexample">
  <h3>Scroll down inside this section ↓</h3>
  <p v-pin:[direction]="200">I am pinned onto the page at 200px to the left.</p>
</div>
🎜🎜🎜🎜🎜🎜🎜🎜🎜🎜동적 지시어 매개변수🎜🎜🎜

지시문의 매개변수는 동적일 수 있습니다. 예를 들어 v-mydirective:[argument]="value"에서 argument 매개변수는 구성 요소 인스턴스 데이터를 기반으로 업데이트될 수 있습니다! 이를 통해 사용자 지정 지시문을 응용 프로그램에서 유연하게 사용할 수 있습니다. v-mydirective:[argument]="value" 中,argument 参数可以根据组件实例数据进行更新!这使得自定义指令可以在应用中被灵活使用。

例如你想要创建一个自定义指令,用来通过固定布局将元素固定在页面上。我们可以像这样创建一个通过指令值来更新竖直位置像素值的自定义指令:

Vue.directive('pin', {
  bind: function (el, binding, vnode) {
    el.style.position = 'fixed'
    var s = (binding.arg == 'left' ? 'left' : 'top')
    el.style[s] = binding.value + 'px'
  }
})
new Vue({
  el: '#dynamicexample',
  data: function () {
    return {
      direction: 'left'
    }
  }
})
Vue.directive('color-swatch', function (el, binding) {
  el.style.backgroundColor = binding.value
})

这会把该元素固定在距离页面顶部 200 像素的位置。但如果场景是我们需要把元素固定在左侧而不是顶部又该怎么办呢?这时使用动态参数就可以非常方便地根据每个组件实例来进行更新。

<div v-demo="{ color: 'white', text: 'hello!' }"></div>
Vue.directive('demo', function (el, binding) {
  console.log(binding.value.color) // => "white"
  console.log(binding.value.text)  // => "hello!"
})

结果:

1.gif

这样这个自定义指令现在的灵活性就足以支持一些不同的用例了。


函数简写


在很多时候,你可能想在 bindupdate

예를 들어 고정 레이아웃을 통해 페이지의 요소를 수정하는 사용자 정의 지시어를 만들고 싶습니다. 다음과 같이 지시문 값으로 수직 위치 픽셀 값을 업데이트하는 사용자 정의 지시문을 만들 수 있습니다.

rrreeerrreee
이렇게 하면 페이지 상단에서 200픽셀 위치에 요소가 고정됩니다. 하지만 요소를 위쪽이 아닌 왼쪽에 고정해야 하는 시나리오라면 어떻게 될까요? 이때 동적 매개변수를 사용하면 각 구성 요소 인스턴스를 매우 편리하게 업데이트할 수 있습니다.

rrreeerrree

결과: 1.gif이러한 방식으로 이 사용자 정의 지시어는 이제 몇 가지 다른 사용 사례를 지원할 수 있을 만큼 유연해졌습니다.



함수 약어

🎜많은 경우 바인딩업데이트할 때 트리거할 수 있습니다. 다른 후크에 관계없이 동일한 동작입니다. 예를 들어 다음과 같이 작성합니다.🎜rrreee🎜🎜🎜🎜🎜🎜Object literal🎜🎜🎜🎜🎜명령에 여러 값이 필요한 경우 JavaScript 개체 리터럴을 전달할 수 있습니다. 지시문 함수는 모든 합법적인 JavaScript 표현식을 허용한다는 점을 기억하십시오. 🎜🎜rrreeerrreee🎜🎜🎜🎜 🎜