Skip to content

Instantly share code, notes, and snippets.

@taketo1113
Last active March 4, 2020 04:02
Show Gist options
  • Save taketo1113/2147b590e9898bd676385fc54ef0726c to your computer and use it in GitHub Desktop.
Save taketo1113/2147b590e9898bd676385fc54ef0726c to your computer and use it in GitHub Desktop.
vue component per form controls

Design Pattern to create vue component per form controls

Background

Rails MPA + Vue.js

Files

  • Rails View: app/views/views/_form.slim
  • Vue SFC: components/equipment_form/
    • index.js
    • EquipmentFormDeviceId.vue
    • EquipmentFormLoopback4.vue
    • EquipmentFormManagement4.vue
  • Vue Store: store/modules/equipmentForm.js

Problems

  • Create vue component a whole form with Rails MPA
    • couldn't use rails validation / url routing

SFC per form controls

Pros

  • Rails Way
    • From Action URL
    • Validation

Cons

  • Fat store
    • business logic goes in the store
  • Duplicate set value to pros value for form inputs
<template lang="pug">
input.form-control(type="text" name="equipment[deviceid]" v-model="deviceId" @blur="setDeviceId")
</template>
<script>
export default {
props: {
inputDeviceId: String
},
data: function() {
return {
deviceId: ""
};
},
mounted: function() {
// set init value
this.$store.commit("equipmentForm/setDeviceId", this.inputDeviceId);
this.deviceId = this.$store.state.equipmentForm.deviceId;
},
methods: {
setDeviceId: function() {
this.$store.commit("equipmentForm/setDeviceId", this.deviceId);
}
}
};
</script>
<template lang="pug">
input.form-control(type="text" name="equipment[loopback4]" v-model="loopback4")
</template>
<script>
export default {
props: {
inputLoopback4: String
},
computed: {
loopback4: {
get() {
return this.$store.state.equipmentForm.loopback4;
},
set(value) {
this.$store.commit("equipmentForm/setLoopback4", value);
}
}
},
mounted: function() {
// set init value
this.$store.commit("equipmentForm/setLoopback4", this.inputLoopback4);
}
};
</script>
<template lang="pug">
input.form-control(type="text" name="equipment[management4]" v-model="management4")
</template>
<script>
export default {
props: {
inputManagement4: String
},
computed: {
management4: {
get() {
return this.$store.state.equipmentForm.management4;
},
set(value) {
this.$store.commit("equipmentForm/setManagement4", value);
}
}
},
mounted: function() {
// set init value
this.$store.commit("equipmentForm/setManagement4", this.inputManagement4);
}
};
</script>
import EquipmentFormDeviceId from "./EquipmentFormDeviceId.vue";
import EquipmentFormLoopback4 from "./EquipmentFormLoopback4.vue";
import EquipmentFormManagement4 from "./EquipmentFormManagement4.vue";
export {
EquipmentFormDeviceId,
EquipmentFormLoopback4,
EquipmentFormManagement4
};
const namespaced = true;
const state = {
deviceId: "",
loopback4: "",
management4: ""
};
const getters = {
loopback4: state => {
return "45.0.0." + state.deviceId + "/32";
},
management4: state => {
return "172.16.0." + state.deviceId + "/32";
}
};
const mutations = {
setDeviceId(state, deviceId) {
state.deviceId = deviceId;
if (state.loopback4 === "") {
state.loopback4 = getters.loopback4(state);
}
if (state.management4 === "") {
state.management4 = getters.management4(state);
}
},
setLoopback4(state, loopback4) {
state.loopback4 = loopback4;
},
setManagement4(state, management4) {
state.management4 = management4;
}
};
export default {
namespaced,
state,
getters,
mutations
};
= form_for @equipment, html: { class: "form-horizontal", id: "form_equipment" } do |f|
- if @equipment.errors.any?
#error_explanation.bs-callout.bs-callout-danger
h4 = "#{pluralize(@equipment.errors.count, "error")} prohibited this equipment from being saved:"
ul.text-danger
- @equipment.errors.full_messages.each do |message|
li = message
.form-group
.control-label.col-sm-2
= f.label :name
.col-sm-6
= f.text_field :name, class: "form-control"
.form-group
.control-label.col-sm-2
= f.label :deviceid
.col-sm-6
= f.text_field :deviceid, class: "form-control", data: { vue: "EquipmentFormDeviceId", "input-device-id": "#{@equipment.deviceid}" }
.form-group
.control-label.col-sm-2
= f.label :hostname
.col-sm-6
= f.text_field :hostname, class: "form-control", maxlength: 128
.form-group
.control-label.col-sm-2
= f.label :loopback
.col-sm-6
div
span IPv4:
= f.text_field :loopback4, class: "form-control", data: { vue: "EquipmentFormLoopback4", "input-loopback4": "#{@equipment.loopback4}" }
.form-group
.control-label.col-sm-2
= f.label :management
.col-sm-6
div
span IPv4:
= f.text_field :management4, class: "form-control", data: { vue: "EquipmentFormManagement4", "input-management4": "#{@equipment.management4}" }
.form-group
.col-sm-10.col-sm-offset-2
= f.submit class: "btn btn-primary"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment