vue中数据交互和传参方式

一、介绍

通过vue-music-app项目,初步熟悉vue中的数据交互和传参方式,此项目中使用到了
vuex,vue-router,props,solt传参方式进行页面传参,以及如何设置代理服务器对访问的ip地址进行管理
,并且使用到了vant按需引入轮播图组件。

源码地址

二、传参方式

1、插槽分发内容

  • 定义一个组件,在组件内写入<slot></slot>标签,当调用组件时,组件中如果有内容,则会替换slot标签渲染数据。
  • 新建一个slider组件:
<template>
  <!-- TODO:vue通过ref设置dom元素,通过$refs方法获取此dom节点 -->
  <div class="slider" ref="slider">
    <div class="sliderGroup" ref="sliderGroup">
      <slot></slot>
    </div>
  </div>
</template>
  • 新建一个recommend.vue组件,调用slider组件
<template>
  <div class="recommend">
    <h2 class="recommendlist">推荐歌单</h2>
    <slider>
      <!-- TODO:使用插槽,通过组件的slot标签,替换数据 -->
      <div v-for="item in slider" :key="item.id">
        {{ item.songName }}
      </div>
    </slider>
</div>
</template>
<script>

import slider from "./slider.vue";
export default {
  data() {
    return { 
      slider: []
    };
  },
  components: {  //调用slider组件
    slider
  },
   methods: {
      getSlider() {  //获取数据存储在slider数组中
        this.$axios.get("http://www.wanandroid.com/tools/mockapi/9664/songlist").then(resp => {
          if (resp.status == 200) {
            this.slider = resp.data;
          }
        });
      },
   }
</script>
页面效果.png

2、通过props进行父子组件传参

  • 有些时候,我们定义一个组件,在多个地方调用,而所需展示的数据不同,可以通过props传参方式对组件进行页面渲染
  • 新建一个Songlist.vue组件
<!-- 不同数据调用此模板 -->
<template>
  <div>
    <ul>
      <li class="songli" v-for="item in songList" @click="selectSong(item)">
        <div class="songinfor">
          <p class="title">{{item.songName}}</p>
          <p class="singer" style="font-size:12px;color:#888">{{item.singer}}</p>
        </div>
        <p class="start">
          <img src="../../static/img/start.png">
        </p>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
    props: ["songList"],  //通过props接收父组件传送的数据
};
</script>
  • 新建一个recommend.vue,调用子组件SongList
<template>
  <div class="recommend">
      <!-- TODO:动态绑定数据songList数据,子组件通过props接收数据 -->
    <songList :song-list="songList"></songList>  
        
  </div>
</template>
<script>
import songList from "./Songlist.vue"
export default {
  data() {
    return { 
      songList: []
    };
  },
  components: {
    songList,
  },
  methods: {
    getSongList() {
      this.$axios.get("http://www.wanandroid.com/tools/mockapi/9664/recommend").then(resp => {
        if (resp.status == 200) {
          this.songList = resp.data;
        }
      });
    }
  }
};
</script>
页面效果.png
  • 新建一个Hot.vue组件,也调用子组件Songlist
<template>
  <div id="hot">    
        <div class="banner">
            热门歌曲
        </div>
        <!-- 动态绑定数据hotList数据 -->
        <songList :song-list="hotList"></songList>
    </div>
</template>

<script>
import songList from "./Songlist.vue"
    export default {
                data() {
            return {hotList: []}
        },
        methods: {
            getHotList() {
                 this.$axios.get("http://www.wanandroid.com/tools/mockapi/9664/recommend").then(resp => {
                     
                    if (resp.status == 200) {
                        this.hotList = resp.data;
                    }
                });
            }
        },
        mounted() {
            this.getHotList()
        },
        components: {
            songList
        }
    }
</script>
页面效果.png

3、使用vue-router进行页面传参

  • 点击某个菜单项,跳转到另一个组件页面时可以使用vue-router进行传参
  • 对路由进行配置


    路由配置.png
  • 在songList组件添加点击事件跳转查看详情页
<!-- 不同数据调用此模板 -->
<template>
  <div>
    <ul>
      <li class="songli" v-for="item in songList" @click="selectSong(item)">
        <div class="songinfor">
          <p class="title">{{item.songName}}</p>
          <p class="singer" style="font-size:12px;color:#888">{{item.singer}}</p>
        </div>
        <p class="start">
          <img src="../../static/img/start.png">
        </p>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
    props: ["songList"],
    methods: {
        selectSong(item) {
            // 直接调用$router.push,实现携带参数的跳转
            // this.$router.push({
            //     "name" : "Detail",  //发送跳转页面名字
            //     "params" : {item,item} //TODO: 通过路由的params进行传参
            // })
            this.$router.push({
                "path": "/detail/:item",
                "query": {item: JSON.stringify(item)}  //TODO: 通过路由的query进行传参
            })
        },
    }
};
</script>
  • 新建detail.vue组件,接收页面传参
<template>
    <transition name="slider">
        <div class="detail">
                <div class="songimg">
                    <img :src="songDetail.songImgSrc">
                </div>
                <div class="songtitle">
                    {{songDetail.songName}}
                </div>
                <div class="songaudio">
                    <audio autoplay="autoplay">
                        <source src="static/song/song.ogg" type="audio/ogg" />
                        <source src="static/song/song.mp3" type="audio/mpeg" />
                    </audio>
                </div>
            </div>
    </transition>
