Vue messaging

1. [Vue warn]: Avoid mutating a prop directly since the value will be overwritten问题

2. Get the parent component data, modify it in the child component, and then pass it to the parent component.

Vue clicks on the child component to perform the +1 operation.

2.1. Method 1. Create data or computed value instead of modifying prop value (official recommendation)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">

  <script src="../vue.js"></script>
</head>

<body>
  
  <!-- 子组件模板 -->
  <template id="cpn1">
    <div>
      <h2 @click='c_click'>子组件:{
   
   {c_counter}}</h2>
    </div>
  </template>

  <!-- 父组件模板 -->
  <div id="app">
    <cpn :c_counter='counter' @itemclick='getcpnclick'></cpn> <!--自动从子组件事件传过来-->
    <h2>父组件:{
   
   {counter}}</h2>
  </div>

  <script>

    const cpn = {
     
     
      template: '#cpn1',
      props:{
     
     
        c_counter: {
     
     
          type: Number,
          default: 111
        }
      },
      data(){
     
     
        return {
     
     
          d_c_counter: this.c_counter,
        }
      },
      methods: {
     
     
        c_click(){
     
     
          // let c_mid_counter = this.c_counter+1;// 不能直接修改c_counter,不知道为什么。修改prop数据就会报错??
          this.d_c_counter++;
          this.$emit('itemclick', this.d_c_counter) // 子组件发射事件给父组件
        }
      }
    }

    new Vue({
     
     
      el: "#app",
      components: {
     
     
        cpn // 全局组件
      },
      data: {
     
     
        counter: 0
      },
      methods: {
     
     
        getcpnclick(c){
     
     
          this.counter = c;
        }
      }
    });
  </script>
</body>

</html>

2.2. Method two. Use the intermediate value (I thought about it myself, not the official recommended method)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">

  <script src="../vue.js"></script>
</head>

<body>
  
  <!-- 子组件模板 -->
  <template id="cpn1">
    <div>
      <h2 @click='c_click'>子组件:{
   
   {c_counter}}</h2>
    </div>
  </template>

  <!-- 父组件模板 -->
  <div id="app">
    <cpn :c_counter='counter' @itemclick='getcpnclick'></cpn> <!--自动从子组件事件传过来-->
    <h2>父组件:{
   
   {counter}}</h2>
  </div>

  <script>

    const cpn = {
     
     
      template: '#cpn1',
      props:{
     
     
        c_counter: {
     
     
          type: Number,
          default: 111
        }
      },
      methods: {
     
     
        c_click(){
     
     
          let c_mid_counter = this.c_counter+1; // 不能直接修改c_counter,不知道为什么。修改prop数据就会报错??
          this.$emit('itemclick', c_mid_counter) // 子组件发射事件给父组件
        }
      }
    }

    new Vue({
     
     
      el: "#app",
      components: {
     
     
        cpn // 全局组件
      },
      data: {
     
     
        counter: 0
      },
      methods: {
     
     
        getcpnclick(c){
     
     
          this.counter = c;
        }
      }
    });
  </script>
</body>

</html>

2.3. Method 3. Replacing events to achieve similar effects

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">

  <script src="../vue.js"></script>
</head>

<body>
  
  <!-- 子组件模板 -->
  <template id="cpn1">
    <div>
      <h2>子组件:{
   
   {c_counter}}</h2>
      <input :value='c_counter' @input='getinput'>
    </div>
  </template>

  <!-- 父组件模板 -->
  <div id="app">
    <cpn :c_counter='counter' @iteminput='getcpninput'></cpn> <!--自动从子组件事件传过来-->
    <h2>父组件:{
   
   {counter}}</h2>
  </div>

  <script>

    const cpn = {
     
     
      template: '#cpn1',
      props:{
     
     
        c_counter: {
     
     
          type: Number,
          default: 111
        }
      },
      data(){
     
     
        return {
     
     
          d_c_counter: this.c_counter,
        }
      },
      methods: {
     
     
        getinput(event){
     
     
          console.log(this.d_c_counter+'---'+event)
          this.d_c_counter = event.target.value
          this.$emit('iteminput', this.d_c_counter);
        }
      }
    }

    new Vue({
     
     
      el: "#app",
      components: {
     
     
        cpn // 全局组件
      },
      data: {
     
     
        counter: 0
      },
      methods: {
     
     
        getcpninput(val){
     
      // 默认为String类型,做一下转换
          this.counter = parseFloat(val);
        }
      }
    });
  </script>
</body>

</html>

Logic: The modified value in the child component is passed to the parent component. Since the value in the parent component is obtained through props binding, the value in the child component is automatically modified.

Method One Two Synchronize changes
Method Three
Sync changes 2

2.4. Answer the above question, why is it not allowed to modify the value in props?

According to the vue mechanism, props are used to obtain the data of the parent component when it is officially set, so it is inappropriate for us to modify the child component.


Zhuang Zhouxiao dreams of butterflies, and Wang Dichun cares for the cuckoo. ——Li Shangyin

Guess you like

Origin blog.csdn.net/weixin_37627774/article/details/108104781