在 Vue JS 和事件监听器中使用 Laravel Blade 模板
Using Laravel Blade templates with Vue JS and event listeners
我正在使用 Laraval 自定义组件,例如,我有:
components/input.blade.php
<input type="text" class="rounded">
注意:这是一个简单的例子,这里关键的部分是我想复用blade模板生成的HTML
现在我可以创建一个带有作用域插槽的 Vue 组件了:
js/components/Search.vue
<template>
<div>
<slot name="search-input" />
</div>
</template>
<script>
export default {
methods: {
focus() {
console.log('focus input');
}
}
}
</script>
// ... and registering the component
// among others
Vue.component('search', require('js/components/Search'));
new Vue({
el: '#vue_app'
});
太棒了,我可以按如下方式使用我的组件:
views/somepage.blade.php
<search>
<template v-slot:search>
<x-input>
</template>
</search>
一切都按预期工作,但是如您所见,我有一个 focus
方法,我希望在关注 blade 输入时触发该方法。
现在我不能这样做了:
js/components/Search.vue
<template>
<div>
<slot name="search-input" @focus="focus" />
</div>
</template>
<script>
export default {
methods: {
focus() {
console.log('focus input');
}
}
}
</script>
但我可以做到:
js/components/Search.vue
<template>
<div>
<div ref="search-container"><slot name="search-input" /></div>
</div>
</template>
<script>
export default {
methods: {
mounted() {
this.$refs['search-container'].querySelector('input').addEventListener('focus', this.focus)
},
focus() {
console.log('focus input');
}
}
}
</script>
但我不确定在 Vue 组件中使用 addEventListener
是最好的方法。
是否有更好的方法来实现我的目标?
不确定具体问题,也许
this.$refs['search-container'].querySelector('input').addEventListener('focus', this.focus)
以某种方式 async (生命周期方面),您可能需要将其包装成 nextTick
this.$nextTick(() => {
this.$refs['search-container'].querySelector('input').addEventListener('focus', this.focus)
})
顺便说一句,IMO 这种添加侦听器的方式没有问题。
此外,也许可以按照此处的建议尝试 @focus.native="focus"
:https://vuejs.org/v2/guide/components-custom-events.html#Binding-Native-Events-to-Components
因为可能是水合作用,元素可能需要一些时间才能作为 Vue 节点可用,因此将其固定在本地焦点可能是解决方案。
不确定这些是否可行,但这是我的两个想法。
我的首选解决方案是利用 scoped slots 及其插槽道具来传递方法。最终解决方案如下所示:
views/somepage.blade.php
<search>
<template v-slot:default>
<x-input @focus="slot.methods.focus">
</template>
</search>
你可以在上面看到我正在引用插槽道具变量 slot
来访问我在下面定义的变量。请注意,我传递了一个 methods
对象。调用对象 methods
只是我的一个偏好。我决定在必要时同时添加 methods
和 props
。
js/components/Search.vue
<template>
<div>
<slot :methods="{ focus }" />
</div>
</template>
<script>
export default {
methods: {
focus() {
console.log('focus input');
}
}
}
</script>
我正在使用 Laraval 自定义组件,例如,我有:
components/input.blade.php
<input type="text" class="rounded">
注意:这是一个简单的例子,这里关键的部分是我想复用blade模板生成的HTML
现在我可以创建一个带有作用域插槽的 Vue 组件了:
js/components/Search.vue
<template>
<div>
<slot name="search-input" />
</div>
</template>
<script>
export default {
methods: {
focus() {
console.log('focus input');
}
}
}
</script>
// ... and registering the component
// among others
Vue.component('search', require('js/components/Search'));
new Vue({
el: '#vue_app'
});
太棒了,我可以按如下方式使用我的组件:
views/somepage.blade.php
<search>
<template v-slot:search>
<x-input>
</template>
</search>
一切都按预期工作,但是如您所见,我有一个 focus
方法,我希望在关注 blade 输入时触发该方法。
现在我不能这样做了:
js/components/Search.vue
<template>
<div>
<slot name="search-input" @focus="focus" />
</div>
</template>
<script>
export default {
methods: {
focus() {
console.log('focus input');
}
}
}
</script>
但我可以做到:
js/components/Search.vue
<template>
<div>
<div ref="search-container"><slot name="search-input" /></div>
</div>
</template>
<script>
export default {
methods: {
mounted() {
this.$refs['search-container'].querySelector('input').addEventListener('focus', this.focus)
},
focus() {
console.log('focus input');
}
}
}
</script>
但我不确定在 Vue 组件中使用 addEventListener
是最好的方法。
是否有更好的方法来实现我的目标?
不确定具体问题,也许
this.$refs['search-container'].querySelector('input').addEventListener('focus', this.focus)
以某种方式 async (生命周期方面),您可能需要将其包装成 nextTick
this.$nextTick(() => {
this.$refs['search-container'].querySelector('input').addEventListener('focus', this.focus)
})
顺便说一句,IMO 这种添加侦听器的方式没有问题。
此外,也许可以按照此处的建议尝试 @focus.native="focus"
:https://vuejs.org/v2/guide/components-custom-events.html#Binding-Native-Events-to-Components
因为可能是水合作用,元素可能需要一些时间才能作为 Vue 节点可用,因此将其固定在本地焦点可能是解决方案。
不确定这些是否可行,但这是我的两个想法。
我的首选解决方案是利用 scoped slots 及其插槽道具来传递方法。最终解决方案如下所示:
views/somepage.blade.php
<search>
<template v-slot:default>
<x-input @focus="slot.methods.focus">
</template>
</search>
你可以在上面看到我正在引用插槽道具变量 slot
来访问我在下面定义的变量。请注意,我传递了一个 methods
对象。调用对象 methods
只是我的一个偏好。我决定在必要时同时添加 methods
和 props
。
js/components/Search.vue
<template>
<div>
<slot :methods="{ focus }" />
</div>
</template>
<script>
export default {
methods: {
focus() {
console.log('focus input');
}
}
}
</script>