Vue

时间:2018-03-15 09:59:55

标签: javascript reactjs vue.js vue-component

我是Vue的新手,来自宁静的React-y郊区。我正从后者重建我的SideNav(“抽屉”)组件。在那里,当单击按钮(与导航本身无关)时,setState编辑this.state.toggle与相应的

相关联
class thePage extends React.Component {
...
    this.handleToggleClick = this.handleToggleClick.bind(this);
    this.state ={
      toggleState: false
    };
  }

// Slide out buttons event handlers
  handleToggleClick(){
    this.setState({
      toggleState: !this.state.toggleState
    })
  }

render() {

const button = <a href="#" onClick={this.handleToggleClick}>here</a>

const isOpenWithButton = this.state.toggleState;


return (
 <div>
  {button}
  <SideNav logo="logo.png" isOpenWithButton={isOpenWithButton}>
  . . .
  </SideNav>
 </div>
);
}

}

    export default SideNavPage;

SideNav如下所示:

class SideNav extends React.Component {

  constructor(props){
    super(props);
    this.state = {
      isThere: false,
      showOverlay: false,

    }
    this.handleOverlayClick = this.handleOverlayClick.bind(this);
  }

  componentWillReceiveProps(NextProps) {
    if (this.props.isOpenWithButton !== NextProps.isOpenWithButton) {
      this.setState({
        isThere: true,
        showOverlay: true
      })
    }
  }

  handleOverlayClick(){
    this.setState({
      isThere: false,
      showOverlay: false
    });
  }

  render() {
    const {
      tag: Tag,
   ...
      isOpenWithButton,
    } = this.props;

    let isThere = this.state.isThere;
    let showOverlay = this.state.showOverlay;
    const overlay = <div class="overlay" onClick={this.handleOverlayClick}></div>


    const sidenav = (
      <Tag>
        <ul>
          {logo &&
            <li>
              <div className="logo-wrapper">
                <a href={href}>
                  <img src={logo} className="img-fluid flex-center d-block"/>
                </a>
              </div>
            </li>
          }
          {children}
        </ul>
      </Tag>
    );


    return (
      <div>
        {isThere && sidenav}
        {showOverlay && overlay}
      </div>
    );
  }
}

export default SideNav;

因此,正如您所看到的,单击该按钮会导致isOpenWithButton道具发生变化,并且无论何时发生(componentWillReceiveProps),都会出现带有叠加层的sidenav。

我做了一些将它移植到Vue的工作,但因为它没有这个生命周期钩子,所以我坚持使用道具。我有一个以下问题:单击按钮打开叠加层,但是当您通过单击叠加层关闭它时,按钮发送的布尔道具不会改变,如果sidenav已经打开,则必须单击按钮两次。我知道我必须错过Vue逻辑中的一个重要部分,我无法掌握哪一个。

1 个答案:

答案 0 :(得分:2)

使用.sync修饰符

您正在寻找的是vue a .sync修饰符。

  

当子组件变异具有.sync的道具时,值更改将反映在父组件中。

有了这个,你可以实现你所描述的:

  

单击按钮可打开叠加层,但当您通过单击叠加层关闭它时,按钮发送的布尔道具不会更改

使用集中存储 - (如vuex)

如果你有一个集中的状态/商店也可以实现同样的目的,在这种情况下,你的两个组件都可以依赖于那个状态属性。

请参阅有关Vue文档的state management

  

由于多个组件分散在许多组件中以及它们之间的交互,大型应用程序的复杂性通常会增加

您可以简单地使用相同的属性,例如:

$store.commit('overlayToggle');