Using Created and Watcher in VUE.JS - vue.js

I am using watch and created method for the same data.Is it duplicate code? Is there a better way to do it?
props: {
regionList: {
type: Array,
},
},
data() {
return {
regions: [],
};
},
watch: {
regionList() {
if (this.regionList) {
this.regions = this.regionList;
}
},
},
created() {
if (!this.regionList) {
this.getApi();
} else {
this.regions = this.regionList;
}
},

It is what immediate watcher is for:
watch: {
regionList: {
immediate: true,
handler(newVal) {
if (newVal.length) {
this.regions = newVal;
}
}
},
},
created() {
if (!this.regionList) {
this.getApi();
}
},

Related

Add a Class if element is in viewport vuejs nuxt

I want give an element a class when it's in the viewport and I don't know how I can handle it. I watched a few Videos on Youtube but nothing helped me.
I work with a boilerplate so I can't implement additional plugins.
My script looks actually like this.
export default {
head() {
return {
title: this.$t("headData.index.title"),
meta: [
{
hid: "description",
name: "description",
content: this.$t("headData.index.description")
}
]
}
},
data() {
return {
debugSingleScroll: true,
}
},
methods: {
handleScroll() {
if(this.debugSingleScroll) {
this.scrollToNextModule()
this.scrollToLastModule()
this.debugSingleScroll = false;
}
},
scrollToNextModule() {
this.$refs.factsModule.triggerAnimation();
},
scrollToLastModule() {
},
},
mounted () {
window.addEventListener('scroll', this.handleScroll);
},
destroyed () {
window.removeEventListener('scroll', this.handleScroll);
},
}

Get params of route Shopware 6

