将 Laravel Blade 模板与 Vue JS 和事件监听器一起使用
Posted
技术标签:
【中文标题】将 Laravel Blade 模板与 Vue JS 和事件监听器一起使用【英文标题】:Using Laravel Blade templates with Vue JS and event listeners 【发布时间】:2021-07-22 22:38:51 【问题描述】:我正在使用Laraval自定义组件,例如我有:
components/input.blade.php
<input type="text" class="rounded">
注意:这是一个简单的例子,这里的关键部分是我想重用刀片模板生成的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
方法,我希望在关注刀片输入时触发该方法。
现在我不能这样做了:
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
是不是最好的方法。
有没有更好的方法来实现我想要做的事情?
【问题讨论】:
所以在第二部分中,您将安装它并直接访问实际上是组件一部分的输入字段,这就是它起作用的原因。那么,您是否试图将注意力集中在页面呈现本身上? @Adi,它按预期工作,但是,我只是质疑这是否是最佳实践。对我来说,这感觉像是一种解决方法。通常我会通过<a @click="doSomething()">
绑定一个点击监听器,如果有一个类似的方法来绑定到一个插槽中包含的元素会很好。
如果您不希望函数在初始渲染时运行,请优先使用<a @click="doSomething">
。
【参考方案1】:
不确定到底是什么问题,也许
this.$refs['search-container'].querySelector('input').addEventListener('focus', this.focus)
以某种方式异步(生命周期方面),您可能需要将其包装成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 节点,因此将其作为原生焦点可能是解决方案。
不确定这些是否可行,但这是我的两个想法。
【讨论】:
感谢您的回复。我猜大家的共识是,以这种方式添加事件监听器是可以的。我的示例中的代码按预期工作。我只是质疑添加事件监听器的风格。我确信这一定是想要在 Vue 模板中使用样式化 Blade 组件并将事件绑定到它们时遇到的常见问题 如上所述,对我来说看起来不错。 :D 不确定我是否在正确的轨道上,但您不能使用属性包将您的事件处理程序@click 传递给刀片组件吗? @futureweb 我想这是正确的,但我不知道组件是否有正确的上下文来触发正确的方法。【参考方案2】:我首选的解决方案是利用scoped slots 及其插槽道具来传递方法。最终解决方案如下所示:
views/somepage.blade.php
<search>
<template v-slot:default>
<x-input @focus="slot.methods.focus">
</template>
</search>
你可以在上面看到我引用了 slot props 变量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>
【讨论】:
以上是关于将 Laravel Blade 模板与 Vue JS 和事件监听器一起使用的主要内容,如果未能解决你的问题,请参考以下文章
使用 Blade/Mustache 模板混合 Laravel 和 Vue.Js
带有 Vue js 组件和 Googlebot 的 Laravel Blade 模板