vue-组件传值

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>

参考资料

vue-自定义事件


初心

我所有的文章都只是基于入门,初步的了解;是自己的知识体系梳理;
如果能帮助到有缘人,非常的荣幸,一切为了部落的崛起;
共勉
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容