vue-组件传值

简介: 组件传值 不管 vue 还是react 亦或某个框架都是重点记得有篇文章写了 ,其实有些情况 完全可以用 js自带 dataset来传值哦

1.前言


组件传值 不管 vue 还是react 亦或某个框架都是重点

记得有篇文章写了 ,其实有些情况 完全可以用 js自带 dataset来传值哦


2. 引子


每个组件只能访问组件内部的 data数据源,要想访问其他组件就需要传值


<template>
  <div id="component_1">
    <h1>子组件内容</h1>
    <p>{{ hour | hourToSecond }}</p>
    <p>{{ componentHour }}小时</p>
    <p>{{ componentMsg }}</p>
    <button @click="changeHour">子组件修改</button>
  </div>
</template>
<script>
export default {
  props: ["hour", "msg"],
  data: function () {
    return {
      componentHour: 10,
    //组件的data函数中,可以使用props中的数据赋初始值
      componentMsg: this.msg,
    };
  },
  methods: {
      changeHour(){
              // 从父组件接收的传值是只读的,只能使用,不能修改。
                // 也就是说vue中数据的传递是单向的,只能自上而下传递,子组件不能修改父组件的数据,这样保证了组件数据的安全性。这叫做vue组件的单向数据流。
          console.log(">>>>",this.hour)
          this.componentHour++
      }
  }
};
</script>
<style lang="less" scoped>
</style>

子组件需要修改父组件数据可能是以下几个目的:

1.父组件传递的值不能直接使用,需要进一步加工:例如父组件传递的是一种单位(米),子组件需要显示另一种单位(千米),这种情况可以使用过滤器解决。

2.父组件传递的数据不能直接使用,需要进行一些计算,然后使用计算之后的结果,这种情况可以使用computed解决。

3.从父组件接受的值只是一个初始值,子组件需要把这个值赋值一份为自己所用。这种情况,需要在子组件的data定义一个变量取接受这个初始值,需要修改时就修改子组件data中的这个变量,而不是修改父组件传递的props。


3. 子组件 修改 父组件 数据


思考子组件 为什么不能修改  例如避免数据流混乱 难以管理

那父组件的数据 可以由父组件自己改变 ,咋改变呢写个函数 ,

好 那就在父组件写个 改变函数

这是父组件的 函数哦


changeCount(count) {
      this.totalPrice = this.price * count;
    },

接着分析 ,父组件可以通过 自己定义的修改函数 修改自己内部的数据

嘿嘿 如果 子组件可以调用 父组件的这个修改函数不就哦了

那问题来了怎么传 函数呢   js里面 函数本身也是一种数据类型,那就按照正常的传法传嘛

使用子组件的时候 绑定 属性 传值为函数的名字就可以

:cb="changeCount"


<p>单价:{{ price }}</p>
      <p>总价:{{ totalPrice }}</p>
      <Component-Emit :cb="changeCount"></Component-Emit>
      <hr />

子组件当然需要 接受下父组件的 传参嘛

props:["cb"] 少不了

子组件 内部 来个按钮 绑定自己的事件函数

在函数里面调用这个 cb就行了嘛 ,就当个正常的变量来使用


<template>
  <div id="component_2">
    <span>商品数量</span>
    <button @click="add">{{ count }} +</button>
  </div>
</template>
<script>
export default {
  props: ["cb"],
  data: function () {
    return {
        count:1,
    };
  },
  methods: {
      add(){
          this.count++
            // 方式一:使用父组件属性传值,得到函数  
           // 回调函
          this.cb(this.count)
      }
  },
};
</script>
<style scoped>
</style>

这里其实  属性应该加个验证更好


props:{
cb:{
type:Function
}
}

以上就是用原有的 思想解决问题

重点是把 函数当做变量传给子组件 这种方法 非常常用哦

vue 难道自己没有解决方案嘛 ,当然有 ,一起玩下


4. 事件触发


这里默认你已经了解 emit,

其实不了解也无妨 ,能看懂 哈哈

我们采用倒推的方法来玩吧

先看我们下边的代码

写法类比回调函数 就是上面的写法

@get-count 其实也能猜出来 就是 自定义一个事件  事件名是 get-count 类似 @click


<p>单价:{{ price }}</p>
      <p>总价:{{ totalPrice }}</p>
      <Component-Emit :cb="changeCount" @get-count="change"></Component-Emit>
      <hr />

