Я только начал изучать VUE и как использовать его в проекте rails. В моем случае я пытаюсь создать встроенный javascript, который магазины могут внедрить на своем веб-сайте, чтобы их покупатели могли искать доступные для него товары.
Цель состоит в том, чтобы встроенный javascript показывает форму с 2 датами arrival
и departure
. После отправки формы посетитель веб-сайта магазина должен быть перенаправлен в мое приложение, которое затем показывает доступные элементы, принадлежащие магазину, из которого пришел пользователь.
Вопрос Я могу задать он работает с действием с фиксированным идентификатором (see also the commented out code below
), но я не знаю, как динамически добавить ссылку (например, найти идентификатор магазина, принадлежащий ссылочной ссылке, который должен соответствовать booking_url
, и перенаправить на ../park_availability page
моего приложения).
Попытка 1 + сообщения об ошибках:
общая идея: Я попытался создать submit method
в форме файла javascript/app.vue
, который следовательно, следует загрузить функцию searchAccommodations
в javascript/store.js
при отправке.
сообщения об ошибках
vue.esm.js:628 [Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'dispatch' of undefined"
found in
---> <App> at app/javascript/app.vue
<Root>
warn @ vue.esm.js:628
logError @ vue.esm.js:1893
globalHandleError @ vue.esm.js:1888
handleError @ vue.esm.js:1848
invokeWithErrorHandling @ vue.esm.js:1871
invoker @ vue.esm.js:2188
original._wrapper @ vue.esm.js:7565
TypeError: Cannot read property 'dispatch' of undefined
at VueComponent.submit (app.vue:36)
at submit (app.vue?0d7f:13)
at invokeWithErrorHandling (vue.esm.js:1863)
at HTMLFormElement.invoker (vue.esm.js:2188)
at HTMLFormElement.original._wrapper (vue.esm.js:7565)
logError @ vue.esm.js:1897
globalHandleError @ vue.esm.js:1888
handleError @ vue.esm.js:1848
invokeWithErrorHandling @ vue.esm.js:1871
invoker @ vue.esm.js:2188
original._wrapper @ vue.esm.js:7565
javascript / app. vue (форма магазина должна вставить)
<template>
<!-- For reference Working link commented out below -->
<!-- <form id="myapp-reservation-form" action="https://www.myapp.eu/parks/18/park_availability" ref="form" method="get"> -->
<form @submit.prevent="submit" id="myapp-reservation-form" ref="form">
<div class="myapp-reservation-form-item">
<h6>Arrival</h6>
<input type="date" id="arrival" name="arrival" class="form-control"/>
</div>
<div class="myapp-reservation-form-item">
<h6>Departure</h6>
<input type="date" id="departure" name="departure" class="form-control" />
</div>
<div class="myapp-reservation-form-item">
<h6></h6>
<button class="btn search-accommodations-button">Search</button>
</div>
</form>
</template>
<script>
export default {
data: function () {
return {
}
},
methods:{
submit(){
let formData = new FormData(this.$refs.form)
this.Redirect(`https://www.myapp.eu/parks/${encodeURIComponent(booking_url)}/park_availability/`);
console.log(this)
console.log(this.state.$store)
this.$store.dispatch("searchAccommodations", formData)
}
}
}
</script>
<style scoped>
p {
font-size: 2em;
text-align: center;
}
</style>
console.log (this)
VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
$attrs: (...)
$listeners: (...)
$data: (...)
$props: (...)
$isServer: (...)
$ssrContext: (...)
_uid: 1
_isVue: true
$options: {parent: Vue, _parentVnode: VNode, propsData: undefined, _parentListeners: undefined, _renderChildren: undefined, …}
_renderProxy: Proxy {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
_self: VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
$parent: Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
$root: Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
$children: []
$refs: {form: form#myapp-reservation-form}
_watcher: Watcher {vm: VueComponent, deep: false, user: false, lazy: false, sync: false, …}
_inactive: null
_directInactive: false
_isMounted: true
_isDestroyed: false
_isBeingDestroyed: false
_events: {}
_hasHookEvent: false
_vnode: VNode {tag: "form", data: {…}, children: Array(5), text: undefined, elm: form#myapp-reservation-form, …}
_staticTrees: (3) [VNode, VNode, VNode]
$vnode: VNode {tag: "vue-component-1", data: {…}, children: undefined, text: undefined, elm: form#myapp-reservation-form, …}
$slots: {}
$scopedSlots: {$stable: true, $key: undefined, $hasNormal: false}
_c: ƒ (a, b, c, d)
$createElement: ƒ (a, b, c, d)
_watchers: [Watcher]
submit: ƒ ()
_data: {__ob__: Observer}
$el: form#myapp-reservation-form
get $attrs: ƒ reactiveGetter()
set $attrs: ƒ reactiveSetter(newVal)
get $listeners: ƒ reactiveGetter()
set $listeners: ƒ reactiveSetter(newVal)
__proto__: Vue
javascript / packs / embed. js (используется для загрузки начальной формы, показанной в приложении. vue)
import TurbolinksAdapter from 'vue-turbolinks'
import Vue from 'vue/dist/vue.esm'
import App from '../app.vue'
import store from '../store'
const event = (typeof Turbolinks == "object" && Turbolinks.supported) ? "turbolinks:load" : 'DOMContentLoaded';
document.addEventListener(event, () => {
const el = document.querySelector('#myapp-reservation-form')
store.dispatch('loadComments')
const app = new Vue({
el,
store,
render: h => h(App)
})
})
javascript / store. js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
accommodation_categories:[]
},
mutations: {
load(state, accommodation_categories){
state.accommodation_categories = accommodation_categories
},
},
actions: {
async loadComments({ commit }){
let booking_url = window.location.href
fetch(`https://www.myapp.eu/api/v1/parks/${encodeURIComponent(booking_url)}/form_availability/`,{
headers: {accept: 'application/json'}
})
.then(response => response.json())
.then(data => commit('load', data))
},
async searchAccommodations({commit}, formData){
let booking_url = window.location.href
fetch(`https://www.myapp.eu/parks/${encodeURIComponent(booking_url)}/park_availability/`,{
headers: {accept: 'application/json'},
method: "get",
body: formData,
})
.then(response => response.json())
.then(data => commit('load', data))
}
}
})
window.store = store
export default store
Попытка 2 + сообщения об ошибках: Следуя подсказке @ellisdod, я попытался переместить исходный store.dispatch ('loadComments ') в созданный хук моего компонента.
сообщение об ошибке
vue.esm.js:628 [Vue warn]: Error in v-on handler: "TypeError: this.Redirect is not a function"
found in
---> <App> at app/javascript/app.vue
<Root>
warn @ vue.esm.js:628
logError @ vue.esm.js:1893
globalHandleError @ vue.esm.js:1888
handleError @ vue.esm.js:1848
invokeWithErrorHandling @ vue.esm.js:1871
invoker @ vue.esm.js:2188
original._wrapper @ vue.esm.js:7565
vue.esm.js:1897 TypeError: this.Redirect is not a function
at VueComponent.submit (app.vue:32)
at submit (app.vue?0d7f:13)
at invokeWithErrorHandling (vue.esm.js:1863)
at HTMLFormElement.invoker (vue.esm.js:2188)
at HTMLFormElement.original._wrapper (vue.esm.js:7565)
javascript / app. vue (изменение скрипта)
export default {
data: function () {
return {}
},
methods:{
submit(){
let formData = new FormData(this.$refs.form)
this.Redirect(`https://www.myapp.eu/parks/${encodeURIComponent(booking_url)}/park_availability/`);
console.log(this)
console.log(this.$store.state)
this.$store.dispatch("searchAccommodations", formData)
}
},
created () {
this.$store.dispatch('loadComments')
}
}