Vue.jsカスタムコマンド、ドラッグ可能なサスペンションを実現
5108 ワード
Vueは、内蔵命令(v-show、v-forなど)のようなカスタム命令を独自に開発することをサポートしています.通常、最下位のDOM操作の場所で使用されます.本稿では,カスタム命令の基本的な使い方を簡単に紹介し,命令v−dragによるサスペンションドラッグ機能を実現する.
一、基本用法
1)登録
同様のコンポーネントでは、コマンドの登録は、グローバル登録とローカル登録に分けることもできます.名前の通り、グローバル登録はプロジェクトの下のすべてのVueコンポーネントで使用でき、ローカル登録は現在のVueコンポーネントでのみ使用できます.カスタムコンポーネント登録には、コマンド名、コマンドオプションの2つのパラメータが必要です.
簡単なfocusコマンドを例に挙げます.
上記の例は、コマンドバインドの要素がdomに挿入されたときに自動的にフォーカスを取得するカスタムコマンドです.
コマンド名は「focus」、コマンドオプションはオブジェクトで、組み込みコマンドと同様に接頭辞「v-」を付ける必要があります.
次に、コマンド構成オプションについて詳しく説明します.
2)指令配置オプション
命令構成オプションは、実際にはいくつかのフック関数を含むオブジェクトであり、各オプションはフック関数であり、オプションのフックであり、前例focus命令の「inserted」はフック関数である.オプションのフック関数は次のとおりです(Vue公式サイトより抜粋).
各フック関数には、「focus」コマンドでelが使用されるなど、同じパラメータ(すなわち
二、ドラッグ可能なサスペンションを実現する
1)実現効果(ここで体験できる):
2)指令配置項目コードは大体以下の通りである:
3)使用(事前登録が必要):
一、基本用法
1)登録
同様のコンポーネントでは、コマンドの登録は、グローバル登録とローカル登録に分けることもできます.名前の通り、グローバル登録はプロジェクトの下のすべてのVueコンポーネントで使用でき、ローカル登録は現在のVueコンポーネントでのみ使用できます.カスタムコンポーネント登録には、コマンド名、コマンドオプションの2つのパラメータが必要です.
簡単なfocusコマンドを例に挙げます.
//
Vue.directive('focus', {
inserted: function (el) {
el.focus()
}
})
//
var vm = new Vue({
el: '#app',
directives: {
focus: {
//
inserted: function (el) {
el.focus()
}
}
}
})
上記の例は、コマンドバインドの要素がdomに挿入されたときに自動的にフォーカスを取得するカスタムコマンドです.
コマンド名は「focus」、コマンドオプションはオブジェクトで、組み込みコマンドと同様に接頭辞「v-」を付ける必要があります.
次に、コマンド構成オプションについて詳しく説明します.
2)指令配置オプション
命令構成オプションは、実際にはいくつかのフック関数を含むオブジェクトであり、各オプションはフック関数であり、オプションのフックであり、前例focus命令の「inserted」はフック関数である.オプションのフック関数は次のとおりです(Vue公式サイトより抜粋).
bind
:1回のみ呼び出し、命令が初めてエレメントにバインドされたときに呼び出されます.ここでは、一度に初期化設定を行うことができます.inserted
:バインドされた要素が親ノードに挿入されたときに呼び出されます(親ノードのみが存在しますが、ドキュメントに挿入されたとは限りません).update
:あるコンポーネントのVNode更新時に呼び出されますが、そのサブVNode更新の前に発生する場合があります.命令の値が変わったかもしれないし、なかったかもしれない.ただし、更新前後の値を比較することで、不要なテンプレート更新を無視できます(詳細なフック関数パラメータは下を参照).componentUpdated
:命令が存在するコンポーネントのVNodeおよびそのサブVNodeが全て更新されて呼び出される.unbind
:1回のみ呼び出し、命令と要素の結合解除時に呼び出す.各フック関数には、「focus」コマンドでelが使用されるなど、同じパラメータ(すなわち
el
binding
・vnode
・)が使用できます.これらの意味は以下の通りです(Vue公式サイトより抜粋).oldVnode
:コマンドにバインドされた要素は、DOMを直接操作するために使用できます.el
:次の属性を持つオブジェクト:binding
:命令名、含まないname
接頭辞.v-
:命令のバインド値、例えば:value
で、バインド値はv-my-directive="1 + 1"
です.2
:命令バインドの前の値は、oldValue
およびupdate
フックのみで使用可能です.値が変更されるかどうかにかかわらず使用できます.componentUpdated
:文字列形式の命令式.例えばexpression
では、式はv-my-directive="1 + 1"
です."1 + 1"
:命令に渡すパラメータは、オプションです.例えばarg
でパラメータはv-my-directive:foo
です."foo"
:修飾子を含むオブジェクト.例えば、modifiers
のうち、修飾子の対象はv-my-directive.foo.bar
である.{ foo: true, bar: true }
:Vueコンパイルにより生成された仮想ノード.vnode
:前の仮想ノードは、oldVnode
およびupdate
フックのみで使用可能です.二、ドラッグ可能なサスペンションを実現する
1)実現効果(ここで体験できる):
2)指令配置項目コードは大体以下の通りである:
function inserted (el, binding, vNode) {
el.setAttribute('style', 'position: fixed; z-index: 9999')
}
function bind (el, bindding, vNode) {
el.setAttribute('draggable', true)
let left, top, width, height
el._dragstart = function (event) {
event.stopPropagation()
left = event.clientX - el.offsetLeft
top = event.clientY - el.offsetTop
width = el.offsetWidth
height = el.offsetHeight
}
el._checkPosition = function () { //
let width = el.offsetWidth
let height = el.offsetHeight
let left = Math.min(el.offsetLeft, document.body.clientWidth - width)
left = Math.max(0, left)
let top = Math.min(el.offsetTop, document.body.clientHeight - height)
top = Math.max(0, top)
el.style.left = left + 'px'
el.style.top = top + 'px'
el.style.width = width + 'px'
el.style.height = height + 'px'
}
el._dragEnd = function (event) {
event.stopPropagation()
left = event.clientX - left
top = event.clientY - top
el.style.left = left + 'px'
el.style.top = top + 'px'
el.style.width = width + 'px'
el.style.height = height + 'px'
el._checkPosition()
}
el._documentAllowDraop = function (event) {
event.preventDefault()
}
document.body.addEventListener('dragover', el._documentAllowDraop)
el.addEventListener('dragstart', el._dragstart)
el.addEventListener('dragend', el._dragEnd)
window.addEventListener('resize', el._checkPosition)
}
function unbind (el, bindding, vNode) {
document.body.removeEventListener('dragover', el._documentAllowDraop)
el.removeEventListener('dragstart', el._dragstart)
el.removeEventListener('dragend', el._dragEnd)
window.removeEventListener('resize', el._checkPosition)
delete el._documentAllowDraop
delete el._dragstart
delete el._dragEnd
delete el._checkPosition
}
export default {
bind,
unbind,
inserted
}
3)使用(事前登録が必要):
export default {
}