简体   繁体   中英

Vue Component, toggle data

Think i'm cracking up, this is some very basic stuff but it doesn't seem to be working...

Basically clicking the link should toggle display between true and false, but this isn't the case.

 Vue.component('dropdown', { props: [ 'expanded' ], data: function() { return { display: !!(this.expanded) } }, template: '<div><transition name="expand"><slot :display="display"></slot></transition></div>' }); window.app = new Vue({ el: '#app' }); 
 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <div id="app"> <dropdown> <div slot-scope="{ display }"> <a href="javascript:void(0)" @click="display = !display">Toggle {{ display }}</a> <div v-if="display"> Dropdown content </div> </div> </dropdown> </div> 

Edit:

Updated code, I forgot I changed that, I did infact have the click event as display = !display . But even with that said, if you had tried to click the button you would see that it doesn't change the true either...

Updating after a correcting comment from . 提出纠正意见后更新。 I stumbled onto the right answer without really understanding it.

The problem is that within the slot, display refers to an item in the scope-slot object. Updating it there does not update the actual source variable. If you pass in and call a function, the proper variable is updated.

 Vue.component('dropdown', { props: ['expanded'], data: function() { return { display: Boolean(this.expanded) } }, methods: { toggle() { this.display = !this.display; } }, template: '<div><transition name="expand"><slot :display="display" :toggle="toggle"></slot></transition></div>' }); new Vue({ el: '#app' }); 
 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <div id="app"> <dropdown> <div slot-scope="{display, toggle}"> <a href="javascript:void(0)" @click="toggle">Toggle {{ display }}</a> <div v-if="display"> Dropdown content </div> </div> </dropdown> </div> 

One solution would be to implement a v-model for the dropdown component which would allow you to two-way bind the display property to a property in the parent. That way you wouldn't need to pass anything via the slot-scope .

Here's an example of that:

 Vue.component('dropdown', { props: [ 'value' ], data() { return { display: !!(this.value) } }, watch: { value(value) { this.$emit('input', value); } }, template: '<div><transition name="expand"><slot></slot></transition></div>' }); new Vue({ el: '#app', data() { return { dropdownToggle: false } } }); 
 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <div id="app"> <dropdown v-model="dropdownToggle"> <div> <a href="javascript:void(0)" @click="dropdownToggle = !dropdownToggle"> Toggle {{ dropdownToggle }} </a> <div v-if="dropdownToggle"> Dropdown content </div> </div> </dropdown> </div> 

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM