七、列表循环渲染

1、v-for 循环中使用 :key= 提高渲染效率

  • 如下例,v-for的循环中使用:key={{item}},提高循环渲染的效率
    1. 点击按钮事件后,数据中的数组改变,页面重新渲染,v-for遍历的样式跟着改变;
    2. 为循环遍历的每一项都加上:key="item"(注:item是唯一的),为每一个经过循环渲染的元素做区分;
    3. Vue会在底层判断相同的 key 值的元素可以复用,不用重新渲染,从而提高了循环渲染的效率;
  • 如下例,v-for可以直接循环数字,<div v-for="item in 10">{{item}}</div>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <script>
    const app = Vue.createApp({
    data() {
    return {
    listArray: ["小明", "男", "19岁" ],
    listObject: {
    name: "小明",
    gender: "男",
    age: "19岁"
    }
    }
    },
    methods: {
    handleClick() {
    this.listArray.push("凡尔赛人")
    this.listObject.job = "student";//注:新版本Vue3才支持改变对象后添加展示内容,旧版本Vue3之前这么展示有问题;
    }
    },
    template: `
    <div>
    <div v-for="(item, index) in listArray" :key="index">{{index}}{{item}}</div>
    <div v-for="(value, key, index) in listObject">{{index}}-{{key}}{{value}}</div>
    <button @click="handleClick">哪里人?</button>
    <div v-for="item in 10">{{item}}</div>
    </div>
    `
    });
    const vm = app.mount("#root");
    </script>

    2、v-ifv-for不能在同一标签内使用 及 <template></template>占位符的使用

  • 若 template 如下,v-ifv-for在同一标签使用,v-if失效,页面仍会展示 gender: "男",这一项
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template: `
    <div>
    <div
    v-for="(value, key, index) in listObject"
    :key="index"
    v-if="key !== 'gender'"
    >
    {{index}}-{{key}}:{{value}}
    </div>
    </div>
    `
  • 若要使v-if恢复作用,不展示 gender: "男"这一项,需要在内层再加一层 div ,将v-if="key !== gender"从外层移到内层;
    • 此时,循环渲染出的内容都会多出一层
      的包裹;
    • 可在使用v-for的标签上将
      改为 占位符;
    • 循环渲染出的内容都会多出一层就会消失
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      template: `
      <div>
      <template
      v-for="(value, key, index) in listObject"
      :key="index"
      >
      <div v-if="key !== 'gender'">
      {{index}}-{{key}}:{{value}}
      </div>
      </template>
      </div>
      `

八、事件绑定

  1. vue中传递参数与事件的方法

  2. vue中点击一个按钮绑定多个事件方法

  3. 事件修饰符:stop、prevent、self、once、capture、passive

    • @click.self 修饰符,只点击本事件才触发
    • @click.once 修饰符,事件仅触发一次
    • @click.stop 修饰符,阻止事件冒泡
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      <body>
      <div id="root">
      </div>
      <script>
      const app = Vue.createApp({
      data() {
      return {
      counter: 0
      }
      },
      methods: {
      handleClick(num, event) {
      console.log(event.target, 0);
      this.counter += num;
      },
      handleClick1(num, event) {
      console.log("click1")
      },
      handleDivClick() {
      alert("div")
      }
      },
      template: `
      <div @click.self.once="handleDivClick">
      {{counter}}
      <button @click.stop="handleClick(2, $event), handleClick1()">button</button>
      </div>
      `
      });

      app.mount("#root");
      </script>
      </body>
  4. 按键修饰符:enter、tab、delete、esc、up、down、left、right……

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <body>
    <div id="root">
    </div>
    <script>
    const app = Vue.createApp({
    methods: {
    handelKeyDown() {
    console.log("keydown");
    },
    handelLeft() {
    console.log("left");
    }
    },
    template: `
    <div>
    <input @keydown.delete="handelKeyDown"/>
    </div>
    `
    });

    app.mount("#root");
    </script>
    </body>
  5. 鼠标修饰符:middle、left、right……

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <body>
    <div id="root">
    </div>
    <script>
    const app = Vue.createApp({
    methods: {
    handelLeft() {
    console.log("left");
    }
    },
    template: `
    <div>
    <div @click.left="handelLeft">11111</div>
    </div>
    `
    });

    app.mount("#root");
    </script>
    </body>
  6. 精确修饰符:exact……

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <body>
    <div id="root">
    </div>
    <script>
    const app = Vue.createApp({
    methods: {
    handelLeft() {
    console.log("left");
    }
    },
    template: `
    <!-- vue中精确修饰符:exact……-->
    <div>
    <div @click.ctrl.exact="handelLeft">11111</div>
    </div>
    `
    });

    app.mount("#root");
    </script>
    </body>
  7. 双向绑定修饰符:lazy、number、trim

  • lazy:失焦后进行双向绑定;
  • number:将绑定之后的数据转换成数字;
  • trim:将绑定之后的string前后的空格清除,字符串中间的空格不能清除;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    <script>
    const app = Vue.createApp({
    data() {
    return {
    message: "",
    numberMessage: 123,
    spaceMessage: "hey"
    }
    },
    template: `
    <div>
    {{message}}
    <input v-model.lazy="message"/>
    </div>
    div>
    {{numberMessage}}
    {{typeof numberMessage}}
    <input v-model.number="numberMessage" type="number"/>
    </div>
    <div>
    {{spaceMessage}}
    <input v-model.trim="spaceMessage"/>
    </div>
    `
    });

    app.mount("#root");
    </script>