change就是父组件的方法


methods:{
 change(a, b) {
      this.totalPrice = this.price * a + b;
    },

那子组件怎么写呢

核心是


this.$emit("get-count",this.count,"¥")

参数1是事件名 和 父组件传参 绑定的保持一致

后续 可以根据需要 写很多参数


<template>
  <div id="component_2">
    <span>商品数量</span>
    <button @click="add">{{ count }} +</button>
    <button @click="duce">{{ count }} +</button>
  </div>
</template>
<script>
export default {
  props: ["cb"],
  data: function () {
    return {
        count:1,
    };
  },
  methods: {
      add(){
          this.count++
            // 方式一:使用父组件属性传值,得到函数  
           // 回调函
          this.cb(this.count)
      },
      duce(){
        // 方式二: 发射事件:参数1:事件名 参数2及以上是要传递的参数  
          this.count --
          this.$emit("get-count",this.count,"¥")
      }
  },
};
</script>
<style scoped>
</style>



5.简单写个 分页案例


简单的分页组件


<template>
  <div id="pageContainer">
      <button @click="prevPage">上一页</button>
      <span>{{page}}</span>
      <button @click="nextPage">下一页</button>
  </div>
</template>
<script>
export default {
    props: ["page","cb"],
    methods:{
        prevPage(){
            console.log("----")
            this.cb("prev")
        },
        nextPage(){
    // $emit方法只能给父组件发射事件,父组件的父组件不能接收到这个事件。
            this.$emit("get-page","next")
        }
    }
}
</script>
<style scoped>
</style>

分页组件的使用


<p>父标签 获取到 page信息:{{ page }}</p>
      <Component-Page
        :page="page"
        :cb="changePage"
        @get-page="changePage"
      ></Component-Page>



6. 分页案例 v-model 实现


page.vue


<template>
  <div>
        <button @click="prevClick()">上一页</button>
        <span>当前页:{{value}}</span>
        <button @click="nextClick()">下一页</button>
  </div>
</template>
<script>
//  v-model =  v-bind:value  + v-on:input
export default {
    // 这里必须用 value
    // 因为 v-model 指令 绑定的是 value属性
    props:["value"],
    methods:{
        prevClick(){
            // 因为  v-model 绑定是   input事件
            // 所以 emit 发射/方法调用 的必须是  input事件
            this.$emit("input",this.value-1)
        },
        nextClick(){
            this.$emit("input",this.value+1)
        }
    }
}
</script>


App.vue使用


<Component-Model v-model="page1"></Component-Model>


本质 v-model


<!-- 本质 
    arguments[0] 子组件 $emit()方法的 事件参数
    -->
      <Component-Model :value="page1" @input="page1 = arguments[0]"
        >本质</Component-Model>




相关文章
|
22小时前
|
分布式计算 资源调度 JavaScript
程序员必知:vue项目创建和启动、ElementUI的安装和快速学习
程序员必知:vue项目创建和启动、ElementUI的安装和快速学习
|
22小时前
|
JavaScript
vue基础概念(1)
vue基础概念(1)
6 0
|
1天前
|
JavaScript
vue父子组件传值,父组件内容更新子组件内容不实时更新
vue父子组件传值,父组件内容更新子组件内容不实时更新
5 0
|
1天前
|
前端开发 JavaScript
vue+el-select下拉多选实现,全选,反选,清空功能源码
vue+el-select下拉多选实现,全选,反选,清空功能源码
4 0
|
1天前
|
JavaScript 前端开发
脚手架vue-cli自定义创建Vue项目,完整详细步骤!
脚手架vue-cli自定义创建Vue项目,完整详细步骤!
|
10月前
|
JavaScript
Vue的非父子组件之间传值
全局事件总线 一种组件间通信的方式,适用于任意组件间通信
|
9月前
|
缓存 JavaScript 前端开发
Vue Props、Slot、v-once、非父子组件间的传值....
Vue Props、Slot、v-once、非父子组件间的传值....
53 0
|
10月前
|
JavaScript
Vue中父子组件传值
先在⽗组件中给⼦组件的⾃定义属性绑定⼀个⽗组件的变量
|
10月前
|
JavaScript
vue 组件传值
vue 组件传值
58 0
|
10月前
|
JavaScript
vue父子组件传值
vue父子组件传值