NO17--vue父子组件间单向数据流的解决办法

在上一篇中讲解了父子组件之间是如何传值的,如果子组件需要改变传过来的数据供自己使用,或者想在子组件中改变传过来的数据并同步到父组件,那么直接改肯定是不行的,如果你这么做了,Vue 会在控制台给出警告。

对应这两种情况,解决方式如下:

先创建项目并运行

vue init webpack-simple template
cd template
npm i
npm run dev

一、 子组件需要改变传过来的数据供自己使用
1. 定义一个局部变量,并用 props 的值来初始化它

在 App.vue 中

<template>
    <div class="hello">
        <h3>我是 App 父组件</h3>
        <h4>访问自己的数据:{{msg}},{{name}},{{user.id}}</h4>
        <hr>
        <!-- 1. 在调用子组件时,绑定想要获取的父组件中的数据 -->
        <Hello :message="msg"></Hello>
    </div>
</template>

<script>
// 引入 Hello 组件
import Hello from ‘./assets/components/Hello.vue‘
export default {
  data(){
    return {
      msg:‘父组件‘,
      name:‘tom‘,
      age:‘22‘,
      user:{
        id:1234,
        userName:‘Jack‘
      }
    }
  },
  // 注册 Hello 组件
  components:{
    Hello
  }
}
</script>

在 Hello.vue 中

<template>
    <div class="hello">
        <h3>我是 hello 子组件</h3>
        <!-- 在页面中直接渲染即可 -->
        <h4>访问父组件中的数据: {{msg}}</h4>
        <button @click="change">改变父组件的数据</button>
    </div>
</template>

<script>
export default {
    // 2. 在子组件内部,使用 props 选项声明获取的数据,即接收来自父组件中的数据
    props:[‘message‘],
    data(){
        return {
            // 定义一个局部变量,并用 props 的值来初始化它
            msg:this.message
        }
    },
    methods:{
        // 定义一个方法,来触发改变父组件的数据
        change(){
            this.msg = ‘我改变了父组件的数据‘
        }
    }
}
</script>

效果图:

子组件改变父组件的数据

2. 定义一个计算属性,处理 prop 的值并返回:

在 Hello.vue 中改动

<script>
export default {
    // 2. 在子组件内部,使用 props 选项声明获取的数据,即接收来自父组件中的数据
    props:[‘message‘],
    data(){
        return {
            // 定义一个局部变量,并用 props 的值来初始化它
            msg:this.message
        }
    },
    computed:{
        // 定义一个方法,来触发改变父组件的数据
        change(){
            return this.msg = ‘我改变了父组件的数据‘
        }
    }
}
</script>

当页面渲染成功自动完成计算

二、子组件中改变传过来的数据并同步到父组件
1. 使用 sync 修饰符,它会被扩展为一个自动更新父组件属性的 v-on 监听器

在 App.vue 中把 template 的内容更改为

<template>
    <div class="hello">
        <h3>我是 App 父组件</h3>
        <h4>访问自己的数据:{{msg}}</h4>
        <hr>
        <!-- 1. 在调用子组件时,绑定想要获取的父组件中的数据 -->
        <!-- .sync 会被扩展为一个自动更新父组件属性的 v-on 监听器 -->
        <Hello :message.sync="msg"></Hello>
    </div>
</template>

在 Hello.vue 中更改为

<template>
    <div class="hello">
        <h3>我是 hello 子组件</h3>
        <!-- 在页面中直接渲染即可 -->
        <h4>访问父组件中的数据: {{message}}</h4>
        <button @click="change">改变父组件的数据</button>
    </div>
</template>

<script>
export default {
    // 2. 在子组件内部,使用 props 选项声明获取的数据,即接收来自父组件中的数据
    props:[‘message‘],
    methods:{
        change(){
            // 使用 .sync 时,需要显式的触发一个更新事件
            // update 为固定写法,后面跟将要被改变的数据对象,接着写替换的数据
            this.$emit(‘update:message‘,‘我改变了父组件的数据‘)
        }
    }
}
</script>

效果为:

2. 可以将父组件中的数据包装成对象或数组,然后在子组件中修改对象的属性

在 App.vue 中

<template>
    <div class="hello">
        <h3>我是 App 父组件</h3>
        <h4>访问自己的数据:{{user.userName}}</h4>
        <hr>
        <!-- 2. 在调用子组件时,绑定想要获取的父组件中的数据 -->
        <Hello :user="user"></Hello>
    </div>
</template>

