vue项目参数传递

页面的参数传递

1、再脚手架项目中常用的跳转方法,使用<router-lint :to = "">方法和使用vue-router;
2、参数的传递都是页面跳转中常用的,另外有些参数需要全局共享,这时使用的一般都是vueX;

父传递子

1、父传子的方式可以直接使用组件的porps方式传递参数;
2、可以使用vueX共享数据传递参数;
3、可以使用vue-router方式再跳转路由中传递参数;

子传父参数

1、首先跳转会使用到路由,所以使用路由的方式传递参数是可以的vue-router;
2、其次共享数据再全局都可以调用,使用vueX方法是可以的;

兄弟之间的传参

1、共享数据vueX的方式;
2、使用路由方式vue-router;


父子传参/组件props方式传参

使用组件间传参的方式

***组件减传参使用的是属性props***:

组件加传参的使用方式

  • 首先是父子传参,需要一个父组件,和一个子组件,并且需要再父组件中声明子组件;注意在路由中的配置;
  • 其次,向子组件中传递参使,再使用自定义子组件标签中自定义一个属性,作为一个存放参数的盒子;
  • 最后,在子组件的javascript的模块中使用属性props进行属性的承接,注意这里参数是父组件中定义的属性名;

路由设置

这是使用路由嵌套的父子组件使用方式;

{
      path: '/father',
      name: 'father',
      component: father,
      children: [
        {
          path: 'son',
          name: 'son',
          component: son
        }
      ] 
}

还有一种是使用非嵌套路由方式的父子组件;

路由字典的结构

interface RouteConfig = {
  path: string,
  component?: Component,
  name?: string, // 命名路由
  components?: { [name: string]: Component }, // 命名视图组件
  redirect?: string | Location | Function,
  props?: boolean | Object | Function,
  alias?: string | Array<string>,
  children?: Array<RouteConfig>, // 嵌套路由
  beforeEnter?: (to: Route, from: Route, next: Function) => void,
  meta?: any,

  // 2.6.0+
  caseSensitive?: boolean, // 匹配规则是否大小写敏感?(默认值:false)
  pathToRegexpOptions?: Object // 编译正则的选项
}

其中的props是判断是否使用props进行参数传递:

{
      path: '/father',
      name: 'father',
      component: father,
      props:true
},
{
      path: '/son',
      name: 'son',
      component: son,
      props:true
}

父组件

父组件中引入子组件,然后再使用子组件的自定义标签的时候将自定义属性和参数绑定

// 父组件
<template>
  <div>
    <h1>父组件</h1>
    <!-- 路由窗口,这里也可直接使用子组件的标签指定组件 -->
    <!-- 绑定了两个自定义属性fData fMessage,使用v-bind绑定(一种是简写方式)-->
    <router-view v-bind:fData="data1" :fMessage="data2"></router-view>
  </div>
</template>
 
<script>
export default {
  data () {
    return {
      data1: '父组件数据data1',
      data2: '父组件数据data2',
    };
  }
}
</script>

子组件

子组件中需要使用props属性进行参数的获取

// 子组件
<template>
  <div>
    <h1>子组件</h1>
    <p>下面是父组件传过来的数据</p>
    <p>第一个数据:{{fData}}</p>
    <p>第二个数据:{{fMessage}}</p>
  </div>
</template>
  
<script>
export default {
  // 使用参数props,数组中的字符串列表指的是父组件中传递的自定义属性名
  props: ['fData', 'fMessage'],
  data () {
    return {
  
    };
  }
}
</script>

使用vue-router方式传参/父传子/子传父/兄弟间

因为路由是项目中跳转的基本使用方法之一,且具备普适性,所以路由传参时候所有情况的传递,当然前提是使用路由的方式进行跳转

vue-router网址:https://router.vuejs.org

路由传递参数有几种办法:

  • 查询字符串
  • 路由路径传参

路径传参

路由字典设置

const User = {
  template: '<div>User</div>'
}

const router = new VueRouter({
  routes: [
    // 动态路径参数 以冒号开头
    { path: '/user/:id', component: User }
  ]
  // 或者使用多个参数设置
  routes: [
    // 动态路径参数 以冒号开头
    { path: '/user/:username/pwd/:pwd', component: User }
  ]
})

路由参数传参的方法是再路由上做文章,路由上定义了传递参数

