v-model深度使用和sync修饰符

120 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情

一.element-ui组件

       <div class="root">
  <b-table :list="students">
    <t-table-column prop="no" lable="学号"></t-table-column>
    <t-table-column prop="name" lable="姓名"></t-table-column>
    <t-table-column prop="sex" lable="性别"></t-table-column>
    <t-table-column prop="age" lable="年龄"></t-table-column>
  </b-table>
  <hr />
  <b-table :list="cars">
    <t-table-column prop="no" lable="车牌"></t-table-column>
    <t-table-column prop="name" lable="车名"></t-table-column>
    <t-table-column prop="color" lable="颜色"></t-table-column>
    <t-table-column prop="price" lable="车价"></t-table-column>
  </b-table>
</div>
<script src="./js/vue.min.js"></script>
<script>
  Vue.config.productionTip = false;
  //   子组件1的子组件
  Vue.component("t-table-column", {
    template: `
      <th>{{lable}}</th>
      `,
    props: ["prop", "lable"],

    mounted() {
      // 将获取到的prop属性添加到父组件的cloumns里面
      this.$parent.columns.push(this.prop);
    },
  });
  //   子组件1

{{item[item2]}} item循环出来的是数组的每一个对象,item[item2]是对象里的值 对象可以写成obj.name,也可以写成obj["name"] image.png

  Vue.component("b-table", {
    template: `
    <table>
    <thead>
      <tr>
       <slot></slot>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(item,index) in list" :key="item.no">
        {{item}}
        <td v-for="(item2,index2) in columns" >
        {{item[item2]}}
        </td>
      </tr>
    </tbody>
  </table>
   ,
   
  // 表格内容
    props: ["list"],
    data() {
      return {
        //   表头
        columns: [],
      };
    },
  });
  new Vue({
    el: ".root",
    data: {
      students: [
        {
          no: 1001,
          name: "张三",
          sex: "男",
          age: 30,
        },
        {
          no: 1002,
          name: "李四",
          sex: "女",
          age: 31,
        },
        {
          no: 1003,
          name: "王五",
          sex: "男",
          age: 32,
        },
        {
          no: 1004,
          name: "周六",
          sex: "女",
          age: 33,
        },
      ],

      cars: [
        {
          no: "苏A1001",
          name: "宝马",
          color: "黑",
          price: 302,
        },
        {
          no: "苏A1002",
          name: "奔驰",
          color: "黄",
          price: 301,
        },
        {
          no: "苏A1003",
          name: "奥迪",
          color: "白",
          price: 302,
        },
        {
          no: "苏A1004",
          name: "法拉利",
          color: "红",
          price: 303,
        },
      ],
    },
  });
 </script>

image.png

image.png

二.v-model深度使用和sync修饰符

1.v-model深度使用 image.png

①正常情况下触发自定义事件

             <div class="root">
    {{yf}}--{{xz}}--{{kz}}
  <b-table :count="yf" label="衣服" @synca="yf=$event"></b-table>
  <b-table :count="xz" label="鞋子" @synca="xz=$event"></b-table>
  <b-table :count="kz" label="裤子" @synca="kz=$event"></b-table>
</div>
<script src="./js/vue.min.js"></script>
<script>
  Vue.config.productionTip = false;

  Vue.component("b-table", {
    template: `
    <div class="box_a">
    <div>{{label}}</div>
    <div>
      <button @click="mycount--">-</button>
      <span>{{mycount}}</span>
      <button @click="mycount++">+</button>
    </div>
  </div>
 `,
    props: ["count", "label"],
    data() {
      return {
          mycount:this.count
      };
    },
    
    watch: {
      mycount(val) {
        this.$emit("synca", val);
      },
    },
  });
  new Vue({
    el: ".root",
    data: {
      yf: 5,
      xz: 3,
      kz: 4,
    },
   
  });
</script>

②。使用v-model和input事件

      <div class="root">
    {{yf}}--{{xz}}--{{kz}}
      <!-- v-model指令就是对v-bind:value和v-on:input的封装-->
  <b-table v-model="yf" label="衣服" ></b-table>
  <b-table v-model="xz" label="鞋子" ></b-table>
  <b-table v-model="kz" label="裤子" ></b-table>
</div>
<script src="./js/vue.min.js"></script>
<script>
  Vue.config.productionTip = false;

  Vue.component("b-table", {
    template: `
    <div class="box_a">
    <div>{{label}}</div>
    <div>
      <button @click="mycount--">-</button>
      <span>{{mycount}}</span>
      <button @click="mycount++">+</button>
    </div>
  </div>
 `,
    props: ["value", "label"],
    data() {
      return {
          mycount:this.value
      };
    },
    
    watch: {
      mycount(val) {
        this.$emit("input", val);
      },
    },
  });
  new Vue({
    el: ".root",
    data: {
      yf: 5,
      xz: 3,
      kz: 4,
    },
   
  });
</script>

2.sync修饰符(sync修饰符可以实现子组件与父组件的双向绑定,并且可以实现子组件同步修改父组件的值。)

  一般情况下,想要实现父子组件间值的传递,通常使用的是 `props` 和自定义事   件 `$emit` 。 其中,父组件通过 `props` 将值传给子组件,子组件再通               过 `$emit` 将值传给父组  件,父组件通过事件[监听]获取子组件传过来的值。
<div class="root">
  {{yf}}--{{kz}}--{{xz}}
  <!-- <b-table :yf="yf" :kz="kz" :xz="xz" @update:yf="yf=$event" @update:kz="kz=$event" @update:xz="xz=$event"></b-table> -->

  <!-- 通过.sync修饰符,可以实现对多个属性的双向绑定 -->
  <b-table :yf.sync="yf" :kz.sync="kz" :xz.sync="xz"></b-table>
</div>
<script src="./js/vue.min.js"></script>
<script>
  Vue.config.productionTip = false;

  Vue.component("b-table", {
    template: `
   <div>
    <div class="box_a">
    <div>衣服:</div>
    <div>
      <button @click="myyf--">-</button>
      <span>{{myyf}}</span>
      <button @click="myyf++">+</button>
    </div>
  </div>

  <div class="box_a">
    <div>裤子:</div>
    <div>
      <button @click="mykz--">-</button>
      <span>{{mykz}}</span>
      <button @click="mykz++">+</button>
    </div>
  </div>

  <div class="box_a">
    <div>鞋子:</div>
    <div>
      <button @click="myxz--">-</button>
      <span>{{myxz}}</span>
      <button @click="myxz++">+</button>
    </div>
  </div>
    </div>
  `,
    props: ["yf", "xz", "kz"],
    data() {
      return {
        myyf: this.yf,
        mykz: this.kz,
        myxz: this.xz,
      };
    },

    //   触发自定义事件
    // 注意:这里事件名称命名方式是(update:属性名),然后在使用组件时就可以使用sync修饰符
    watch: {
      myyf(val) {
        this.$emit("update:yf", val);
      },
      mykz(val) {
        this.$emit("update:kz", val);
      },
      myxz(val) {
        this.$emit("update:xz", val);
      },
    },
  });
  new Vue({
    el: ".root",
    data: {
      yf: 5,
      xz: 3,
      kz: 4,
    },
  });
</script\
  。