vue组件中props与data的结合使用方式

Octavia ·
更新时间:2024-11-14
· 488 次阅读

目录

组件中props与data的结合使用

子组件中data从props中动态更新数据

组件中props与data的结合使用

如前所述(vue组件属性(props)及私有数据data),vue组件中,props是组件公有属性,对外;data是组件的私有数据,对内。正因为props对外,由外部赋值,因此在组件内部,是只读的,即组件内部不适宜去改变这些元素的值。当然,改也可以改,但运行时刻会有告警。

正如我们写一个函数,对于传入的参数,我们一般是只读对待的,极少会去修改它的值一样。当然,这只是一种编码约定,你硬是要改,也无话可说,改了就改了。

同时,props是在开发时,预先设置好,传给组件的。在运行过程中,这些设置是一锤子买卖,以后就不起作用了。假如我们想调用该组件的一个方法,而该方法又依赖于props,问题就出来了:props是旧的。

这个时候,组件开发过程中,应该将props与data相结合。在组件内部,应该依赖于data,而data的初始值来自于props:

组件

export default {   props: {     id: { default: 0 }   },   data () {     return {       myId: this.id //用props的id初始化     }   },   methods: {     pop (id) { // 供外部调用       this.myId = id       alert(this.id)       alert(this.myId)     }   } }

调用组件:

<template>   <div>       <!-- 将变量id的值赋给组件的id属性,一锤子买卖 -->     <Pop ref="popWin" :id="id" />   </div> </template> <script> import Pop from './_pop.vue' export default {   components: {     Pop   },   data () {     return {       id: 0     }   },   methods: {     showDetail (id) {//页面的id也是由外部传进来的,事先不可能知道       this.id = id //保存了id,但影响不了组件Pop       this.$refs.popWin.pop(id) // 调用Pop组件的方法,并传递id     }   } } </script>

2021.07.22补充:

还有另一种机制,就是子组件监控props里的属性,当该属性变化时,就触发,处理相应的逻辑。

流程是这样:父组件或页面,将通过变量传值给子组件的props,子组件监控props。如果父组件在运行过程中,想动态更改这个属性,那就更改自己的变量。由于有监控(watch)机制存在,子组件被触发。

父组件或页面

<template>    <div><Report ref="report1" :id="myId"/></div> </template> <script> import Report from './_report.vue' export default {   components: {     Report   },   data () {     return {       myId: 0,     }   },   methods: {     init (id) {       this.myId = id //改变id值     }   } } </script>

组件_report.vue:

<template>     <div>我是子组件,名曰谢康乐,一箭射双鹤</div> </template> <script> export default{   watch: {     id (val) {       alert('id变了,我是不是应该做点什么?')     }   } } </script>

2021.07.23补充:

监视比父组件调用子组件方法控制更为合理,耦合程度更低。你值得拥有。

子组件中data从props中动态更新数据

考虑这样一种情况,Vue 的父组件根据网络请求获取到数据后,动态更新到子组件的 props 上,

// 父组件 <template>   <div class="parent">     <chart :info='info'/>   </div> </template> // 子组件 <template> <div class="child"> <ul> <!-- 此处 info 来自 props --> <li v-for="i in info" :key='i'>{{i}}</li> </ul> </div> </template> <script> export default { props:['info'], data () {}, } </script>

走到这一步,都很顺利,子组件能响应父组件的数据,进行动态更新。

但是,

实际项目中,往往要对子组件上接收到的数据进行操作处理,然后才能通过 data 渲染到页面上,这时就会发现,父组件上的数据变化,子组件不再能响应并及时更新了。

在子组件上把数据直接渲染到模型上即可。

// 子组件 <template> <div class="child"> <ul> <!-- 此处 list 来自 data --> <li v-for="i in list" :key='i'>{{i}}</li> </ul> </div> </template> <script> export default { props:['info'], data () { return { list:[], } }, mounted(){ this.list = this.info.map(i => '0_'+i) }, } </script>

原因很简单,从 props 的 info 传递给 data 的 list ,只有一次操作,就是在 mounted 中,往后即使 props 的 info 发生了变化,data 也接收不到。

问题在于数据在传递过程中不能及时关联,针对这一点,可以用 watch 来进行跟踪,如下即可

// 子组件 <template> <div class="child"> <ul> <!-- 此处list 来自 data --> <li v-for="i in list" :key='i'>{{i}}</li> </ul> </div> </template> <script> export default { props:['info'], data () { return { list:[], } }, mounted(){ // this.list = this.info.map(i => '0_'+i) }, watch: { info() { this.list = this.info.map(i => '0_'+i) } } } </script>

后记:

以上操作其实也是走了一些弯路,对于这种 通过对 props 数据操作再赋值给 子组件 data ,导致子组件 data 不能根据 父组件传值变化而及时更新数据的情况。直接用计算属性  computed  : list 

// 子组件 <template> <div class="child"> <ul> <!-- 此处comp 来自 computed --> <li v-for="i in comp" :key='i'>{{i}}</li> </ul> </div> </template> <script> export default { props:['info'], computed: { comp (){ return this.info.map(i => '0_'+i) } }, } </script>

如上即可

以上为个人经验,希望能给大家一个参考,也希望大家多多支持软件开发网。



data VUE

需要 登录 后方可回复, 如果你还没有账号请 注册新账号