How to fix 'didn't work redirect by Turbolinks' in Ruby on Rails with Vue.js

邮差的信 提交于 2020-01-25 10:49:26

问题


In my sign in page, didn't work redirect by Turbolinks.
This page use form for sign in. After posting form correct information, browser end up going to original page.

I'm implementing sign in page with Ruby on Rails and Vue.js.
In loading, I use Turbolinks, so I did Vue.js plugin vue-turbolinks, too.

Rails: 5.2.2
Ruby: 2.5.1
Turbolinks: 5
vue-turbolinks: 2.0.4
webpacker: 3.5

user_controller.rb

# coding: utf-8
class UsersController < ApplicationController

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      flash[:success] = "registing user data"
      redirect_to '/'
    else
      flash[:danger] = "invalid info"
      redirect_to '/signup'
    end
  end

  private
    def user_params
      params.require(:user).permit(:user_name, :email, :password, :password_confirmation)
    end

new.html.erb

<h1>Add</h1>
</div>
<%= javascript_pack_tag 'new' %>
<div>

new.vue

<template>
  <form accept-charset="UTF-8">
    <input type="text" v-model="username" placeholder="username">
    <input type="text" v-model="email" placeholder="email">
    <input type="password" v-model="password" placeholder="password">
    <input type="password" v-model="password_confirm" placeholder="password(confirm)">
    <button type="submit" v-on:click="sendForm">send</button>
  </form>
</template>

<script>
import axios from 'axios';

const token = document.getElementsByName("csrf-token")[0].getAttribute("content");
axios.defaults.headers.common["X-CSRF-Token"] = token;
axios.defaults.headers.common["Content-Type"] = "application/json";
axios.defaults.headers.common["charset"] = "utf-8";
axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";

export default {
  data: function() {
    return {
      username: "",
      email: "",
      password: "",
      password_confirm: ""
    }
  },
  methods: {
    sendForm: function(e){
      axios.post("/signup", {
        "user": {
          "user_name": this.username,
          "email": this.email,
          "password": this.password,
          "password_confirmation": this.password_confirm,
        }
      })
      .then(response => { 
      })
      .catch(response => {
      });
    }
  }
}
</script>

new.js

import Vue from 'vue';
import New from '../new.vue';
import TurbolinksAdapter from 'vue-turbolinks';

Vue.use(TurbolinksAdapter);

document.addEventListener('turbolinks:load', () => {
    const el = document.body.appendChild(document.createElement('new'));
    const new_ = new Vue({
        el,
        render: h => h(New)
    });

    console.log('/new page');
});

I expect the after loading, browser go to root page in correct registing.


回答1:


/vueturbo.js

 if (typeof(Vueturbo) === 'undefined') {
       Vueturbo = {};
    }

    Vueturbo.Dispatcher = function() {
       this.dispatch = function() {
          var elements = $('.sjs');
          var cls, meth;

          $(elements).each(function (index, element) {
             tokens  = $(element).attr('data-cls').split('.');
             meth    = $(element).attr('data-method') || 'fire';
             context = window;

             $(tokens).each(function(tidx, token) {
                context = context[token];
             });

             cls = new (context)();
             cls[meth]();
          });
       };

       this.turbolinks = function() {
          var ref = this;
          document.addEventListener('turbolinks:load', function() {
            ref.dispatch();
          });
       };
    };

insert the tag and dispatcher callings in templates ../views/layouts/public.html.erb

<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<script charset="utf-8">(new Vueturbo.Dispatcher()).turbolinks();</script>
...
<%= yield %>
...

insert the tag calling the js that you want ../views/public/new.html.erb

<%= hidden_field_tag nil, 'new', class: 'sjs', 'data-cls': 'Vueturbo.new' %>

/new.js

import Vue from 'vue';
import New from '../new.vue';
import TurbolinksAdapter from 'vue-turbolinks';

Vue.use(TurbolinksAdapter);

Vueturbo.new = function() {
  this.fire = function() {
    const el = document.body.appendChild(document.createElement('new'));
    const new_ = new Vue({
        el,
        render: h => h(New)
    });
  }
}


来源:https://stackoverflow.com/questions/54178315/how-to-fix-didnt-work-redirect-by-turbolinks-in-ruby-on-rails-with-vue-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!