精华内容
下载资源
问答
  • vue父组件子组件传值时,其父子prop之间形成单向下行绑定,反过来则不行,这样会防止子组件意外改变父组件,从而数据流变的难以理解;另外,每次父组件的数据发生更新时,子组件的都会刷新到最新的数据,但...

    最近在前端项目中遇到了父子组件传值的问题...

    vue中父组件向子组件传值时,其父子prop之间形成单向下行绑定,反过来则不行,这样会防止子组件意外改变父组件的值,从而数据流变的难以理解;另外,每次父组件的数据发生更新时,子组件的都会刷新到最新的数据,但不能改变子组件内部改变prop,这样浏览器就会发出警告

    解决办法来啦

    解决办法一、子组件想要修改时,需要通过$emit派发一个自定义事件,父组件收到后,由父组件进行修改

    子组件在computed中,

    computed:{
      currentActiveNames: {
       get() {
        return this.activeNames //父组件传给子组件的值
       },
       set(val) {
        // 改变由父组件控制
        this.$emit('on-change-activeNames', val)   
       }
      }
    }

    这样子组件告诉父组件自己修改了父组件传过来的值

    接下来呢,父组件中在引用子组件的地方添加@on-change-activeNames="changeActiveNames",另外,在methods方法中定义changeActiveNames用来接收父组件传过来的值

    methods:{
     changeActiveNames(val){
      console.log(‘子组件传过来的值’,val)
     }
    }

    解决办法二、

    注意在 JavaScript 中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态。

    大概意思就是:只要prop是对象或者数组,在子组件里面就可以修改从而改变父组件的值

    那具体要怎么写呢...

    1. 父组件中引入子组件 <child :par-obj="parObj"><child/>  child为子组件的名称(这里提一下 子组件名若为驼峰式,父组件引用的时候用‘-’连接 例如子组件名称为 childCom 引用时则用child-com)

    2. parObj为传给子组件的对象,在data中定义 重点来啦....在data中可以这样定义

    parObj:{ 
        parVal: 1
    },

    这样palVal才是你需要真正传给子组件的值

    3. 在子组件中

    props: {
      parObj: {
        type: Object,
        default: null
      }
    },

    拿到parObj后,子组件就可以肆意的改变parObj对象中的parVal啦

     

    展开全文
  • 下述组件传值指引用类型(数组或对象)传值。准备:单向数据流所有的 prop 都使得...额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的。这意味着你不应该在一个子组件内部改变 prop。如果...

    下述组件传值指引用类型(数组或对象)传值。

    准备:单向数据流

    所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。

    额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

    • 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。 定义一个本地的 data property 并将这个 prop 用作其初始值
    props: ['initialCounter'],
    data: function () {
     return {
     counter: this.initialCounter
      }
    }
    
    • 这个 prop 以一种原始的值传入且需要进行转换。 使用这个 prop 的值来定义一个计算属性
    props: ['size'],
    computed: {
     normalizedSize: function () {
     return this.size.trim().toLowerCase()
      }
    }
    
    注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。

    问题

    父子组件间,通过引用类型传值,为什么控制台不会告警(基本类型会告警)?Object.assign() 或者 JSON.parse(JSON.stringify()) 是在子组件中传引用值的标准处理方法吗?

    问题1

    父组件 App.vue

    <template>
      <div id="app">
        <child :initialValue="valueEmit">
        </child>
      </div>  
    </template>  
    <script>
    import childEmit from './components/child.vue'
    export default {
      data () {
        return {
          valueEmit: {dog: 1, cat: 2}
        }
      },
      components: {
        child
      }
    }        
    </script>        

    子组件 components/child.vue

    <template>
      <div class="child-container">
        <p> 
          <label for="cat">猫 :</label>
          <input id="cat" type="text" v-model="value.cat" />
        </p>
        <p>
          <label for="dog">狗 :</label>
          <input id="dog" type="text" v-model="value.dog" />
        </p>
      </div>
    </template>
    <script>
    export default {
      name: 'child',
      props: {
        initialValue: Object
      },
      data () {
        return {
          value = Object.assing({}, this.initialValue)
        }
      }
    }
    </script>

    子组件内的修改,父组件也会直接变更,且不告警!

    问题2

    修改子组件,子组件 components/child.vue

    export default {
      name: 'child',
      props: {
        initialValue: Object
      },
      data () {
        return {
          valueEmit: Object.assign({}, this.initialValue)
        }
      }
    }
    

    切断了引用,但是父组件变化不会触发子组件响应!(computed or watch 可以实现)

    问题3

    父组件 App.vue

    <template>
      <div id="app">
        <child
          :initialValue="valueEmit"
          @update-value-by-child="updateParentValue">
        </child>
      </div>  
    </template>  
    <script>
    import childEmit from './components/child.vue'
    export default {
      data () {
        return {
          valueEmit: {dog: 1, cat: 2}
        }
      },
      components: {
        child
      },
      methods: {
        updateParentValue(newValue) {
          this.valueEmit = newValue
        }
      }
    }        
    </script>        
    

    子组件 components/child.vue

    <template>
      <div class="child-container">
        <p> 
          <label for="cat">猫 :</label>
          <input id="cat" type="text" v-model="valueEmit.cat"
            @input="$emit('update-value-by-child', valueEmit)" />
        </p>
        <p>
          <label for="dog">狗 :</label>
          <input id="dog" type="text" v-model="valueEmit.dog" />
        </p>
      </div>
    </template>
    <script>
    export default {
      name: 'child',
      props: {
        initialValue: Object
      },
      data() {
        return {
          valueEmit: Object.assign({}, this.initialValue)
        }
      }
    }
    </script>

    现象:

    1. 首先对“dog”进行修改,父组件的 initialValue 并未发生改变
    2. 对“cat”进行修改,父组件的 initialValue 发生变化(dog、cat都被修改了)
    3. 此时,在对“dog”修改,父组件的 initialValue 发生变化!

    总结

    1. 纯展示 直接使用父组件属性,不会有副作用!
    <template>
     <div>
        {{parentObj.value}}
     </div>
    </template>
    <script>
     export default {
      name: 'child',
      props: {
        parentObj: Object
      }
     }
    </script>

    2. 只子组件内部修改,父组件不会修改(即,父组件只做初始化)
    子组件 data 中声明新的数据,通过 Object.assign() 或者 JSON.parse(JSON.stringify()) 切断引用即可。

    <template>
    	<div>
        <input type="text" v-model="childObj.value">
      </div>
    </template>
    <script>
    	export default {
        name: 'child',
        props: {
          parentObj: Object
        },
        data () {
          return {
            childObj: Object.assign({}, this.parentObj)
          }
        }
      }
    </script>

    3. 父子组件都会修改 通过 computed 或者 watch 进行处理

    <template>
    	<div>
        <input type="text" v-model="childObj.value">
      </div>
    </template>
    <script>
    	export default {
        name: 'child',
        props: {
          parentObj: Object
        },
        computed: {
          childObj () {
            return Object.assign({}, this.parentObj)
          }
        }
      }
    </script>

    或者 watch 方式

    export default {
      name: 'child',
      props: {
        parentObj: Object
      },
      data () {
        return {
          childObj: {}
        }
      },
      watch: {
        parentObj: {
          handler (val, oldVal) {
            if (val) {
              this.childObj = Object.assign({}, this.parentObj)
            }
          },
          deep: true,
          immediate: true
        }
      }
    }
    

    关于 watch 和 computed 区别: https://ligang.blog.csdn.net/article/details/94590314

    欢迎关注 「 Super 前端 」微信公众号

    211b8659040254c8db7cc2ad89a1f8c8.png
    版权声明: 本文原创自我的博客:李刚的学习专栏
    展开全文
  • 每次父级组件发生更新时,子组件中所有的props都将会刷新为最新的。 不能在子组件内部改变props,否则会导致浏览器控制台发出警告 子组件要修改时,用$emit调用自定义事件,父组件接到后由父组件修改 改变props的...

    1. props验证与默认值

    父props与子props是单向下行绑定:父级的props的值更新会流动到子组件中,但反过来却不行。
    避免子组件意外改变父级组件的状态,导致数据流混乱。
    每次父级组件发生更新时,子组件中所有的props都将会刷新为最新的值。
    不能在子组件内部改变props,否则会导致浏览器控制台发出警告
    子组件要修改时,用$emit调用自定义事件,父组件接到后由父组件修改
    改变props的常用例子:

    1. 这个用来传递一个初始值;这个组件接下来希望将其作为一个本地的数据来使用,要定义一个本地属性用做初始值、

        props:['initialCounter'],
        data:function(){
        return{
        counter:this.initialCounter
        	}
        }
      
    2. 这个以一种原始的值传入且需要进行转换,定义一个计算属性

        props:['size'],
        computed:{
        normalizedSize:function(){
        return this.size.trim().toLowerCase()
        	}
        }
      

    2. Vue的双向数据绑定

    1. 定义数据监听器Observer,能够对数据对象所有属性进行监听,数据有变动会获取新值并通知订阅者;
    2. 定义一个指令解析器Compile,对每个元素节点指令进行扫描,根据指令模板替换数据,以及绑定相应的更新函数;
    3. 实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图;

    Vue实现双向数据绑定主要采用:数据劫持结合“发布-订阅”模式的方式,通过Object.defineproperty()的set和get,在数据变动是发布消息给订阅者触发监听。

    Vue组件父传子,子传父,兄弟通信

    1. 父传子:(通过props实现)

    1. 在父组件中给子组件标签绑定一个属性,属性上挂载需要传递的值;

    2. 在子组件通过props[“自定义属性名”]来接受数据;

    以下是三种方法,没用vue写,引入vue.js文件,以下是HTML代码:

    <body>
        <div id="app">
            <child></child>
        </div>
        <script src="./vue.js"></script>//引入vue.js文件
        <script>
            const child = {
                // props: ['msg'], // 第一种方法
                inject: ['name', 'age', 'tel'],
                template:  `
                    <div>
                        这是子组件
                        {{msg}} {{name}} -- {{age}} -- {{tel}}
                    </div>
                `,
                data() {
                    return {
                        msg: ''
                    }
                },
                created() {
                    // console.log(this.$parent.msg) // 第二种方法 不建议过多的使用
                    // this.msg = this.$parent.msg
                    console.log(this.name, this.age, this.tel)
                }
            }
            Vue.component('child', child)
            new Vue({
                provide: { // 第三种方法 开发高阶组件时建议使用
                    name: "张三",
                    age: 16,
                    tel: 110
                },
                data:{
                    msg: '这是要传递给子组件的数据'
                }
            }).$mount('#app')
        </script>
    </body>
    
    

    2. 子传父:(通过$emit实现)

    1. 在父组件中给子组件标签绑定一个自定义事件,给这个事件挂载需要调用的方法;

    2. 在子组件的方法通过this.$emit(“自定义事件名”)来调用这个方法;

    以下是HTML代码:

    <body>
        <div id="app">
            <child @senddata="getData"></child>
        </div>
        <script src="./vue.js"></script>
        <script>
            const child = {
                template:  `
                    <div>
                        这是子组件
                        <button @click="sendData">点击传递数据给父组件</button>
                    </div>
                `,
                data() {
                    return {
                        msg: '这是要传递给父组件的数据'
                    }
                },
    
                methods: {
                    sendData() {
                        this.$emit('senddata', this.msg)
                    }
                }
            }
            Vue.component('child', child)
            new Vue({
                data:{
                    msg: ''
                },
                mounted() {
                    console.log(this.$children[0].msg)
                },
                methods: {
                    getData(data) {
                        console.log(data)
                    }
                }
            }).$mount('#app')
        </script>
    </body>
    

    3. 兄弟传参:两种方法

    1. 通过event bus实现

    创建一个空的vue实例eventBUS,作为公共的桥梁;在两个组件中引入创建的bus,组件A用BUS.$ emit(“自定义事件名”,要传递的值)发送数据;组件B用BUS.$on(“自定义事件名”,function(v){挂载从A穿过来的数据})来接受数据

    以下是HTML代码:

      <body>
        <div id="app">
          <child1></child1>
          <child2></child2>
        </div>
        <script src="./vue.js"></script>
        <script>
          const child1 = {
            template: `
                    <div>
                        这是子组件
                        <button @click="send">点击传递数据给父组件</button>
                    </div>
                `,
            data() {
              return {
                msg: "这是要传递给父组件的数据",
              };
            },
    
            methods: {
              send() {
                this.$bus.$emit("getdata", this.msg);
              },
            },
          };
    
          const child2 = {
            template: `
                    <div>
                        这是子组件
                        {{msg}}
                    </div>
                `,
            created() {
              // console.log(this)
              // var _this = this
              this.$bus.$on("getdata", (data) => {
                // console.log(this)
                this.msg = data;
              });
            },
            data() {
              return {
                msg: "",
              };
            },
          };
          Vue.component("child1", child1);
          Vue.component("child2", child2);
          var bus = new Vue();
          Vue.prototype.$bus = bus;
          new Vue({
            methods: {},
          }).$mount("#app");
        </script>
      </body>
    
    

    2. 使用vuex来传递

    vuex是一个状态管理工具,主要解决中大型复杂项目的数据共享数据

    1. State-存放Vuex store实例的状态对象,用于定义共享的数据。

    2. Action-动作,向store发出调用通知,执行异步操作。

    3. Mutations-修改器,它只用于修改state中定义的状态变量。

    4. getter-读取器,外部程序通过它获取变量的具体值,或者在取值前做一些计算(可以认为是store的计算属性)

    5. modules对state进行分类处理

    流程:dispatch到actions,actions是异步操作,从commit到mutations
    

    使用mutations再通过逻辑操作改变state,同步到组件,更新其数据状态。

    展开全文
  • 子组件修改从父组件传过来的同时响应更新 我们都知道子组件直接修改父组件传过来的的话控制台会报错,一般的做法是通过$emit(‘自定义属性名’,value)来实现修改 这里我们使用另外一种方法: 例如: 我们需要当点击...

    子组件修改从父组件传过来的值同时响应更新

    我们都知道子组件直接修改父组件传过来的值的话控制台会报错,一般的做法是通过$emit(‘自定义属性名’,value)来实现修改

    这里我们使用另外一种方法:

    例如:
    我们需要当点击某项操作后刷新表格,需要改变表格loading的状态,
    直接修改控制台肯定是会报错的
    

    这个时候我们就需要在父组件中在自定义属性名后加上.sync修饰符

    父组件
    <children :loading.sync="loading"></children>
    

    然后在子组件中加上update属性就可以实现父组件和子组件同时响应变化

    子组件
    this.$emit('update:loading',true)
    this.$api...
    .then(res => {
    	this.$emit('update:loading',false)  /成功调用接口后关闭loading
    })
    

    这样就修改成功了,同时控制台也不会报错,父组件和子组件也是同时更新的

    展开全文
  • vue父子组件传值

    2020-03-27 16:49:06
    (2)直接在父组件中通过$refs.change(params) 子组件方法(参数)将传给子组件 (正确用法) 当改变了props的时,子组件也会自动改变的 (1)在父组件改变props就可以了 (2)如果想组件刷新的话,可以在组件里面...
  • 就是子组件父组件中传过来的,当我在父组件改变子组件的时候,发现子组件的视图并没有发生更新,肿么办?** 思路: 只要强制更新视图就行了 解决方法一: 使用了 key-changing // 父组件 <div class=...
  • 1、iview table 自定义序号 将其对应的type设为 index 即可 ...复制代码2、父子组件传值,父组件调用子组件方法 场景:iview 中 封装一个modal 组件公共引用 父组件: // 引入组件 import orderMod...
  • 此时,父组件值更新,子组件不重新渲染,是因为,父组件值改变子组件不会走mounted的生命周期。 处理方案: 使用watch监听父组件传的值,当值改变的时候,进行对应操作。 2、推荐使用: 子组件中直接使用父组件传...
  • 但是当我刷新页面后高亮位置就变成了第一个 在头部组件里面控制导航高亮显示是checked,默认值是0,触发点击事件会重新赋值,跳转路由,当刷新页面,checked是0...这样会防止从子组件意外改变父级组件的状态,
  • 在头部组件里面控制导航菜单高亮显示是checkindex,默认值是0,触发点击事件contact时候会重新赋值,跳转路由,一旦刷新页面,这个checkindex的就是0,所以要把这个checkindex记录下来,时刻监听到变化;...
  • 1.vue-router用path,query传参,刷新页面数据消失的问题 1、要跳转的传参页:先将数组...3.vue中的props是单向绑定的,父组件的属性变化时会传递给子组件子组件内部不应改变props的,否则控制台会给出警告。 ...
  • 点击加入购物车按钮时(不同页面都有加入购物车按钮,它们之间是非子父组件之间关系),实时改变购物车数量的变化; 我们都知道,实现它可以使用vuex,但是页面刷新时,要保持vuex中的不会被还原成默认值,该...
  • 在项目中使用到json数据的次数还是很多的,小编奔到的第一个问题就是,父传子的json数据在子组件操作的时候,会顺带的改变父组件,试了好几个办法,最后是使用的JSON.parse(JSON.stringify('传的')做的处理,...
  • 【前端】vue遇到的坑

    2019-05-15 11:10:00
    2、在页面引入子组件时,子组件修改以后,想要重新刷新vue组件实现局部刷新)。 答:在引入子组件时,增加v-if属性,通过控制v-if的值,控制刷新。(v-if的值改变时,该组件会重新加载刷新) 实现方法如...
  • vue 数据流研究

    2021-02-01 23:15:29
    父组件子组件的数据交流方式: ...每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的。这意味着你不应该在一个子组件内部改变 prop。 <uni-popup-dialog type="success" cont
  • 父组件子组件传值 Prop 单向数据流 所有的 prop 都使得其父子 prop ...额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的。这意味着你不应该在一个子组件内部改变 prop。如果你这样做...
  • 改变子组件中的props中的,浏览器会发出警告在vue文档中的单向数据流也提到了 每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了...
  • vue中,父组件子组件传值, 并在子组件改变父组件,就会发出警告 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件...
  • prop 验证,和默认值

    2020-09-14 21:00:57
    额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。子组件想修改时,只能通过 $emit ...
  • qiankun 对于 props 的应用类似于 react 框架的父子组件通信,传入 data 数据供自组件使用,传入 fn 函数给子组件触发向上回调。 按照这个思路我们将主应用的 main.js 和子应用的 main.js 都改造一番(此改造会在...

空空如也

空空如也

1
收藏数 20
精华内容 8
关键字:

vue父组件值改变刷新子组件

vue 订阅