</template>
<script>
    export default {
        data() {
            return {
                songDetail: {}
            }
        },
        mounted () {
            //TODO:parmas传参不可以刷新,会丢失数据,query可以刷新页面
            // console.log(this.$route.params) //$route接收传递的参数
            // this.songDetail = this.$route.params.item  //TODO: params接收路由传递的参数
            this.songDetail = JSON.parse(this.$route.query.item); //TODO: query接收路由传递的参数
        },
    }
</script>

4、使用vuex进行数据管理

  • 使用vuex可以更好的管理数据状态,使数据得到共享
  • 安装vuex npm install vuex --save
  • 新建store文件夹,同一组织store文件


    store文件结构.png
(1) 在main.js引入store
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
import store from './store/index'  //导入store主文件index

Vue.prototype.$axios = axios  //将axios添加到vue的原型上,所有vue实例上都可以使用axios

Vue.config.productionTip = false

new Vue({
  el: '#app',
  store,  //添加在vue实例上
  router,
  components: { App },
  template: '<App/>'
})
(2) 编写store文件夹
  • index.js
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import state from './state'
import mutations from './mutations'
import actions from './action'
Vue.use(Vuex)

export default new Vuex.Store({
    getters,
    state,
    mutations,
    actions
})
  • state.js //数据管理
const state = {
  song: {}
}
export default {
    state
}
  • getters.js //管理数据状态,相当于computed(计算)属性
const getters={
  getSong(state){
    return state.song;
  }
}
export default getters;
  • actions.js //提交数据变化,一把用于异步获取数据,相当于methods(方法)属性
import types from './types.js'
import axios from 'axios'

const actions = {
  getSongAsync({commit,state}) {
    axios.get("/recommend/").then(resp => {
      if (resp.status == 200) {
        commit(types.GET_SONG, resp.data);  //提交突变
      }
    });
  }
}

export default actions;
  • mutations.js //改变数据状态,也就相当于对state数据进行更新
import types from './types'

const mutations = {
  [types.GET_SONG](state,data) {
        state.song = data
        console.log(data)
  }
}
export default mutations
  • types.js //定义方法名常量,管理方法名
const GET_SONG = "GET_SONG"  
export default {
    GET_SONG
}
(3) 在detail.vue组件调用state中的数据
<script>
import { mapGetters, mapActions } from "vuex";
export default {
  computed: {
    ...mapGetters(["getSong"])  //此数据可以直接在页面模板调用
  },
  created() {
    this.$store.dispatch("getSongAsync");  //页面初始化时发送事件
  }
};
</script>

三、引入Vant

Vant按需引入组件

官方网址

1、安装

npm i vant -S

  • babel-plugin-import 是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式
# 安装 babel-plugin-import 插件
npm i babel-plugin-import -D
// .babelrc 中配置
// 注意:webpack 1 无需设置 libraryDirectory
{
  "plugins": [
    ["import", {
      "libraryName": "vant",
      "libraryDirectory": "es",
      "style": true
    }]
  ]
}

!注意:配置 babel-plugin-import 插件后将不允许导入所有组件

2、新建--src/vant-components.js按需使用swiper组件
import Vue from 'vue'

import { Swipe, SwipeItem } from 'vant';

Vue.use(Swipe).use(SwipeItem);
3、在main引入vant-components.js即可在所有页面使用引入的组件
引入组件.png
4、此时就可以在vue组件中使用vant的swipe组件了
使用组件.png

四、配置代理服务器

编译打包前要做的事

1、修改文件--config/index.js
  • 找到build中assetsPublicPath选项进行修改
    修改assetsPublicPath选项.png
2、修改文件--config/index.js,进行代理服务器配置
  • 找到dev中的proxyTable进行代理服务器配置,统一管理接口
proxyTable: {
  '/song': {  //匹配项,放在项目调用中
    target: 'http://www.wanandroid.com/tools/mockapi/9664/songlist', // 接口域名
    // secure: false,  // 如果是https接口,需要配置这个参数
    changeOrigin: true, //是否跨域
    pathRewrite: { //重写地址
      '^/song': '' //因为接口中没有这个匹配项,所以要重写地址,才能正常访问
    }
  },
}
3、修改文件--build/utils.js
  • 找到ExtractTextPlugin.extract,添加publicPath选项
if (options.extract) {
    return ExtractTextPlugin.extract({
      publicPath: '../../',  //TODO:css中用到资源时需要加的属性
      use: loaders,
      fallback: 'vue-style-loader'
    })
  } else {
    return ['vue-style-loader'].concat(loaders)
  }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容

  • Vuex是什么? Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件...
    萧玄辞阅读 3,113评论 0 6
  • 安装 npm npm install vuex --save 在一个模块化的打包系统中,您必须显式地通过Vue.u...
    萧玄辞阅读 2,934评论 0 7
  • Vue-Music 一| 前期工作 1.项目初始化 npm install -g vue-cli vue init...
    noobakong阅读 1,828评论 0 5
  • ### store 1. Vue 组件中获得 Vuex 状态 ```js //方式一 全局引入单例类 // 创建一...
    芸豆_6a86阅读 342评论 0 0
  • 南京的三月 词:狂狷的Liang_ 走出24号出口 你坐在地铁口的台阶上 掩着门的店铺 我从玻璃上 看到你被风吹起...
    StoneRli阅读 190评论 0 0