I want to create a tree-view component in Vue-JS to display my JSON data. But I have an additional requirement where I need to launch a VueJS modal on clicking any of the data fields of JSON view. I looked up at several npm modules
that does display data in tree-view but I am not sure how to modify them to make them clickable and launch vue-js modal
. This is the code I am currently using to display tree-view but none of the fields are clickable.
assets.vue
<template>
<div>
<h1>The Assets Page</h1>
<!--<p>{{response}}</p>-->
<tree-view v-on:click="openGroupModal()" :data="response._embedded.assets" :options="{maxDepth: 0, rootObjectKey: 'Assets'}"></tree-view>
</div>
</template>
<script>
import axios from 'axios'
import GroupModal from '../assets/assetdetails.vue'
import Vue from 'vue'
import VModal from 'vue-js-modal'
Vue.use(VModal, { dynamic: true })
export default {
name: 'service',
data () {
return {
response: [],
errors: []
}
},
created () {
this.callRestService()
},
methods: {
callRestService () {
axios.get('http://localhost:8080/rest/assets')
.then(response => {
// JSON responses are automatically parsed.
this.response = response.data
})
.catch(e => {
this.errors.push(e)
})
},
openGroupModal(){
this.$modal.show(GroupModal,
{
draggable: true,
resizable: true,
scrollable: true,
height: "auto",
width:"50%"
})
}
}
}
</script>
<style>
</style>
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import VueRouter from 'vue-router'
import VModal from 'vue-js-modal'
import App from './App.vue'
import TreeView from 'vue-json-tree-view'
import { routes } from './routes';
Vue.use(VueRouter);
Vue.use(VModal, { dynamic: true })
Vue.use(TreeView)
//Vue.config.productionTip = false
const router = new VueRouter({
routes
});
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
Any ideas?
UPDATE : I tried Jacob's answer but that didn't help me launch the modal. I tried this:
<template>
<div>
<h1>The Assets Page</h1>
<!--<p>{{response}}</p>-->
<div @click.capture="openGroupModal($event)">
<tree-view :data="response._embedded.assets" :options="{maxDepth: 0, rootObjectKey: 'Assets'}"></tree-view>
</div>
</div>
</template>
<script>
import axios from 'axios'
import GroupModal from '../assets/assetdetails.vue'
import Vue from 'vue'
import VModal from 'vue-js-modal'
Vue.use(VModal, { dynamic: true })
export default {
name: 'service',
data () {
return {
response: [],
errors: []
}
},
created () {
this.callRestService()
},
methods: {
callRestService () {
axios.get('http://localhost:8080/rest/assets')
.then(response => {
// JSON responses are automatically parsed.
this.response = response.data
})
.catch(e => {
this.errors.push(e)
})
},
openGroupModal($event){
console.log("The console message",$event.target);
this.$modal.show(GroupModal,
{
draggable: true,
resizable: true,
scrollable: true,
height: "auto",
width:"50%"
})
}
}
}
</script>
<style>
</style>
well.. a div container can work for you
use @click.capture. (once .capture
is added, an event targeting an inner element is handled here before being handled by that element, from Vue doc )
and you can get exactly which element has been clicked on by using $event.target
eg
<template>
<div @click.capture="openGroupModal($event)">
<tree-view :data="{1:1,2:{a:'a'}}" :options="{maxDepth: 3}"></tree-view>
</div>
</template>
<script>
export default {
name: "HelloWorld",
methods:{
openGroupModal($event){
console.log($event.target);
// other codes for showing modal and etc...
}
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>
Tested on HelloWorld.vue component in https://codesandbox.io/s/nkwk2k095l
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.