I try to extend the product detail page and get the productId out of the routes.
Shopware.Module.register('sw-product-content-element', {
routeMiddleware(next, currentRoute) {
if (currentRoute.name === 'sw.product.detail') {
currentRoute.children.push({
name: 'sw.product.detail.content-element',
path: '/sw/product/detail/:id/content-element',
component: 'sw-product-detail-content-element',
meta: {
parentPath: "sw.product.index"
},
props: {
default(route) {
console.log(route)
return {
productId: route.params.id
};
}
}
});
}
next(currentRoute);
}
});
I try to pass my productId as props to my component, but in my component productId is undefined.
Component.register('sw-product-detail-content-element', {
template,
props: {
productId: {
required: true,
type: String
},
},
data() {
return {
product: null
};
},
created() {
console.log(this.productId)
},
....
I found a solution. I do not need to pass my value as props, I can just use this.$route.params.id
Component.register('sw-product-detail-content-element', {
template,
props: {
productId: {
required: true,
type: String
},
},
data() {
return {
product: null
};
},
created() {
this.productId = this.$route.params.id
console.log(this.productId)
},
....

Child element not updating props after change in data coming from apollo in nuxt/vue

UPDATE: the main issue seems to be that the props only get updated once. They should change when this.campaign.name becomes available.
I want to dynamically update the title and breadcrumb data fields and show them on the page. Currently page page shows undefined or null. How can I fix this?
I tried to create a computed value but it only seems to update once (after head and breadcrumb data is already showed). A method does not work since I don't have anything to trigger the method.
What is the correct way to fix this?
I am using nuxt generate to deploy the app.
export default {
components: { PageHeader },
middleware: 'authenticated',
data() {
return {
title: 'Campaigns' + this.campaignName,
breadcrumb: [
{
text: 'Campaigns',
href: '/'
},
{
text: this.campaignName,
href: '/'
}
],
campaign: ''
}
},
apollo: {
campaign: {
prefetch: true,
query: campaignQuery,
variables() {
return { id: this.$route.params.id }
}
}
},
computed: {
campaignName() {
return this.campaign && this.campaign.name
}
},
head() {
return {
title: this.title
}
}
}
</script>
Your computed property campaignName returns undefined cuz this.campaign.name is not defined
campaignName() {
if(this.campaign && this.campaign.name) return "Campaigns" + this.campaign.name;
return "default value";
}
Then you can use it directly in head
head() {
return {
title: this.campaignName
}
}
The solution was putting the data elements directly as a computer property. (so no recalculation)
export default {
components: { PageHeader },
middleware: 'authenticated',
data() {
return {}
},
apollo: {
campaign: {
prefetch: true,
query: campaignQuery,
variables() {
return { id: this.$route.params.id }
}
}
},
computed: {
title() {
return this.campaign && `Campaign: ${this.campaign.name}`
},
breadcrumb() {
return [
{
text: 'Campaign',
href: '/'
},
{
text: this.campaign && this.campaign.name,
href: '/'
}
]
}
},
head() {
return {
title: this.title
}
}
}
</script>

Getter undefined vuex and axios

I’m trying to get a getter in my component but it says an error. This is my code store.js
const store = new Vuex.Store({
state: {
config:{
themes: [],
typographies:[],
},
user: {
typography_id: 1,
theme_id: null
}
},
mutations: {
FETCH_CONFIG(state, config) {
state.config.themes = config.themes;
state.config.typographies = config.typographies;
},
FETCH_USER(state, user) {
state.user.theme_id = user.theme_id;
state.user.typography_id = user.typography_id;
},
},
actions: {
fetchConfig({commit}) {
axios.get('/api/config').then( function( response ){
commit('FETCH_CONFIG', response.data);
});
},
fetchUser({commit}) {
axios.get('/api/user').then( function( response ){
commit('FETCH_USER', response.data.data[0]);
});
},
},
getters: {
themes(state) {
return state.config.themes;
},
typographies(state) {
return state.config.typographies;
},
typography(state) {
if (state.user.theme_id == 1) {
return state.user.typography_id;
} else {
var theme = state.config.themes.filter(function (el) {
return el.id == state.user.theme_id;
});
return theme[0].typography_id;
}
},
user_theme(state) {
return state.user.theme_id;
},
}
});
And in my component in computed I have:
...mapGetters(['typographies', 'typography'])
And ths is the error I get:
I guess I’m doing something wrong but I don’t know what.
Your getter for typography returns the error because first it goes into the else and then tries to return theme[0].typography_id - but there is an empty array.. if you are loading the date, later on, make sure that the getter returns null before data is loaded.. like:
const store = new Vuex.Store({
state: {
config:{
themes: [],
typographies:[],
},
user: {
typography_id: 1,
theme_id: null
}
},
mutations: {
FETCH_CONFIG(state, config) {
state.config.themes = config.themes;
state.config.typographies = config.typographies;
},
FETCH_USER(state, user) {
state.user.theme_id = user.theme_id;
state.user.typography_id = user.typography_id;
},
},
actions: {
fetchConfig({commit}) {
axios.get('/api/config').then( function( response ){
commit('FETCH_CONFIG', response.data);
});
},
fetchUser({commit}) {
axios.get('/api/user').then( function( response ){
commit('FETCH_USER', response.data.data[0]);
});
},
},
getters: {
themes(state) {
return state.config.themes;
},
typographies(state) {
return state.config.typographies;
},
typography(state) {
if (state.user.theme_id == 1) {
return state.user.typography_id;
} else {
var theme = state.config.themes.filter(function (el) {
return el.id == state.user.theme_id;
});
return theme.length > 0 ? theme[0].typography_id: 1;
}
},
user_theme(state) {
return state.user.theme_id;
},
}
});

Vue vuex state watch is not working on first load

I have below code to get new ID using watch. Its working fine. However, I need the function to get the ID on first load as well, which is not working. Is there anything I am missing in my code?
watch: {
id: {
immediate: true,
handler(newV, oldV) {
this.id = newV;
},
},
},
mounted () {
store.watch(store.getters.getId, id => {
this.id = id;
});
},
created() {
this.userID();
},
methods: {
userID () {
console.log('this.id);
}
}
}
You can just do this:
data() {
return {id: null}
}
watch: {
'$store.getters.getId': {
immediate: true,
handler: function(newV) {
this.id = newV
},
},
}
Using a computed property is better, as your component does not 'own the id'.
computed: {
id() {
return this.$store.getters.getId
},
},