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

// 父组件 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;
    }
  }
}

  

原文地址:https://www.cnblogs.com/beka/p/8376392.html

时间: 2024-09-29 12:43:33

父传子,子传父,模块切换原理的相关文章

vue,一路走来(12)--父与子之间传参

今天想起一直没有记录父组件与子组件的传参问题,这在项目中一直用到. 父向子组件传参 Index.vue父组件中 <component-a :msgfromfa="(positionnow)"></component-a> import componentA from './components/componentA' export default{ name:'Index', data(){ return{ positionnow:'' } } } compon

Vue 父组件向子组件传值,传方法,传父组件整体

父子组件传值 1.父组件调用子组件时绑定属性,例如-> :title="title" 2.子组件中在props中声明title:props:['title','msg'] 3.就可以在子组件中引用title Tips:避免父子组件传值时命名冲突 父子组件传方法方式一样 1.父组件调用子组件时绑定属性,例如-> :run="run" 2.子组件中props中声明run:props:['title','msg','run'] 3.子组件中的button引用r

Flutter路由跳转父级页面向子页面传参及子页面向父级页面传参

Flutter中页面通过路由跳转传参主要分两种,一种是通过push()跳转时根据设定的参数进行传参,另一种是通过pop()返回时进行传参. 父级页面向子页面push()传参 假设从A页面跳到B页面可能需要携带参数userName和userAge这两个参数,那么需要在B页面先设置这两个参数名:假设userName必须填而userAge非必需,那么可以通过设置@required其为必填选项: class PageB extends StatefulWidget { @override final u

vue的组件通讯 父传子 -- 子传父-- 兄弟组件的传值 vue的组件传值

首先文字简单撸一下 父子传子   -------首先在父组件上绑定一个属性,在子组件里用props接收,可以是数组或者是对象 子传父   ------在父组件升上自定义一个方法,在子组件里通过this.$emit("父组件上的方法名",a)     /-------a------/代表需要传递的参数        兄弟组件通讯   需要创建一个公共的vue 实例, new vue()    在main.js里 书写Vue.prototype .com=new vue()    通过pr

vue中 的传值问题 父传子和子传父

vue中 关于$emit的用法 1.父组件可以使用 props 把数据传给子组件.2.子组件可以使用 $emit 触发父组件的自定义事件. vm.$emit( event, arg ) //触发当前实例上的事件 vm.$on( event, fn );//监听event事件后运行 fn: 例如:子组件: <template> <div class="train-city"> <h3>父组件传给子组件的toCity:{{sendData}}</h

js父页面调用子页面数据时,子页面通过父页面传过来的参数回调父页面具体方法

今天写代码时发现同一页面多个地方需要调用同一个子页面,如果多个方法调用时,同一子页面回调父页面方法则会出问题,所以查了下资料,让这个功能通用化,根据具体方法回调具体父页面方法,顺便总结一下,希望以后可以有用,或许可以帮助需要帮助的人 这里使用 eval() 函数 定义和用法 eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码. 父页面调用子页面的路径(子页面的路径)如下 http://localhoust:8080/oss-portlet/html/util/area

vue--父组件向子组件传参--父组件定义v-bind:参数名--子组件接收props----子组件调用父组件的方法(子组件向父组件传参)父组件@事件名称--子组件接收this.$emit

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" con

js 弹出子页面刷新父页面

// 点击主页面的添加 跳转到JCXMUPDATE页面 function AddNewData() { //居中显示 var Url = "JCXMUPDATE.aspx?action=" + actionmethod; var height = 280; var width = 600; var win = OpenWin(Url, height, width, "no"); win.focus(); //使弹出的页面得到焦点 return false; //防止

组件之间的通信(子组件-改变父组件的值)

在vue中,组件之间的通信,是不建议子组件改变父组件的值,因为一个父组件有可能会有很多子组件,改来改去会很难管理(别人都这样说,我信) 试试: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script src='../vue.js'> </script> </head> <bod