I have this script in the component
<script>
export default {
name: "Auth",
data() {
return {
page: 0,
};
},
methods: {
},
mounted() {
this.page = 3; //works
},
directives: {
swipe: {
loaded: {
function(el, binding) {
alert(this.page == data.binding.page); //doesen't work
},
},
},
},
};
</script>
But in the chrome i have an error
TypeError: Cannot read property 'page' of undefined
So why this is undefined?
The directive hook can access the component through the vnode argument:
export default {
directives: {
swipe: {
inserted(el, binding, vnode) {
console.log(vnode.context.page)
}
}
}
}
Related
I have a state with single module:
const charactersModule = {
state: () => ({
characters: [],
isLoading: false,
totalPages: 0,
currentPage: 1,
itemsPerPage: ITEMS_PER_PAGE,
}),
getters: {},
mutations: {},
actions: {
async getCharacters({state}, page = state.currentPage) {
try {
state.isLoading = true;
const res = await fetch(`${BASE_URL}character/?page=${page}`);
if (res.ok) {
const { info, results } = await res.json();
state.characters = results;
}
} catch (e) {
console.log(e);
} finally {
state.isLoading = false;
}
},
},
};
export default createStore({
modules: {
characters: charactersModule,
},
});
Then in SFC:
// some component
...
methods: {
...mapActions(['getCharacters']),
}
computed: {
...mapState(['characters'])
},
mounted() {
this.getCharacters()
},
I expect that inside this SFC I can access computed properties: characters, isLoading, totalPapges, currentPage and itemsPerPage. What I actually get from ...mapState(['characters']) is an object with all this props, but I need to get them as single computed props (not as part of an object). How can I do this?
Try to use createNamespacedHelpers help to get your state with prefixing them by the module name:
import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('characters')
...
methods: {
...mapActions(['getCharacters']),
}
computed: {
...mapState(['characters'])
},
mounted() {
this.getCharacters()
},
I'm coding along with a Nuxt course and I got the following error while of course it worked in the tutorial.
TypeError: can't access property "dispatch", this.$store is undefined
store/index.js file:
import Vuex from "vuex";
const createStore = () => {
return new Vuex.Store({
state: { loadedPosts: [] },
mutations: {
setPosts(state, posts) {
state.loadedPosts = posts;
},
},
actions: {
setPosts(vuexContext, posts) {
vuexContext.commit("setPosts", posts);
},
},
getters: {
loadedPosts(state) {
console.log("imhere");
return state.loadedPosts;
},
},
});
};
export default createStore;
the script in posts/index.vue file:
<script>
export default {
data() {
return {
loadedPosts: [{id: "1",title: "First Post"}],
};
},
created() {
this.$store.dispatch("setPosts", this.loadedPosts);
},
};
</script>
<template>
<component :is="myComponent" />
</template>
<script>
export default {
props: {
component: String,
},
data() {
return {
myComponent: '',
};
},
computed: {
loader() {
return () => import(`../components/${this.component}`);
},
},
created() {
this.loader().then(res => {
// components can be defined as a function that returns a promise;
this.myComponent = () => this.loader();
},
},
}
</script>
Reference:
https://medium.com/scrumpy/dynamic-component-templates-with-vue-js-d9236ab183bb
Vue js import components dynamically
Console throw error "this.loader() is not a function" or "this.loader().then" is not a function.
Not sure why you're seeing that error, as loader is clearly defined as a computed prop that returns a function.
However, the created hook seems to call loader() twice (the second call is unnecessary). That could be simplified:
export default {
created() {
// Option 1
this.loader().then(res => this.myComponent = res)
// Option 2
this.myComponent = () => this.loader()
}
}
demo 1
Even simpler would be to rename loader with myComponent, getting rid of the myComponent data property:
export default {
//data() {
// return {
// myComponent: '',
// };
//},
computed: {
//loader() {
myComponent() {
return () => import(`../components/${this.component}`);
},
},
}
demo 2
I have this Vue code:
export default {
data: function() {
return {
'showPopup': false
}
},
components: {
'search-bar': SearchBarComponent,
},
mounted: function() {
$(this.$el).foundation();
},
updated: function() {
$(this.$el).foundation();
},
methods: {
clickOutsidePopup: function(event) {
console.log(event);
}
},
directives: {
clickoutside: {
bind (el) {
el.event = event => el.vm.$emit(el.expression, event)
el.addEventListener('click', el.stopProp)
document.body.addEventListener('click', event)
},
unbind(el) {
el.removeEventListener('click', el.stopProp)
document.body.removeEventListener('click', el.event)
},
stopProp(event) { event.stopPropagation() }
}
}
}
And inside the template I have this:
<div class="small-screen popup-container">
<div class="popup" v-show="showPopup" v-clickoutside="clickOutsidePopup">
<search-bar />
</div>
</div>
which will be shown/hidden if we click on this:
<span #click="showPopup = !showPopup">🔍</span>
My problem is that my directive does not execute clickOutsidePopup. When I click outside of my element? I was inspired by this: Detect click outside element
I managed to make it work with this directive code:
directives: {
clickoutside: {
bind: function (el, binding, vnode) {
el.clickOutsideEvent = function (event) {
// here I check that click was outside the el and his childrens
if (!(el == event.target || el.contains(event.target))) {
// and if it did, call method provided in attribute value
vnode.context[binding.expression](event);
}
};
document.body.addEventListener('click', el.clickOutsideEvent)
},
unbind: function (el) {
document.body.removeEventListener('click', el.clickOutsideEvent)
},
}
}
added an id to the search button:
<span id="top-bar-search-icon" #click="showPopup = !sho wPopup">🔍</span>
and modified my method:
methods: {
clickOutsidePopup: function(event) {
if (event.target.id !== "top-bar-search-icon")
this.showPopup = false;
}
},
I am new in vuejs2. I am getting below error. Could anyone say why this error is coming ? Could you please provide any sample solution for this ?
ModalBody.vue
<script>
import SemanticModal from 'vue-ya-semantic-modal'
export default {
components: { SemanticModal: SemanticModal() },
name: 'ModalBody',
props: {
active1: {
required: true
}
},
}
</script>
DataTable.vue
<script>
import ModalBody from './ModalBody'
export default {
components: { ModalBody },
data: function () {
return {
active1: false
}
},
props: {
columns: {
required: true
},
gdata: {
required: true
}
},
methods: {
show () {
this.active1 = true
}
},
}
Use computed Property(eg.isActive) for passing to children component
import ModalBody from './ModalBody'
export default {
components: { ModalBody },
data: function () {
return {
active1: false
}
},
props: {
columns: {
required: true
},
gdata: {
required: true
}
},
computed:{
isActive (){
return this.active1;
},
methods: {
show () {
this.active1 = true
}
},
}
And Pass this computed property to child component in template
<modal-body :active1='isActive'></modal-body>
By doing this it avoid mutation
Finally I got the solution. I added child component to parent component as like below
<modal-body :active1="active1" #sendValue="active1 = $event"></modal-body>
I added methods like below in Parent Component
methods: {
close() {
this.$emit('sendValue', false);
}
}
In vue prop mutating is anti pattern look here