I didn't know the flow of Rails and Vue until now. After playing around with it, I finally understood the flow, so I will write a memo so that I can look back. Since it is a beginner, it is very likely that the understanding is wrong, so it is for reference only! It is not a general correct answer, but my understanding and convincing answer.
MacOS Mojave Ruby 2.6.4 Rails 6.0.3.3 Vue 2.6.12 Webpack 4.44.2 yarn 1.22.5 Docker 2.3.0.5 VScode Vuetify Vue-router Vue-Store
In this article, we will use the following URL: http://localhost:3000/ http://localhost:3000/user
First, enter the URL from your web browser. http://localhost:3000/
routes.rb
Rails.application.routes.draw do
root to: 'home#index'
get "/user", to: 'home#index'
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
The browser sends the URL to the Rails server. http://localhost:3000/のURLを指定しているため The destination of "root to:'home # index'" in routes.rb is Will be referenced.
The home controller index function is called.
home_controller.rb
class HomeController < ApplicationController
def index
end
end
By the way, I don't know if it's correct, but routes.rb and the referenced controller It is a recognition that an instance is created every time. That's why there is no relationship between routes or controllers.
Returning to the main subject, the index function is called. Since there is nothing this time, the Veiw file that matches the index is referenced, but Create an instance of the model like @ home = Home.all in the index function If there was a program, a model instance would be created and If necessary, the model gets the information from the database and stores it in the @home instance There should be a step, but I won't use it this time. Remember as a flow.
The index function of the controller references the corresponding file. Browse to veiw / home / index.html.erb.
The following settings have been entered here, This means referencing the hello.vue file in app / javascript / pack.
rb:index.html.erb
<%= javascript_pack_tag 'hello_vue' %>
<%= stylesheet_pack_tag 'hello_vue' %>
It's the core file for using Vue applications. Each file with the extension Vue is grouped into this file as an object The images to be combined.
render: h => h(App)
As you can see in the app.vue template By calling, the contents of app.vue will be displayed.
This file enables you to use each function of Vue. The contents of Pronto are not written in this file itself. It is a file that seems to be managed behind the scenes.
vuetify,
router,
store,
Is defined so that it can be used in Vue.
The parent component file is App. It is router that realizes SPA Vuex stores the data The UI framework is vuetify.
hello_vue.js
import Vue from 'vue';
import App from '../src/components/app/app';
import Vuetify from 'vuetify';
import router from '../src/router';
import store from "../src/vuex/index"
import 'vuetify/dist/vuetify.min.css';
Vue.use(Vuetify);
const vuetify = new Vuetify();
document.addEventListener('DOMContentLoaded', () => {
const app = new Vue({
vuetify,
router,
store,
render: h => h(App)
}).$mount()
document.body.appendChild(app.$el)
console.log(app)
})
The next thing to look at is the App file.
It ’s very simple, but This file is the parent component and this file is displayed in the browser. However
<router-view></router-view>
By being there Since the route function is provided by hello_vue, the route waits.
app.vue
<template>
<div>
<router-view></router-view>
</div>
</template>
If you have the route function, the specified component will be returned according to the URL information.
router.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from "../src/components/home/Home"
import User from "../src/components/user/User"
Vue.use(VueRouter);
export default new VueRouter({
mode: 'history',
routes: [{
path: '/',
component: Home
}, {
path: '/user',
component: User
}]
});
In your browser http: // localhost: 3000 / Because I hit
{
path: '/',
component: Home
}
Decided to return the Home component. At the beginning routes.rb
root to: 'home#index'
Since it is linked with the route information of, you can also get the URL information with vue.
Since I decided the component to be displayed from the URL information in the root of Vue Let's take a look at the target component here, Home.vue.
Home.vue
<template>
<div>
<p>Home</p>
<p>{{ store}}</p>
</div>
</template>
<script>
export default {
computed: {
store(){
return this.$store.state.store
}
}
}
</script>
The template is the part that is actually displayed on the browser, and the script is the js processing part. In the template
<p>{{ store }}</p>
I want to display, so I will look inside the script process.
computed: {
store(){
return this.$store.state.store
}
}
It says, but this is the file that defines Vuex Since it says to bring the data of state.store, let's look at the file that defines vuex.
index.js
import Vuex from 'vuex';
import Vue from 'vue';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
store: "Store"
}
});
I'm sorry that the file name is difficult to understand, but it is a file that defines vuex.
store:"Store"
Since "Store" is defined by store, you can call "Store" by writing store from any component.
Go back to Home.vue again.
<p>{{ store }}</p>
I want to display, so I will look inside the script process.
computed: {
store(){
return this.$store.state.store
}
}
The flow is to bring "Store" with vuex with script, put it in
{{store}} </ p> and display it.
I think that the URL component (Home) has been decided by Route.
Assign it to
app.vue
<template>
<div>
<router-view></router-view>
</div>
</template>
Under
<router-view></router-view>
But
Home.vue
<template>
<div>
<p>Home</p>
<p>{{ store}}</p>
</div>
</template>
<script>
export default {
computed: {
store(){
return this.$store.state.store
}
}
}
</script>
Is assigned to.
You will be returned to the original management file. All app.vue files will be objects and will be passed to hello_vue.js.
hello_vue.js
import Vue from 'vue';
import App from '../src/components/app/app';
import Vuetify from 'vuetify';
import router from '../src/router';
import store from "../src/vuex/index"
import 'vuetify/dist/vuetify.min.css';
Vue.use(Vuetify);
const vuetify = new Vuetify();
document.addEventListener('DOMContentLoaded', () => {
const app = new Vue({
vuetify,
router,
store,
render: h => h(App)
}).$mount()
document.body.appendChild(app.$el)
console.log(app)
})
By the following render function
render: h => h(App)
All Vue files are returned as objects.
Finally, I'm back on the Rails side. All Vue files will be combined into index.html.erb.
rb:index.html.erb
<%= javascript_pack_tag 'hello_vue' %>
<%= stylesheet_pack_tag 'hello_vue' %>
It's a bit vague, but at the end the controller returns the Veiw files together to the browser.
Type http: // localhost: 3000 / in your browser The Home and Store listed in Home.vue have been returned.
Try another URL. http://localhost:3000/user Type in the above URL in your browser.
get "/user", to: 'home#index'
Is used. The controller is the same, and the erb is also the same, so I will omit it.
routes.rb
Rails.application.routes.draw do
root to: 'home#index'
get "/user", to: 'home#index'
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
router.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from "../src/components/home/Home"
import User from "../src/components/user/User"
Vue.use(VueRouter);
export default new VueRouter({
mode: 'history',
routes: [{
path: '/',
component: Home
}, {
path: '/user',
component: User
}]
});
The following URL and components are used in router.js on the vue side. This time it's the User component.
{
path: '/user',
component: User
}
The User component is as simple as: After that, route will combine with app.vue and display it with hello_vue in the same way. The rest is the same procedure.
User.vue
<template>
<div>
<p>User</p>
</div>
</template>
User is displayed.
By the way, why doesn't it become SPA even though I use router? I wonder if I went to access the server twice with (/ and / user). This is because you are typing the URL directly into your browser.
If you program Home.vue or User.vue to connect to each component You can realize SPA.
Recommended Posts