Passing static props and dynamic params to Vue route with multiple components - vue.js

I have a Vue route I've set up to show courses in a degree program at a school.
{
path: '/courses-by-degree/:degree',
components: {
sidebar: Sidebar,
content: Grid
},
props: {
sidebar: {
title: "Fulfills",
type: "all",
degree: "",
keyword: ''
},
content: {
type: "degree",
degree: "English",
keyword: "",
columns: {
"Title": "title",
"Term": "term_description",
"Day, Time": "",
"Format": "format",
"Capacity": "availability"
}
}
}
}
You can access this via a URL or via a Vue multiselect:
<multiselect
v-model="degree"
placeholder="Select a field..."
:options="degrees"
#select="searchDegrees">
</multiselect>
When you select an option in the multiselect, this is called:
searchDegrees(selectedOption, id) {
this.$root.$router.push({ path: `/courses-by-degree/${selectedOption}` });
},
My question is, how can I pass the selected option in the path to the props in the route, instead of hardcoding it to "English" as I've done above? Is this even possible/a good way to do this?

You are correct, you need to use the function to return the props. In the case of multiple named components, you can do that like this:
{
path: '/courses-by-degree/:degree',
components: {
sidebar: Sidebar,
content: Grid
},
props: {
sidebar: {
title: "Fulfills",
type: "all",
degree: "",
keyword: ""
},
content: route => {
return {
type: "degree",
degree: route.params.degree,
keyword: "",
columns: {
Title: "title",
Term: "term_description",
"Day, Time": "",
Format: "format",
Capacity: "availability"
}
}
}
}

Related

How to use Vue Component on custom formatter in Vue 3

newbie in vuejs.
I'm trying to use tabulator data-table for data and used Custom Formatters. But unable to return Vue component.
How to return Vue component on custom formatter Vue3?
<script>
import BaseLink from "#/components/BaseLink.vue";
export default {
data() {
return {
switch1: false,
columns: [
{
rowHandle: true,
formatter: "handle",
headerSort: false,
frozen: true,
width: 30,
minWidth: 30,
},
{ title: "ID", field: "id", editor: "input" },
{ title: "Name", field: "name" },
{ title: "Email", field: "email" },
{
title: "Status",
field: "status",
formatter: function (cell, formatterParams, onRendered) {
//cell - the cell component
//formatterParams - parameters set for the column
//onRendered - function to call when the formatter has been rendered
return `<v-switch v-model="switch1" />`;
},
},
{
title: "Action",
field: "id",
formatter: function (cell, formatterParams, onRendered) {
//cell - the cell component
//formatterParams - parameters set for the column
//onRendered - function to call when the formatter has been rendered
return `<BaseLink to="/members/${cell.getValue()}/details">Details</BaseLink>`;
},
},
],
};
},
};
</script>
Thank in advance!

how to pass i18n data $t as prop to a component

in a normal way with out translation but i want to translate the two object array and bind into a component
<InfoNews
v-for="infonew in infonews"
:id="infonew.id"
:title="infonew.title"
:content="infonew.content"
/>
data() {
return {
infonews: [
{
id: "01",
title: "what we do",
content:"industke aecimen book. ",
},
{
id: "02",
title: "our mission",
content:"ggdddg",
},
],
};
Make infonews a computed property. The title and content of each should be the translation keys.
export default {
computed: {
infonews() {
return [
{
id: "01",
title: this.$t("what we do"),
content: this.$t("industke aecimen book"),
},
{
id: "02",
title: this.$t("our mission"),
content: this.$t("ggdddg"),
},
]
};
}
}

How to track changes in a property stored in Vuex(store) and perform some method based on the value?

I'm trying to change the links based on the variable user_role which is stored in Vuex(store). I'm not able to find an appropriate way to track the change and based on its value I want to perform some method. Any suggestions on how to do it?
------------------------------store.js-------------------------------
export default new Vuex.Store({
state: {
user_role: "User"
},
mutations: {},
actions: {},
modules: {}
});
-----------------------------------component.vue---------------------------
export default {
name: "Navbar",
data() {
return {
links: [
{ text: "Projects", route: "/projects" },
{ text: "Requests", route: "/requests" },
{ text: "", route: "" },
{ text: "Resources", route: "/resources" }
],
pers_actions: ["Profile", "LogOut"],
};
},
watch: {
user_role: {
if (user_role === "PM") {
this.links[2] = {
text: "Allocations",
route: "/allocations"
};
} else if (user_role === "PMO") {
this.links[2] = {
text: "Reports",
route: "/reports"
};
} else if (user_role === "User") {
this.links = [
{
text: "Allocations",
route: "/allocations"
}
];
}
}
},
Rather than explicitly mutating your local data in response to some state change, it is better to compute your links within a computed property because it will automatically update whenever some dependent data has changed. It'll "just work".
computed: {
links() {
switch (this.$store.state.user_role) {
case: "PM": return [
{ text: "Projects", route: "/projects" },
{ text: "Requests", route: "/requests" },
{ text: "Allocations", route: "/allocations" },
{ text: "Resources", route: "/resources" },
];
case: "PMO": return [
{ text: "Projects", route: "/projects" },
{ text: "Requests", route: "/requests" },
{ text: "Reports", route: "/reports" },
{ text: "Resources", route: "/resources" },
];
// For any other role
default: return [
{ text: "Allocations", route: "/allocations" },
];
}
}
}

How to implement Groupping in Nativescript Vue RadDataForm?

Want to use Fields grouping Documention is not prvided event the topic of grouping nor the example. Most of the example are using typescript. Event the Google is not showing the result.
<RadDataForm
ref="dataform"
:source="customerForm"
:metadata="customerFormMetadata"
:groups="groups"
/>
customerFormMetadata: {
isReadOnly: false,
commitMode: "Immediate",
validationMode: "Immediate",
propertyAnnotations: [
{
name: "customer_name_1",
displayName: "Customer Name",
index: 0,
groupName: "Personal",
editor: "Text"
},
groups: [
Object.assign(new PropertyGroup(), {
name: "Personal",
collapsible: true,
collapsed: false
}),
Object.assign(new PropertyGroup(), {
name: "Address",
collapsible: true,
collapsed: true
})
],
Grouping doesn't require any addtional configuration while using with Vue, it's pretty straight forward as described in the core docs.
Example
<template>
<Page class="page">
<ActionBar title="Home" class="action-bar" />
<RadDataForm :source="person" :metadata="groupMetaData" />
</Page>
</template>
<script>
import Vue from "nativescript-vue";
import RadDataForm from "nativescript-ui-dataform/vue";
Vue.use(RadDataForm);
export default {
data() {
return {
person: {
name: "John",
age: 23,
email: "john#company.com",
city: "New York",
street: "5th Avenue",
streetNumber: 11
},
groupMetaData: {
propertyAnnotations: [{
name: "city",
index: 3,
groupName: "Address",
editor: "Picker",
valuesProvider: [
"New York",
"Washington",
"Los Angeles"
]
},
{
name: "street",
index: 4,
groupName: "Address"
},
{
name: "streetNumber",
index: 5,
editor: "Number",
groupName: "Address"
},
{
name: "age",
index: 1,
editor: "Number",
groupName: "Main Info"
},
{
name: "email",
index: 2,
editor: "Email",
groupName: "Main Info"
},
{
name: "name",
index: 0,
groupName: "Main Info"
}
]
}
};
}
};
</script>
Edit:
As discussed in the docs, to make the Group collapsible use the groupUpdate event.
onGroupUpdate: function(args) {
let nativeGroup = args.group;
if (args.ios) {
nativeGroup.collapsible = true;
} else {
nativeGroup.setExpandable(true);
}
}
Updated Playground

how to dynamically load a vue-form-generator schema?

I need to dynamically load (part of) a form schema asynchronously.
For example, I want to create the schema after a REST call.
I started using vue-form-generator,
I tried to manipulate the schema creating a component that:
creates a text input with a label Name-TEST-failed
asynchronously call a function that changes the label in Name-TEST-success
Code:
<template>
<div class="panel-body">
<vue-form-generator :schema="schema" :model="model" :options="formOptions"></vue-form-generator>
</div>
</template>
<script>
import Vue from 'vue';
import VueFormGenerator from "vue-form-generator";
Vue.use(VueFormGenerator);
export default {
created(){
setTimeout(() => {
console.log("start!");
Vue.set(this.$data.schema.fields,
[{
type: "input",
inputType: "text",
label: "Name-TEST-success",
model: "name",
placeholder: "Your name",
featured: true,
required: true
}]
)
console.log("end!");
}, 1000);
},
data() {
return {
model: {
name: "John Doe"
},
schema: {
fields: [{
type: "input",
inputType: "text",
label: "Name-TEST-failed",
model: "name",
placeholder: "Your name",
featured: true,
required: true
}]
},
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
}
}
}
</script>
both the messages start! and end! appear in the console, but the label of the input test does not change.
How can I change the schema (and the model) dynamically?
Just put the schema in a computed property and make it dependant on a data property. So the schema will change everytime you change a property on which it depends.
export default {
created(){
setTimeout(() => {
console.log("start!");
this.labelName = "Name-TEST-success"
}, 1000);
},
data() {
return {
model: {
name: "John Doe"
},
// Add a new property that you can change as you wish
labelName: 'Name-TEST-failed",
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
}
},
computed: {
schema () {
var result = {
fields: [{
type: "input",
inputType: "text",
label: this.labelName,
model: "name",
placeholder: "Your name",
featured: true,
required: true
}]
}
return result
}
}
}
UPDATE:
You don't need computed properties, they can lead to problems with validity check. Just manipulate the properties direclty.
PS: The $set method needs an index to work correct on arrays.
export default {
created(){
setTimeout(() => {
console.log("start!");
this.fieldObject.label = "Name-TEST-success"
}, 1000);
},
data() {
var fieldObject = {
type: "input",
inputType: "text",
label: this.labelName,
model: "name",
placeholder: "Your name",
featured: true,
required: true
}
return {
fieldObject, // now you can change label with "fieldObject.label = ..."
model: {
name: "John Doe"
},
schema: {
fields: [fieldObject]
},
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
}
}
}
}