如何使用 Laravel + VueJS 动态更改表单操作

How to change form action dynamically with Laravel + VueJS

我有这样的路线设置:

Route::post('subjects/{subject}/{tag}', 'TagController@show');

我有以下表单结构,我通过遍历 $tags 数组填充 select 元素的 options

<form id="tagForm" method="POST"
action="/subjects/{{ $lesson->subject->slug }}/{{ 'selected option will go here' }}">
    {{ csrf_field() }}
   <div class="select">
      <select @change="onTagSelected">
        <option>Tags</option>
        @foreach ($tags as $tag)
                <option value="{{ $tag->id }}">{{ $tag->title }}</option>
        @endforeach
      </select>
    </div>
</form>

如何根据选项中当前选择的标签更改表单操作?

我正在使用 Vue.js 作为 js 框架,我正在监听 onchange 事件:

onTagSelected: function(event) {
        var tagForm = document.getElementById('tagForm');
// what should I do here to change the action?
        tagForm.submit();
}

我必须将 select 标签绑定到 v-model 属性:

<form id="tagForm" method="POST" action="/subjects/{{ $lesson->subject->slug }}/">
    {{ csrf_field() }}
   <div class="select">
      <select @change="onTagSelected" v-model="selectedTag">
        <option>Tags</option>
        @foreach ($tags as $tag)
            <option value="{{ $tag->id }}">{{ $tag->title }}</option>
        @endforeach
      </select>
    </div>
</form>

在我的事件侦听器中,我将 属性 附加到操作然后提交:

onTagSelected: function(event) {
        var tagForm = document.getElementById('tagForm');
        tagForm.action += this.selectedTag;
        // console.log(tagForm.action);
        tagForm.submit();
}

虽然这解决了我的问题,但我对此并不满意。我认为有更好的方法可以做到这一点。请随时分享针对此类情况的最佳解决方案。

按照您解决问题的方式,您并没有真正使用 VueJS,而扁平 javascript 会更有意义。更多的 VueJS 方法是这样的:(假设你在 Blade 视图中编写,这需要在 )

new Vue({
   data: function() {
      return {
         form: {
             baseAction: "/subjects/{{ $lesson->subject->slug }}/",
             chosenAction: '',
         }
      }
   },
   computed: {
       computedAction: function() {
           return this.form.baseAction + this.form.chosenAction;
       }
   }
});

现在填写您的表格:

<form action="computedAction">

还有你的select:

<select v-model="form.chosenAction">

此处不需要 onchange,因为我们将 selected 的值绑定到 form objectchosenAction 属性。然后我们使用 computedAction 属性(当然,这是一个计算值)来指示我们表单的操作。

编辑 - 当对单个文件组件使用转译的 vuejs 方法时:

如果想让vuejs负责表单的life-cycle,那么可以使用单文件组件:

<template>
    <form id="tagForm" method="POST" action="computedAction">
        <input type="hidden" name="_token" value="token"/>
        <div class="select">
            <select v-model="form.chosenAction">
                <option value="">Tags</option>
                <option v-for="tag in tags" value="tag.id"> {{tag.title}} </option>
            </select>
        </div>
     </form>
</template>

<script>
    export default {
        props: ['tags', 'slug', 'token']
        data: function() {
            return {
               form: {
                   chosenAction: ''
               }
            }
       },

       computed: {
           computedAction: function() {
               return `/subjects/${slug}/${this.form.chosenAction}`
           }
       }
    }
</script>

现在,在您的 app.js 文件中,您需要将这个新组件告知 Vue,以便您可以在 blade 模板中使用它。这需要在您在 app.js 文件中使用 import Vue from 'vue' 之后出现。

import MyCoolForm from './path/to/my/cool/form.js';

Vue.component('v-mycoolform', MyCoolForm);

现在在您的 blade 模板中,您可以将属性传递给此组件:

<v-mycoolform :slug="{{$lesson->subject->slug}}" :token="{{csrf_token()}}" :tags="{{json_encode($tags)}}"/>