父传子,子传父,模块切换原理

Posted beka

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了父传子,子传父,模块切换原理相关的知识,希望对你有一定的参考价值。

// 父组件 add-song.vue

// 添加歌曲模板
<template>
  <transition name="slide">
    <div class="add-song" v-show="showFlag" @click.stop>
      <div class="header">
        <h1 class="title">添加歌曲到列表</h1>
        <div class="close" @click="hide">
          <i class="icon-close"></i>
        </div>
      </div>
      <div class="search-box-wrapper">
        <search-box ref="searchBox"
                    @query="onQueryChange"
                    placeholder="搜索歌曲"
        ></search-box>
      </div>
      <div class="shortcut" v-show="!query">
        <switches :switches="switches"
                  :currentIndex="currentIndex"                  @switch="switchItem"
        ></switches>
        <div class="list-wrapper">
          <scroll class="list-scroll"
                  ref="songList"
                  v-if="currentIndex===0"
                  :data="playHistory"
          >
            <div class="list-inner">
              <song-list :songs="playHistory" @select="selectSong"></song-list>
            </div>
          </scroll>
          <scroll class="list-scroll"
                  ref="searchList"
                  v-if="currentIndex===1"
                  :data="searchHistory"
          >
            <div class="list-inner">
              <search-list :searches="searchHistory"
                           @select="addQuery"
                           @delete="deleteSearchHistory"
              ></search-list>
            </div>
          </scroll>
        </div>
      </div>
      <div class="search-result" v-show="query">
        <suggest :query="query"
                 :showSinger="showSinger"
                 @select="selectSuggest"
                 @listScroll="blurInput"
        ></suggest>
      </div>
      <top-tip ref="topTip">
        <div class="tip-title">
          <i class="icon-ok"></i>
          <span class="text">1首歌曲已经添加到播放列表</span>
        </div>
      </top-tip>
    </div>
  </transition>
</template>
<script>
// 搜索框组件
import SearchBox from ‘base/search-box/search-box‘
// 切换组价
import Switches from ‘base/switches/switches‘
// 滚动组件
import Scroll from ‘base/scroll/scroll‘
// 歌单
import SongList from ‘base/song-list/song-list‘
import {mapGetters, mapActions} from ‘vuex‘
import Song from ‘common/js/song‘
import SearchList from ‘base/search-list/search-list‘
// 搜素结果模板
import Suggest from ‘components/suggest/suggest‘
import TopTip from ‘base/top-tip/top-tip‘
export default{
  data() {
    return {
      showFlag: false,
      currentIndex: 0,
      switches: [
        {name: ‘最近播放‘},
        {name: ‘最近搜索‘}
      ],
      query: ‘‘,
      // 不显示歌手
      showSinger: false
    }
  },
  computed: {
    ...mapGetters([
      ‘playHistory‘,
      ‘searchHistory‘
    ])
  },
  methods: {
    // 将search-box中的input给blur(失去焦点事件),隐藏输入框
    blurInput() {
      // 父组件通过$refs调用子组件searchBox的blur()方法
      this.$refs.searchBox.blur()
    },
    // 保存搜索历史
    saveSearch() {
      // 通过mapActions调用saveSearchHistory()来对state进行修改,完成存储
      this.saveSearchHistory(this.query)
    },
    // 选择搜索表中歌曲
    selectSuggest() {
      // 保存搜索历史
      this.saveSearch()
      // 提示框
      this.$refs.topTip.show()
    },
    // 监听search-box中query变化,并将变化值传递给add-song然后发送给suggest并请求数据
    onQueryChange(query) {
      this.query = query
    },
    // 将搜索历史加入搜索框
    addQuery(query) {
      this.$refs.searchBox.setQuery(query)
    },
    selectSong(song, index) {
      if (index !== 0) {
        // 此处song是从缓存中读取出来的,不是对象需要实例化也就是new
        this.insertSong(new Song(song))
        this.$refs.topTip.show()
      }
    },
    // 将索引传给currentIndex并传给子组件
    switchItem(index) {
      this.currentIndex = index
    },
    show() {
      this.showFlag = true
      // 点开页面时,刷新页面,scroll重新计算,然后就可以滚动了
      if (this.currentIndex === 0) {
        this.$refs.songList.refresh()
      } else {
        this.$refs.searchList.refresh()
      }
    },
    hide() {
      this.showFlag = false
    },
    ...mapActions([
      ‘insertSong‘,
      ‘deleteSearchHistory‘,
      ‘saveSearchHistory‘
    ])
  },
  components: {
    SearchBox,
    Switches,
    Scroll,
    SongList,
    SearchList,
    Suggest,
    TopTip
  }
}
</script>
<style lang="scss" scoped>
@import "./add-song.scss";
</style>

// 子组件switches.vue

// 切换模块
<template>
  <ul class="switches">
    <li class="switch-item"
        :class="{‘active‘ : currentIndex === index}"
        v-for="(item, index) in switches"
        @click="switchItem(index)"
    >
      <span>{{item.name}}</span>
    </li>
  </ul>
</template>
<script>
export default{
  props: {
    switches: {
      type: Array,
      default: []
    },
    currentIndex: {
      type: Number,
      default: 0
    }
  },
  methods: {
    switchItem(index) {
      // 将点击将索引发给父组件
      this.$emit(‘switch‘, index)
    }
  }
}
</script>
<style lang="scss" scoped>
  @import "./switches";
</style>

父传子:(本页数据存储一般放在data()中,接受的父组件的数据一般放在props)将data()中的switches数据通过数据绑定(左侧为绑定数据的名称):switches="switches”(右侧为绑定的数据)传给子组件switches,用props来接受数据(通过传来的数据名)
子传父:将点击开关模块对应的下角标传递给父组件,this.$emit(‘switch‘,index)通过emit发射switch事件,在父组件中通过(左侧为接受子组件发送过来的事件)@switch="switchItem"(右侧为父组件定义的方法名)
模块切换实现原理:
主要通过下角标来控制切换后的样式,事件
先将子组件要显示的switches数据通过绑定的方式传给子组件switches,v-for将数据渲染到页面并获得每个item的index,当点击每个item时,会获得当前点击item的下角标currentIndex,将currentIndex传给父组件,通过v-if ="currentIndex===0",v-if="currentIndex===1"来控制页面显示,将currentIndex通过数据绑定再传给子组件switches,通过class绑定的方法来控制样式的变化:class=“‘active’: currentIndex === index”(在样式scss中,先写好active样式)
// switches.scss样式

@import "~common/scss/variable";

.switches{
  display: flex;
  align-items: center;
  width: 240px;
  margin: 0 auto;
  border: 1px solid $color-highlight-background;
  border-radius: 5px;
  .switch-item{
    flex: 1;
    padding: 8px;
    text-align: center;
    font-size: $font-size-medium;
    color: $color-text-d;
    &.active{
      background: $color-highlight-background;
      color: $color-text;
    }
  }
}

  

以上是关于父传子,子传父,模块切换原理的主要内容,如果未能解决你的问题,请参考以下文章

React传值(子传父,父传子)

微信小程序创建组件以及父传子、子传父内容

Vue组件 父传子 子传父

react实现父传子子传父

vue 组件通信 (子传父 , 父传子 , 兄弟通信)

vue中组件间的通信,父传子,子传父