我尝试使用vuejs和vuex与组件进行通信:
menu
hamburgerButton
。在目前的情况下,当我点击hamburgerButton
时,这个动画和菜单也是如此。使用此代码,在单击按钮后,menu
将使用vueTransition和hamburgerButton
进行动画处理。请注意,我使用vuex来管理menuIsOpen
状态。
我的问题是当我点击菜单项时,我想要解雇hamburgerButton
动画。
hamburgerButton
动画方法,调用animButtonHandler()
,封装在@click
事件中。实际上我理解为什么它不能正确地知道,但我不知道如何处理这个方法来点击父元素(菜单项)。所以我的问题是,如何从父组件访问子组件的方法?或者是否有另一种解决方法来实现这一目标?
父组件 - menu.vue:
<template>
<div class="menu">
<!-- import hamburgerButton component -->
<hamburger-button></hamburger-button>
<transition v-on:enter="enterMenuHandler" v-on:leave="leaveMenuHandler">
<div class="menu_wrapper" v-if="this.$store.state.menuIsOpen">
<ul class="menu_items">
<li class="menu_item" @click="$store.commit('toggleMenu')">
<router-link class="menu_link" to="/">home</router-link>
<router-link class="menu_link" to="/contact">contact</router-link>
</li>
</ul>
</div>
</transition>
</div>
</template>
<script>
import hamburgerButton from "hamburgerButton.vue";
export default {
components: {
'hamburger-button': hamburgerButton,
},
methods: {
enterMenuHandler(el, done){
TweenLite.fromTo(el, 0.5, {
opacity: '0',
},{
opacity: '1',
onComplete: done
});
},
leaveMenuHandler(el, done){
TweenLite.to(el, 0.5, {
opacity: '0',
onComplete: done
});
},
}
}
</script>
子组件:hamburgerButton.vue:
<template>
<div class="hamburgerButton" @click="animButtonHandler()">
<div class="hamburgerButton_inner" ref="hamburgerButtonInner">
<i class="hamburgerButton_icon></i>
</div>
</div>
</template>
<script>
export default {
methods: {
animButtonHandler (){
// toggle the state of menu if button clicked
this.$store.commit('toggleMenu');
const isOpen = this.$store.state.menuIsOpen === true;
// anim the button
TweenLite.to(this.$refs.hamburgerButtonInner, 0.5, {
rotation: isOpen ? "43deg" : '0',
});
},
}
}
</script>
store.js(在main.js中导入):
let store = new Vuex.Store({
state : {
menuIsOpen : false,
},
mutations: {
toggleMenu(state) {
state.menuIsOpen = !state.menuIsOpen
}
}
});
答案 0 :(得分:1)
我添加了事件总线的基本示例。你现在可以将它与之比较,并做出明智的改变。
如果发现任何困难,请发表评论。
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/vue@2.1.10/dist/vue.min.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="app">
<h2>event bus</h2>
<button @click="callChildAnimateMethod"> Button On Parent Call Child </button>
<childcmp><childcmp />
</div>
<script>
var EventBus = new Vue();
Vue.component('childcmp', {
template: `<div>child demo - {{ message }}</div>`,
data: function() {
return {
message: 'hello'
}
},
mounted: function() {
// listen for event
EventBus.$on('animate', this.animButtonHandler);
},
destroyed: function(){
// remove listener
EventBus.$off('animate', this.animButtonHandler);
},
methods: {
animButtonHandler: function() {
console.log('this is child method');
this.message = 'I am changed.'
}
}
});
new Vue({
el: '#app',
data: function() {
return {
}
},
methods: {
callChildAnimateMethod: function() {
EventBus.$emit('animate');
}
}
});
</script>
</body>
</html>
更新
您需要定义 EventBus
eventbus.js
import Vue from 'vue';
const EventBus = new Vue();
export default EventBus;
父组件 - menu.vue
import EventBus from './eventbus.js'
... your code
子组件:hamburgerButton.vue:
import EventBus from './eventbus.js'
... your code
现在EventBus将可用于您的代码。
答案 1 :(得分:1)
由于您想知道如何使用您的代码集成事件总线,因此它是:
创建一个只是空vue实例的事件总线
将它添加到main.js文件中或将其外包到一个完整的文件中;
<强> main.js 强>
uname -r
<强> menu.vue 强>
H.but(3) = uicontrol('Units','normalized', ...
'BackgroundColor',[1 0.7 1], ...
'Callback','MyFunction(''Reset'');', ...
'FontSize',12, ...
'Position',[0.04 0.54 0.1 0.05 ], ...
'String','Reset');
case 'Reset'
clear all % Is not working and I think that isn't that I expect
set(findobj(H.fig,'style','edit', '-or','style','text'),'string','') % H is a global variable. This trial don't give the default value, it just clear certain boxes
在创建的钩子中的事件总线上设置一个事件监听器,并在每个export const EventBus = new Vue();
事件上执行动画
<强> hamburgerButton.vue 强>
<template>
<div class="menu">
<!-- import hamburgerButton component -->
<hamburger-button></hamburger-button>
<transition v-on:enter="enterMenuHandler" v-on:leave="leaveMenuHandler">
<div class="menu_wrapper" v-if="this.$store.state.menuIsOpen">
<ul class="menu_items">
<li class="menu_item" @click="toggleMenu">
<router-link class="menu_link" to="/">home</router-link>
<router-link class="menu_link" to="/contact">contact</router-link>
</li>
</ul>w
</div>
</transition>
</div>
</template>
<script>
import hamburgerButton from "hamburgerButton.vue";
import {EventBus} from './path/to/main.js' //or a path to file where you exported your EventBus
export default {
components: {
'hamburger-button': hamburgerButton,
},
methods: {
toggleMenu(){
this.$store.commit('toggleMenu');
EventBus.$emit('animate-hamburger-btn');
},
enterMenuHandler(el, done){
TweenLite.fromTo(el, 0.5, {
opacity: '0',
},{
opacity: '1',
onComplete: done
});
},
leaveMenuHandler(el, done){
TweenLite.to(el, 0.5, {
opacity: '0',
onComplete: done
});
},
}
}
</script>