使用路由传递参数

// 路由字典
routes: [
  // 动态路径参数 以冒号开头
  { path: '/user/:username', component: User }
]
// 使用方法
this.$router.push('/user/evan');
// 获取传递的参数
let obj=this.$route.params;
// 打印evan
console.log(obj.username);
// 或者使用多个参数设置
  routes: [
    // 动态路径参数 以冒号开头
    { path: '/user/:username/pwd/:pwd', component: User }
  ]
// 上述的路由字典中使用路由传参可以同时传递多个参数
// 使用方法
this.$router.push('/user/evan/pwd/evan123');
// 获取传递的参数
let obj=this.$route.params;
// 打印evan
console.log('uname:'+obj.username+'pwd:'+obj.pwd);

以查询字符串的方式在路由中传递参数

路由跳转的方式原理是使用了一个页面栈;页面栈是按照页面显示的先后顺序向栈中添加页面,规则是先进后出;显示的页面一定是处于最上层的页面
页面栈的操作方法有以下几种:

  • router.push
  • router.replace
  • router.go
  • router.back
  • router.forward

push方法是先页面栈中添加一个新的页面;replace表示的是替换一个页面;go表示是跳转到指定的页面;back表示返回,后退一步;forward表示的是导航前进一步;

router.push

这个是在原有的页面栈上添加一新的页面;与标签<router-link :to>使用的原理是一致的;使用的方法如下所示:

// 字符串,看情况使用的是history方式还是hash方式
router.push('home')
router.push('/home')
// 对象,对应的是路由字典中的对象参数,有patH或者是name
router.push({ path: 'home' })
// 命名的路由,对应路由字典中的参数name
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:

const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user

router.replace

router.replace(location, onComplete?, onAbort?)

不会添加栈页面,但是会用新的页面替换掉当前展示的页面,当前页面在栈中将不存在,与标签<router-link :to="..." replace>作用原理一致

router.go(n)

这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,n可以是正数表示前进,可以为负数表示后退,前进后退几步就看n的值是多少了

router.back()和 router.forward()

表示前进后退,步距是1,表示前进/后退1步

路由对象属性

路由对象的属性例如params或者query,可以配合路由进行路由传参,常用的路由属性:

  • $route.path 字符串,对应当前路由的路径,总是解析为绝对路径,如 “/foo/bar”
  • $route.params 一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。
  • $route.query 一个 key/value 对象,表示 URL 查询参数。
  • $route.hash 当前路由的 hash 值 (带 #) ,如果没有 hash 值,则为空字符串
  • $route.fullPath 完成解析后的 URL,包含查询参数和 hash 的完整路径。
  • $route.matched 一个数组,包含当前路由的所有嵌套路径片段的路由记录 。

建议使用这些路由跳转方法的时候使用传递对象的方式进行使用,因为将路径和参数分开的方法在实际操作中确实存在,但是在API中没有相应的介绍,保险起见传递跳转的时候使用对象形式

使用vueX进行数据共享传参

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。我们暂时不详细了解;目前只需要值到,在脚手架项目中的热河模块地址都可以访问vueX获取数据和传递数据

vueX官方网址

首先是引入vueX
import Vue from 'vue'
import App from './App'
// 这里是导入vueX
import Vuex from 'vuex'
// 这里是还是导入vueX,只是是其中的store
import store from './vuex/store'
// 挂载到vue上
Vue.use(Vuex)

// 这里是跟组件所在,注意的是这里使用store参数
new Vue({
  el: '#app',
  store,
  render: h => h(App)
})

数据源State

这里是vueX存储数据的地方,读取属性的最简单方法就是在组件的计算属性中返回vuex中的数据;
但在组件中需要使用vuex的数据或者方法的时候可以使用map方法将vuex中的数据或者方法解析到本组件,然后再本组件中使用。
创建脚手架项目的时候一般都会有一个选项是否使用vueX,选择后生成的vue项目的项目结构中会出现一个store的文件夹,该文件夹下面会生成一个index.js文件,该文件就是公共的vuex文件

index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  // 数据存储区域
  state: {
    sount:0
  },
  // 数据修改区域
  mutations: {
  },
  // 数据操作区域
  actions: {
  },
  // 模块
  modules: {
  }
})

