Vue.js Passing variable from one component to another (jQuery) - javascript

I have a component called ShowComment and a component called EditComment.
In ShowComment there is a variable this.CommentRecID. I want to use this variable in the component EditComment.
The problem is that a console.log(this.CommentRecID); shows that the variable is undefined in EditComment, but defined in ShowComment, but I don't know why it's undefined:
I used this to "use" this.CommentRecID in EditComment, but I don't know if this is the correct way to do it because it's related to jquery:
import * as $ from "jquery";
import DatePicker from "vue2-datepicker";
export default {
props: ["CommentRecID"],
components: { DatePicker },
Here's the full ShowComment component: https://pastebin.com/fcy4PCq0
Here's the full Editcomment component: https://pastebin.com/uik7EwD1
I'm fairly new to Vue.js. Does someone know how one can solve this issue?

You should not use jQuery and Vue.js at the same time.
You should try to use props to send data from parent to child.
You could add EditComment as an element in your ShowComment something like this:
<EditComment CommentRecID="this.CommentRecID" v-if="showEdit" />
And toggle the showEdit flag from the editItem method
editItem() {
this.showEdit = true
}
If you want to show a modal, then your EditComment component is probably up the tree so you could either use EventBus or use Vuex.
It seems like you are already using Vuex in your project, so add a mutation that stores the CommentRecID and use it in a similar manner to show the dialog.

You can use Vue Props to easily solve this problem, you have to send the variable from parent component to child component, please check this PROPS documentation out, its self explanatory:
Props Vuejs documentation
please let me know if you find trouble in using props

Related

Set "this" keyword of App.vue in Vuex state

I found a seloution for how to access to vue-router and other services that works only inside the vue component. In the created option of App.vue i save the "this" of vue app inside state of vuex.
does it's a good way or can make some problems in future?
instead to write:
this.$router.push('route-name')
from some component, is save the this keyword in the state as context key for example,
and now from the Actions i'm using the context instead this
such like this:
state.context.router.push('route-name')
and its works..
my question is if its good solution or not.
I think that is not a good solution, if you want to use this, you should try with the actions or getter returned value, inside a Vue file instead using it directly in an action.
I'm giving an example and an explanation
Example:
Getter:
export function getRedirect(state){
return state.routerName
}
Vue file:
<template>
Page
<button #onClick="redirect" > Redirect </button>
</template>
<script>
import {mapGetters} from 'vuex'
export default: {
computed:{
...mapGetters('VuexStoreName',['getRedirect'])
},
methods:{
redirect(){
this.$router.push(this.getRedirect)
}
}
}
</script>
So, instead of using the redirect inside an JS file, creating an action and passing this inside the parameter or getting it by state, you'll be using it correctly in a Vue file.
The probblem setting this in the state is that when it changes the instance saved will not change, and you'll have to update every time and everywhere. And calling this inside a Vue file, it'll always be updated

Access data inside dynamic components from parent component in VueJS + Vuex

I created this demo to explain better my goal: https://codepen.io/Albvadi/pen/OJMgByR
Each button create a new alert creating a object inside the vuex store in the components array. With the component property I know the type of the component to render.
Each alert generate a random string in a data property inside the component.
How do I need to configure the connection with Vuex to obtain the data from the child alert component inside the global components array?
Thanks!
Finally, I solved with a computed property that gives me the parent item. I don't know if it is the best way or if there is a simpler one, but I think it is the correct one.
computed: Vuex.mapState({
getParentItem(state) {
return state.components[state.components.indexOf(this.index)];
}
}),
Demo solved: https://codepen.io/Albvadi/pen/wvMrpLv

How to remove global component completely in Vue?

I have a component called button-widget and it is registered globally.
Vue.component('button-widget', {
template: `<button>My Button</button>`
})
Now, how can I delete this component permanently?
I am not talking about v-if or $destroy() -- I just want to completely remove this component in such a way that it was never defined so that for example, I get this warning: Unknown custom element: <button-widget> - did you register the component correctly? For recursive components, make sure to provide the "name" option..
There is no public API to do this.
The correct solution is not to register it globally in the first place and instead just use it on a per-component basis by adding it to the components option of each component you want to use it in.
Otherwise you can unregister it like this:
delete Vue.options.components['button-widget']

Vue V-Bind to Programmatically Created Instance

I follewed this instructions to create a Vue instance programmatically. I use this to dynamically add component instances in project by user events. My problem now it, that my component to initialize needs a model. I regular I would use it like this:
<my-component v-model="variable"/>
But now I create this component with this code snippet within another components methods section:
import MyComponent from '../MyComponent'
...
add () {
const Component = Vue.extend(MyComponent)
const instance = new Component()
instance.$mount()
document.getElementById('app').appendChild(instance.$el)
}
I know using a $ref here is better, but it must work globally, so I didn't know how to add it else to the DOM. But just as side note.
Now i need to give this instance a v-model binding. I already know how to define props or slots, but not a model. In the official docu they mention something for that. But to be honest I don't understand it and didn't get it work.
Can anybody tell me how I have to extend my code to define the model for this instance? Something like instance.$model = this.variable would be awesome. Thank u!
Finally I got some kind of workaround for this. I'm not aware if there is a better solution out there, but this works for me.
The MyComponent used this description to handle the v-model. By this is emit the change event for the parent component. So The idea is simply to pass the model variable as property, work in MyComponent on a copy of this variable and emit changes to the parent. To catch this change event I can add to my instance the following:
const Component = Vue.extend(EditWindow)
const instance = new Component({
propsData: { content: this.variable }
})
instance.$on('change', value => {
this.variable = value
})
instance.$mount()
document.getElementById('app').appendChild(instance.$el)
I guess this is pretty the same as Vue actually does in the background (maybe?). But after all it works and I'm happy. Of cause I'm open for the 'correct' solution, if such one should exist.

TestUtils get React element rendered in the "root"

I have a React component rendered directly on the "root" (document.body), I want to get this element using TestUtils but I do not want to keep a reference to this element. Is there any way to do that?
Basically I want something like this:
React.addons.TestUtils.findRenderedComponentWithType(document.body, MyReactClass);
But this does not work (passing null or undefined as the first parameter does not work either). I am left wondering if there is any "root" React Component Tree that I can get a reference to.
If it is for Unit test purpose, you don't need to do that, if you are testing the component MyReactClass, just do :
const props = {//some mocked props}
const element = TestUtils.renderIntoDocument(<MyReactClass {...props}/>);
element will contains the element.
Hope I correctly understood your question...

Categories