九、表单中双向绑定指令的使用

  1. input、textarea的双向绑定
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <script>
    const app = Vue.createApp({
    data() {
    return {
    message: "hey"
    }
    },
    template: `
    <div>
    {{message}}
    <input v-model="message"/>
    <textarea v-model="message"/>
    </div>
    `
    });

    app.mount("#root");
    </script>
  2. checkbox的双向绑定
  • 单个checkbox
  • 多个checkbox
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <script>
    const app = Vue.createApp({
    data() {
    return {
    singleCheckBox: false,
    checkBoxes: []
    }
    },
    template: `
    <div>
    {{singleCheckBox}}
    <input type="checkbox" v-model="singleCheckBox"/>

    {{checkBoxes}}
    <input type="checkbox" v-model="checkBoxes" value="红"/>
    <input type="checkbox" v-model="checkBoxes" value="黄"/>
    <input type="checkbox" v-model="checkBoxes" value="蓝"/>
    绿<input type="checkbox" v-model="checkBoxes" value="绿"/>
    </div>
    `
    });

    app.mount("#root");
    </script>
  • 单个checkbox时自定义 true-value & false-value
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <script>
    const app = Vue.createApp({
    data() {
    return {
    checkBoxValue: "假",
    }
    },
    template: `
    <div>
    {{checkBoxValue}}
    <input type="checkbox" v-model="checkBoxValue" true-value="真" false-value="假"/>
    </div>
    `
    });

    app.mount("#root");
    </script>
  1. radio的双向绑定
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <script>
    const app = Vue.createApp({
    data() {
    return {
    radioData: "中"
    }
    },
    template: `
    <div>
    {{radioData}}
    <input type="radio" v-model="radioData" value="大">
    <input type="radio" v-model="radioData" value="中">
    <input type="radio" v-model="radioData" value="小">
    </div>
    `
    });

    app.mount("#root");
    </script>
  2. select的双向绑定
  • select单选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <script>
    const app = Vue.createApp({
    data() {
    return {
    selectValue: ""
    }
    },
    template: `
    <div>
    <select v-model="selectValue">
    <option value="" disabled>请选择</option>
    <option value="a">a</option>
    <option value="b">b</option>
    <option value="c">c</option>
    </select>
    </div>
    `
    });

    app.mount("#root");
    </script>
  • select多选
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <script>
    const app = Vue.createApp({
    data() {
    return {
    selectValues: [],
    }
    },
    template: `
    <div>
    {{selectValues}}
    <select v-model="selectValues" multiple>
    <option value="a">a</option>
    <option value="b">b</option>
    <option value="c">c</option>
    </select>
    </div>
    `
    });

    app.mount("#root");
    </script>
  • v-for使option循环
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <script>
    const app = Vue.createApp({
    data() {
    return {
    option: [{
    text: "a",
    value: "a"
    },{
    text: "b",
    value: "b"
    },{
    text: "c",
    value: "c"
    }],
    optionA: [],
    }
    },
    template: `
    <div>
    {{optionA}}
    <select v-model="optionA" multiple>
    <option v-for="item in option" :value="item.value">{{item.text}}</option>
    </select>
    </div>
    `
    });

    app.mount("#root");
    </script>
  • 利用select进行数据转化
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    <script>
    const app = Vue.createApp({
    data() {
    return {
    options: [{
    text: "a",
    value: {value: "a"}
    },{
    text: "b",
    value: {value: "b"}
    },{
    text: "c",
    value: {value: "c"}
    }],
    optionsA: [],
    }
    },
    template: `
    <div>
    {{optionsA}}
    <select v-model="optionsA" multiple>
    <option v-for="item in options" :value="item.value">{{item.text}}</option>
    </select>
    </div>
    `
    });

    app.mount("#root");
    </script>