How to destroy vuejs component from outside of component - vue.js

I have created one of component in vuejs something like this
var tree_data = Vue.extend({
template: '#tree_data_template',
props: [
'groupmodal',
'search-name',
'tree-id'
], // props in single quotes
data: function () {
return {
shared: d2d.store
};
}
});
And use this component in another template like this.
var template_data = Vue.extend({
template: '#template_data',
created: function () {
var self = this;
self.shared.setCurrentRoute('templates');
},
components: {
'tree-data': tree_data
},
data: function () {
return {
id: this.$route.params.id,
shared: d2d.store,
};
},
methods: {
destroyComponent: function () {
//Need to code for destroy tree-data component
}
}
});
Blade file code
<tree-data
groupmodal="false"
search-name="user_search"
tree-id="user_tree"
>
</tree-data>
So finally how can i destroy my "tree-data" component through the "destroyComponent()" method

As cobaltway said you can use v-if
Setting v-if initially to false will render(generate) the component.
Then in your method setting v-if to true will destroy the component.
html
<div id="template_data">
<tree-data v-if="destroyComponent"></tree-data>
</div>
script
var template_data = Vue.extend({
template: '#template_data',
created: function () {
var self = this;
self.shared.setCurrentRoute('templates');
},
components: {
'tree-data': tree_data
},
data: function () {
return {
id: this.$route.params.id,
shared: d2d.store,
destroyComponent:true
};
},
methods: {
destroyComponent: function () {
//Need to code for destroy tree-data component
this.destroyComponent = false;
}
}
});
Here is the fiddle

Related

nested object reactivity vue js

I have the following setup for my vue application
var store = {
...
state: {
currentCustomer:{},
},
};
current customer has a property that is an object called payment method
app:
var app= new Vue({
el:'#application',
data: {
sharedState: store.state
}
});
and a couple of components:
Vue.component('user_search', {
template: '#user_search-template',
data() {
return {
sharedState: store.state
}
},
methods: {
getCustomerData: function () {
this.sharedState.currentCustomer(c);
}
mounted: function () {
...
}
});
and
Vue.component('paymentdetails',{
template: '#payment_details_template',
data(){
return{
sharedState: store.state
}
},
mounted:function(){
...
}});
The issue is like this. The payment method component does not bind to the payment details object that is nested inside the current customer object
any suggestions?
Yeah, I think what you are looking for is a computed property for accessing the data.
Vue.component('paymentdetails',{
template: '#payment_details_template',
computed{
sharedState() {
return store.state
}
},
mounted:function(){
...
}});
Maybe give that a try and see how it works.

Vue.js change template data

I have the following code:
Vue.component('greeting', {
template: `<h1>{{ greeting }}</h1>`,
data: function () {
return {
greeting: app.text
}
},
});
var app = new Vue({
el: '.app',
data: {
text: 'Hello'
},
methods: {
changeText: function () {
this.text = 'Goodbye'
}
}
});
So when I call changeText method it changes text but greeting in the component is not updated. I didn't understand if I should use props, watcher or computed property in this case.
You need to pass it as a prop to the component:
Vue.component('greeting', {
template: `<h1>{{ greeting }}</h1>`,
props: ['greeting']
});
and the html:
<greeting :greeting="text"></greeting>

VueJS: Setting data initially based on http response

So I have a template .vue file:
<template>
<div id="app">
<textarea v-model="input" :value="input" #input="update"></textarea>
<div v-html="compiledMarkdown"></div>
</div>
</template>
<script>
var markdown = require('markdown').markdown;
export default {
name: 'app',
data() {
return {
input: '# Some default data'
}
},
mounted: function () {
this.$nextTick(function () {
this.$http.get(window.location.pathname + '/data').then((response) => {
this.input = response.body.markdown;
}) })
},
computed: {
compiledMarkdown: function() {
this.$http.post(window.location.pathname, {
"html": markdown.toHTML(this.input)}).then(function() {
},function() {
});
return markdown.toHTML(this.input);
}
},
methods: {
update: function(e) {
this.input = e.target.value
}
}
}
</script>
In the mounted function I am trying to set input equal to the response of an HTTP request, but when you view this file this.input is still the same as it was initially declared. How can I change this.input inside the compiledMarkdown function to be this.input in the mounted function. What other approaches might I take?
You can not call a async method from a computed property, you can use method or watcher to run asynchronous code, from docs
This is most useful when you want to perform asynchronous or expensive operations in response to changing data.
You have to ran that relevant code when input changes, like following:
var app = new Vue({
el: '#app',
data: {
input: '# Some default data',
markdown : ''
},
methods: {
fetchSchoolData: function (schoolId) {
var url = this.buildApiUrl('/api/school-detail?schoolId=' + schoolId);
this.$http.get(url).then(response => {
this.schoolsListData = response.data;
}).catch(function (error) {
console.log(error);
});
},
},
mounted: function () {
this.$nextTick(function () {
this.$http.get(window.location.pathname + '/data').then((response) => {
this.input = response.body.markdown;
})
})
},
watch: {
// whenever input changes, this function will run
input: function (newInput) {
this.$http.post(window.location.pathname, {
"html": markdown.toHTML(this.input)}).then(function() {
},function() {
this.markdown = markdown.toHTML(this.input);
});
}
},
Have a look at my similar answer here.

VueJS Extends Methods and Data

I would like to extend methods. Example:
Vue.extend({
data: function () {
return {
fetcData: 'Test',
}
},
methods: function(){
return {
modal: function(){ alert('Modal') },
}
}
});
Vue.extend({
....
});
I use multiple extends.
// VueJS Instance
new Vue({
el: 'html',
data: {
effect: true
},
methods: {
xhrGet: function () {
alert(this.fetcData); // Undefined
this.modal(); // Undefined
},
xhrPost: function (event) {
alert('xhrPost')
}
}
});
Error Code:
this.fetchData is undefined.
this.modal is not a function
Vue.extend returns a new Vue component definition that can be later on instantiated using new keyword, it doesn't change the global Vue object. So if you want to create a component hierarchy try:
var BaseComponent = Vue.extend({
methods: {
foo: function() { console.log('foo') }
}
})
var MyComponent = BaseComponent.extend({
methods: {
bar: function() {
this.foo()
console.log('bar')
}
}
})
let myComponentInstance = new MyComponent()
Check out that fiddle for a live example.

Vuejs, how to put data in children component?

I want to set currentView variable if changePassword method start.
I tried $broadcast, if the event is in Model var it works, but if I put the event in Setting var, $broadcast does not work. and I tried $children too, but didn't work.
var Settings = Vue.extend({
template: '#temp-setting',
data: function() {
return { currentView: '' };
},
components: {
'change-password': ChangePassword
}
});
This is full vuejs code
var ChangePassword = Vue.extend({
template: '#temp-change-password'
});
var Settings = Vue.extend({
template: '#temp-setting',
data: function() {
return { currentView: '' };
},
components: {
'change-password': ChangePassword
}
});
var Modal = Vue.extend({
template: '#temp-modal',
methods: {
close: function() {
Router.go('/');
$('#modal').modal('hide');
}
}
});
var MainApp = Vue.extend({
methods: {
changePassword: function() {
Router.go('/settings/change-password');
$('#modal').modal({
backdrop: false,
keyboard: false
});
}
},
ready: function() {
Router.go('/');
}
});
var Router = new VueRouter();
Router.map({
'/': {
component: Modal,
},
'/settings': {
component: Modal,
subRoutes: {
'/change-password': {
component: Settings
}
}
}
});
Router.start(MainApp, 'body');