因为再mian.js中将store对象引入并加载到了vue的跟组件中,所以使用的时候可以使用$store.state.属性名进行使用vux中定义的数据了

获取数据方法封装getters

这里存储的是获取vuex的数据的方法

 const store = new Vuex.Store({
   //数据
   state:{
      count:5  5
   },
   getters:{
     定义使用getter的方法
      newCount:state => state.count * 3
   }
 });

使用getter的方法如下所示

// 使用getterd的方法,使用组件的计算属性获取vux中的get方法,也可以在其他的地方使用这种方式获取,注意的是并不会触发该方法,触发需要自信使用;(计算属性会自信触发,其他不会触发的地方需要自信触发)
export default {
  computed: {
      newCount(){
          return this.$store.getters.newCount;
      }
  } 
};  

上述的这种获取vuex的方法的方式也适用钰其他的方法与属性值,只需要更换相应的对象即可,例如return this.$store.state.count;获取state中的count属性

对数据进行修改的方法封装mutations

这里存储的是对数据进行修改的方法

/**
 * 放置的是我们操作state对象属性的方法
 */
const mutations = {
    AddCount(state, n = 0) {
        return (state.count += n)
    },
    ReduceCount(state, n = 0) {
        return (state.count -= n)
    }
}
// 因为是直接导出的store对象,mutations包含在对象中一起挂载在vue跟组件下所以直接可以使用不需要专门去进行封装
// export default new Vuex.Store({
//     state,
//     mutations
// })

数据操作的方法封装actions

这里存贮的是对数据进行操作的方法

在组件中对封装的方法进行使用

<template>
  <div class="hello">
    <h2>{{$store.state.count}}</h2>
    <div>
      <button @click="AddClick(5)">增加</button>
      <button @click="ReduceClick(5)">减少</button>
    </div>
  </div>
</template>
methods: {
    handleAddClick(n){
      // 使用方法是直接使用挂载在vue跟组件下的store对象使用commit方法激活对应字符串方法名的方法,并可以传递参数
      this.$store.commit('AddCount',n);
    },
    handleReduceClick(n){
      this.$store.commit('ReduceCount',n);
    }
  }

这里注意下:
这里使用vuex的方式是使用$storecommmit方法分发到mutations然后触发对应的事件,这种分发的方式以上四个模块使用的方法都不一样:

  • commit 分发mutation
  • dispatch 分发action
  • replaceState对应 store
this.$store.commit('ReduceCount',n);
this.$store.dispatch('ReduceCoun1t',n);
.......

vueX模块化

使用的方式是和模块化一样的,建立模块1,模块2,模块1模块2中包含一个vuex文件该有的或者说是用到的组件对象,然后将该文件导出为一个对象,在主vuex文件中引入,然后再modules对象模块中将其作为属性对象封装景区;跟组件照常挂载主要的store对象

// 模块A
export default {
    state: {
        text: 'moduleA'
    },
    getters: {},
    mutations: {},
    actions: {}
}
// 模块B
export default {
    state: {
        text: 'moduleB'
    },
    getters: {},
    mutations: {},
    actions: {}
}

主要的store进行封装

export default new Vuex.Store({
    actions,
    getters,
    state,
    mutations,
    modules: {
        moduleA,
        moduleB
    }
})

官方提供的正常使用vux中的数据方法的方式

官方提供了一系列的组件解绑辅助对象,分别对应的vuex中的几个对象进行解绑

  • mapState
  • mapGetters
  • mapActions
  • mapMutations

使用方法

import { mapState } from 'vuex'
import { mapGetters } from 'vuex'
import { mapActions } from 'vuex'
import { mapMutations } from 'vuex'

使用如上方式,解绑出vuex中的四个对象,然后在当前组件中的一些需要的地方(位置符合要求,随便用户自行放置)配合打散语法将其打散并获取相应的方法:

// 例如在本组件的methods中
methods: {
		...mapGetters({
      // 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
      doneCount: 'doneTodosCount'
    }),
    // 或者直接这样。。。。
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ]),
    ...mapActions([
      'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
      // `mapActions` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    })
	}

总结

通过上述两种方法都可以使用vuex的方法与数据,所以这时要传递参数就很简单了,直接将数据放在vuex中,各个组件都可以调用gettersMutations方法进行数据的获取与操作