<script>
// 引入 Hello 组件
import Hello from ‘./assets/components/Hello.vue‘
export default {
  data(){
    return {
      // 1. 在父组件中把数据写成对象的形式
      user:{
        id:1234,
        userName:‘Jack‘
      }
    }
  },
  // 注册 Hello 组件
  components:{
    Hello
  }
}
</script>

在 Hello.vue 中

<template>
    <div class="hello">
        <h3>我是 hello 子组件</h3>
        <!-- 5. 在页面中直接渲染即可 -->
        <h4>访问父组件中的数据: {{user.userName}}</h4>
        <button @click="change">改变父组件的数据</button>
    </div>
</template>

<script>
export default {
    // 3. 在子组件内部,使用 props 选项声明获取的数据,即接收来自父组件中的数据
    props:[‘message‘,‘user‘],
    methods:{
        // 4.直接修改 user 对象中的数据
        change(){
            this.user.userName = ‘Tom‘
        }
    }
}
</script>

效果如下:

我们是不允许直接修改父组件传过来的数据或对象的,而这种方法更改的是对象中的属性,因为对象是引用类型,指向同一内存空间,所以可以实现此效果。推荐使用该方式

原文地址:https://www.cnblogs.com/cb-bin/p/9085459.html

时间: 2024-08-30 13:31:39

NO17--vue父子组件间单向数据流的解决办法的相关文章

第四节:Vue表单标签和组件的基本用法,父子组件间的通信

vue表单标签和组件的基本用法,父子组件间的通信,直接看例子吧. <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script src="vue.js"></script> </head> <body> <div id="app"&

Vue入门七、父子组件间通讯

一.父子组件通讯 父传子:1.父用子的时候通过属性传递2.子要声明props:['属性名']接收3.子组件template中直接用 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script type="

vue的父子组件间传值以及非父子间传值

Vue组件间的传值方式: 父传子 子传父 非父子间传值 1.首先父组件传值给子组件,使用bind绑定属性,然后在子组件用props接收属性值. //父组件 <template> <input type="text" /> <br/> <child :inputValue="inputValue"></child> </template> <script> import child f

【转】vue父子组件之间的通信

vue父子组件之间的通信 在vue组件通信中其中最常见通信方式就是父子组件之中的通性,而父子组件的设定方式在不同情况下又各有不同.最常见的就是父组件为控制组件子组件为视图组件.父组件传递数据给子组件使用,遇到业务逻辑操作时子组件触发父组件的自定义事件.无论哪种组织方式父子组件的通信方式都是大同小异. 父组件到子组件通讯 父组件到子组件的通讯主要为:子组件接受使用父组件的数据,这里的数据包括属性和方法(String,Number,Boolean,Object, Array ,Function).v

非父子组件间传值(一)

非父子组件间传值有两种方法,一种是vuex共享数据,另一种是发布订阅模式/观察者模式/总线/Bus.这篇随笔主要总结总线机制的学习心得: 首先通过在Vue.prototype上挂载一个bus属性,指向vue实例:接下来在调用Vue或者创建组件时都会有bus属性. Vue.prototype.bus=new Vue() var Child={ props:['content'], data:function() { return {num:this.content} }, //因为vue是单项数据

vue 父子组件传值

父组件通过属性向子组件传值 单向数据流,父组件可以向子组件传值,子组件不能向父组件传值 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>vue</title> 6 </head> 7 <body> 8 <div id="app"> 9 <counter :coun

非父子组件间的传值

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>非父子组件间的传值(Bus/总线/发布订阅模式/观察者模式)</title> <script src="./vue.js"></script> </head> <body> <div

父子组件间的数据传递

vue当中有个单向数据流的概念,也就是:父组件可以向子组件传递/修改参数(通过属性的方式传),但子组件不可以反过来修改父组件传递过来的参数!(因为怕子组件改了父组件引用类型的数据,可能会影响到其他组件).那怎样解决这个问题?可以复制给子组件自己的变量,然后子组件修改自己的变量啊!这是父组件向子组件传递数据: <!DOCTYPE html> <html> <head> <title></title> <meta http-equiv=&quo

父子组件间的传值

父子组件间通信 父组件-->子组件 1.父组件通过给子组件添加属性给子组件传值,子组件通过props来接受. 2但是要在属性前加“:”,即使用v-bind指令,才能使属性值是js代码,不然就是字符串. 3.单项输出流.即子组件不允许修改父组件传递的值,只能使用,不能修改. 父组件通过属性向子组件传值时,如果传递的是引用型的值,这时候子组件对父组件传递的值进行修改可能会影响其他子组件对这个引用类型值的使用. 解决办法:子组件在data项中新赋值父组件的变量,操作新的变量即可. 子组件-->父组件