02-模板语法

nobility 发布于 2022-01-16 1344 次阅读


模板语法

数据绑定

插值语法绑定

插值表达式

使用双大括号的标签,该标签内可以是JavaScript的任意表达式(字符串拼接、数值计算,函数调用等)

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

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <style>[v-cloak] { display: none }</style>  <!-- 隐藏具有v-cloak属性的标签 -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    {{1+1}}	<!-- 1 -->
    <br>
    {{"hello" + " worad"}}  <!-- hello worad -->
    <br>
    {{new Date()}}  <!-- Thu Jan 01 1970 08:00:00 GMT+0800 (中国标准时间) -->
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
    });
  </script>
</body>

</html>
v-cloak

若客户端出现卡顿,插值表达式会先显示Mustache标签,之后会迅速替换为定义的数据,为了解决这种闪动问题,可使用该指令,隐藏未编译的Mustache标签,编译完成后显示,和CSS[v-cloak] { display: none }连用

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

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <style>[v-cloak] { display: none }</style>  <!-- 隐藏具有v-cloak属性的标签 -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app" v-cloak>{{message}}</div>	<!-- 插值语法填充数据 -->
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() {  //绑定数据
        return { message: "hello world" }
      }
    });
  </script>
</body>

</html>

v-text、v-html和v-pre

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

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <div v-text="message"></div>  <!-- 替换标签中的整个内容(会自动转义html标签) -->
    <div v-html="message"></div>  <!-- 替换标签中的整个内容(会渲染html标签) -->
    <div v-pre>{{message}}</div> <!-- 标签中的插值表达式不会经过编译,而是原封不动的返回 -->
    <div v-text="message + 123"></div>  <!-- 引号中可以是JavaScript的任意表达式(字符串拼接、数值计算,函数调用等) -->
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() {  //绑定数据
        return { message: "<h1>hello world</h1>" }
      }
    });
  </script>
</body>

</html>

v-model

随表单内容数据进行双向数据绑定,可用于输入框、下拉框、复选框和单选框,还可以使用以下三种修饰符

  • .lazy:使用input事件监听代替change事件
  • .number: 输入字符串转为有效的数字
  • .trim: 输入首尾空格过滤
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <fieldset>
      <legend>输入框</legend>
      输入框双向绑定:<input type="text" v-model="input">
      <h4>绑定的input变量值为:{{input}}</h4>
      使用lazy修饰符:<input type="text" v-model.lazy="input">
      <h4>绑定的input变量值为:{{input}}</h4>
    </fieldset>

    <fieldset>
      <legend>复选框</legend>
      <input type="checkbox" v-model="checkboxArray" name="checkbox" value="checkbox1">复选框1
      <input type="checkbox" v-model="checkboxArray" name="checkbox" value="checkbox2">复选框2
      <h4>绑定的checkboxArray数组为:{{checkboxArray}}</h4>
    </fieldset>

    <fieldset>
      <legend>单选框</legend>
      <input type="radio" value="nan" v-model="radio"><input type="radio" value="nv" v-model="radio"><h4>绑定的radio变量值为:{{radio}}</h4>
    </fieldset>

    <fieldset>
      <legend>下拉框</legend>
      <select v-model="select">
        <option value="opt1">选项1</option>
        <option value="opt2">选项2</option>
        <option value="opt3">选项3</option>
      </select>
      <h4>绑定的select变量值为:{{select}}</h4>
      <select v-model="selectArray" multiple>
        <option value="opt1">选项1</option>
        <option value="opt2">选项2</option>
        <option value="opt3">选项3</option>
      </select>
      <h4>绑定的selectArray数组为:{{selectArray}}</h4>
    </fieldset>

  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() { //绑定数据
        return {
          input: "input",
          checkboxArray: [],
          radio: "",
          select: "",
          selectArray: []
        }
      }
    });
  </script>
</body>

</html>

v-once

只编译一次,不再具有数据响应式功能,用于新能优化

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

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app" v-once>{{message}}</div> <!-- 插值语法填充数据 -->
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() {  //绑定数据
        return { message: "hello world" }
      }
    });
    app.$data.message = "你好,世界"; //该修改不会影响到页面变化
  </script>
</body>

</html>

事件绑定

v-on

使用v-on:事件名="内容"方式绑定事件,也可以使用@事件名="内容"的简写方式,内容可以是简单的JavaScript代码,也可以是Vue对象中methods属性中的方法

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

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <h1>{{number}}</h1>
    <input type="button" v-on:click="number++" value="按钮"> <!-- 简单JavaScript代码片段 -->
    <input type="button" @click="number++" value="按钮"> <!-- 简写方式 -->
    <input type="button" @click="add" value="按钮"> <!-- 绑定方法,会自动传递事件对象参数,等价与add($event) -->
    <input type="button" @click="addNum(2,$event)" value="按钮"> <!-- 绑定方法,但并非是该方法的返回值,而是用于传参 -->
    <!-- 不会自动传递事件对象参数,必须手动传递事件对象,并且事件对象必须是最后一个参数 -->
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() { //绑定数据
        return { number: 0 }
      },
      methods: {
        add(event) {
          console.log(event); //默认参数是事件对象
          this.number++; //this指向该Vue对象,即app
        },
        addNum(number, event) {	//事件对象必须是最后一个参数
          console.log(event);
          this.number += number; //this指向该Vue对象,即app
        }
      }
    });
  </script>
</body>

</html>

事件修饰符

还可以使用以下修饰符,多个修饰符可链式调用,但是要注意顺序,因为 @click.prevent.self 会阻止所有的点击,而 @click.self.prevent 只会阻止对元素自身的点击

  • .stop:调用 event.stopPropagation()取消事件冒泡
  • .prevent:调用 event.preventDefault()取消事件默认行为
  • .self:只当事件是从绑定的元素本身触发时才触发回调
  • .once:只触发一次回调
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app" @click="fun(1)">fun(1)  <!-- 父元素绑定事件 -->
    <h1 @click.stop="fun(2)">fun(2)</h1>  <!-- 阻止子元素的事件冒泡 -->
    <a href="https://www.baidu.com" @click.stop.prevent>百度</a>  <!-- 阻止默认行为和冒泡,链式调用即可 -->
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      methods: {fun(num){ alert(num) }}
    });

  </script>
</body>

</html>

按键修饰符

对于键盘事件可以使用以下修饰符来指定按键,若不指定按键,则任意按键都会触发事件,可以向Vue.config.keyCodes对象中添加自定义按键修饰符

  • .enter:回车键
  • .tab:tab键
  • .delete :包括删除和退格键
  • .esc:ESC键
  • .space:空格键
  • .up:上方向键
  • .down:下方向键
  • .left:左方向键
  • .right:右方向键
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <input type="text" @keyup.enter.delete.a="fun(1)">  <!-- 可链式调用指定多个键 -->
  </div>
  <script>
    Vue.config.keyCodes.a = 65; //自定义按键修饰符(必须用小写),该数字是键盘事件对象中keyCode的值
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      methods: { fun(num){ console.log(num) } }
    });
  </script>
</body>

</html>

控制按键修饰符

控制按键修饰符,需同时于其他按键一起使用,否则组合任意键都会触发事件(包括鼠标事件)

  • .ctrl:与ctrl键同时按下
  • .alt:与alt键同时按下
  • .shift:与shift键同时按下
  • .meta:与win键或command键同时按下
  • .exact:组合按键更加精确,比如在点击事件和控制按键组合时,若多按一个控制键也会触发,但是使用该修饰符后就不再会触发
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <input type="text" @keyup.ctrl.a="fun(1)"> <!-- 同时按下CTRL + A键 -->
  </div>
  <script>
    Vue.config.keyCodes.a = 65; //自定义按键修饰符
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      methods: { fun(num) { console.log(num) } }
    });
  </script>
</body>

</html>

鼠标按钮修饰符

对于鼠标事件可以使用以下修饰符来指定按钮,若不指定按键,则默认是鼠标左键

  • .left:左键
  • .right:右键
  • .middle:中键
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <h1 @click.right.prevent="fun(1)">H1</h1> <!-- 按下鼠标右键 -->
  </div>
  <script>
    Vue.config.keyCodes.a = 65; //自定义按键修饰符
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      methods: { fun(num) { console.log(num) } }
    });
  </script>
</body>

</html>

属性绑定

v-bind

使用v-bind:属性名="内容"方式绑定属性,也可以使用:属性名="内容"的简写方式,内容可以是Vue对象中data属性中的数据变量,也可以是Javascript代码

普通属性绑定

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

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <a v-bind:href="url">连接</a>
    <a :href="url">连接</a> <!-- 简写方式 -->
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() { return { url: "http://www.baidu.com" } }
    });
  </script>
</body>

</html>

Class属性绑定

对象语法
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <div :class="{one:isOne,two:isTwo}"></div> <!-- 对象的键是one,值是布尔类型,若为true则添加该类名 -->
    <div class="base" :class="{one:isOne,two:isTwo}"></div> <!-- 对于已有的class不会覆盖,而是融合 -->
    <div :class="ClassObj"></div> <!-- 也可以是对象类型的变量 -->
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() {
        return {
          isOne: true,
          isTwo: false,
          ClassObj: { isOne: true, isTwo: false }
        }
      }
    });
  </script>
</body>

</html>
数组语法
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <div :class="[oneClass,twoClass,threeClass]"></div> <!-- 数组中所有类变量全部添加到该标签上,若该类名为空字符串则不会添加任何内容 -->
    <div class="base" :class="[oneClass,twoClass]"></div> <!-- 对于已有的class不会覆盖,而是融合 -->
    <div :class="ClassArr"></div> <!-- 也可以是数组类型的变量 -->
    <div :class="[oneClass,twoClass,{three:isThree}]"></div> <!-- 也可以与对象方式混合使用连用 -->
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() {
        return {
          oneClass: "one",
          twoClass: "two",
          threeClass: "",
          ClassArr: ["one", "two"],
          isThree: true
        }
      }
    });
  </script>
</body>

</html>

Style属性绑定

对象语法
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <div :style="{border: borderStyle, width: widthStyle, height: heightStyle}"></div> <!-- 对象的键是属性名,值是属性值 -->
    <div :style="styleObj"></div> <!-- 也可以是对象类型的变量 -->
    <div style="border:1px solid yellow;" :style="styleObj"></div> <!-- 对于已有的样式会覆盖,没有的会融合 -->
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() {
        return {
          borderStyle: "1px solid red",
          widthStyle: "100px",
          heightStyle: "100px",
          styleObj: {border: "1px solid red", width: "100px", height: "100px"}
        }
      }
    });
  </script>
</body>

</html>
数组语法
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>
<body>
  <div id="app">
    <div :style="[styleObj1,styleObj2]"></div>
    <!-- 数组中存放多个对象,前后对象中有重复的属性时,后面会覆盖掉前面的,不重复时会融合 -->
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() {
        return {
          styleObj1: {border: "1px solid red", width: "100px", height: "100px"},
          styleObj2: {backgroundColor: "blue", width: "200px"}	//短横线连接的属性在JavaScript中使用驼峰命名法
        }
      }
    });
  </script>
</body>

</html>

其他数据操作

计算属性

是Vue对象中computed属性中的方法就是计算属性,与普通方法不同的是:

  • 若有多处用到该计算属性时该函数只会执行一次,而方法却会执行多次(当页面重新渲染时方法也会重新执行)
  • 定义计算属性时必须有return语句,调用计算属性时不能加括号
  • 当数据发生改变时,计算属性的缓存值也会发生变化,若是对象形式的计算属性则可以定义setter方法,非对象形式计算属性默认只有getter方法
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <h4>计算属性:{{fullNameComputed}} | 方法:{{fullNameMethod()}} | {{age}}</h4>
    <h4>计算属性:{{fullNameComputed}} | 方法:{{fullNameMethod()}} | {{age}}</h4>
    <!-- 切勿使用函数调用的方式进行调用,因为计算属性本身就是属性,Vue只是将该值当作属性缓存起来了,方便下次调用 -->
    <h4>对象形式的计算属性:{{fullName}}</h4>
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() { //绑定数据
        return {
          firstName: "firstName",
          lastName: "lastName",
          age : 18
        }
      },
      computed: { //计算属性
        fullNameComputed() { //默认情况下只有getter方法
          console.log("计算属性执行了一次");
          return this.firstName + " " + this.lastName;
        },
        fullName: { //计算属性的对象形式,可以定义setter方法
          get(){
            return this.firstName + " " + this.lastName;
          },
          set(value){ //value是外部传递的值,就可以通过设置计算属性值设置非计算属性的值
            this.firstName = value.split(" ")[0];
            this.lastName = value.split(" ")[1];
          }
        }
      },
      methods: {  //方法
        fullNameMethod() {
          console.log("方法执行了一次");
          return this.firstName + " " + this.lastName;
        }
      }
    });
    app.age = 100;  //修改age属性会导致页面重新渲染,当页面渲染时,方法会重新执行,但是计算属性却不会
    setTimeout(() => { app.fullName = "first last"; }, 1000);  //1秒后修改对象形式的计算属性的值
  </script>
</body>

</html>

监听器

是Vue对象中watch属性中的方法,并且与data中绑定的数据名字保持一致,当data中的属性发生变化时,会触发watch中对应的方法,方法中第一个参数就是变化后的值

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

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app"> {{message}} </div>
  <!-- 切勿使用函数调用的方式进行调用,因为计算属性本身就是属性,Vue只是将该值当作属性缓存起来了,方便下次调用 -->
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data(){ //绑定数据
        return{message: "hello world"}
      },
      watch: { //计算属性
        message(value){
          console.log("变化后的数据为:",value);
          //this.message = "我是前缀" + value;  //切勿在监听器中递归修改,否则递归没有出口导致栈溢出
        }
      }
    });
    app.message = "hello world!!!"
  </script>
</body>

</html>

过滤器

是Vue对象中filters属性中的方法,方法中第一个参数就是要过滤的值,在使用时类似Linux中的管道运算符,过滤器参数可以使用括号进行传递,在定义过滤器时自定义参数是从第二个开始的

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

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app"> 
    {{message | prefix}}  <!-- 对message进行过滤 -->
    <br>
    {{message | prefix | prefix}}  <!-- 可过滤多次 -->
    <br>
    {{message | suffix("参数")}} <!-- 带参数的过滤器 -->
  </div> 
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() { //绑定数据
        return { message: "hello world" }
      },
      filters: {  //过滤器
        prefix(value) { return "前缀" + value },
        suffix(value,arg) { return value + arg }	//参数是从第二个开始的
      }
    });
  </script>
</body>

</html>

分支循环结构

v-if、v-else和v-else-if

控制元素是否会被渲染,会有DOM操作,v-if、v-else和v-else-if这三个指令必须紧贴在一起使用,否则会报语法错误

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

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>
<body>
  <div id="app">
    <h1 v-if="score>=90">A</h1> <!-- v-if后是一个布尔表达式,若表达式为真则该元素将会被渲染,否则不会渲染 -->
    <h1 v-else-if="score<90&&score>=60">B</h1>  <!-- 与v-if类似 -->
    <h1 v-else>C</h1> <!-- 无需跟布尔表达式,若上面的v-if或v-else-if都为fasle时才会渲染该元素 -->
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() { return { score: 60 } }
    });
  </script>
</body>

</html>

v-show

控制元素是否显示,不会有DOM操作,而是已经渲染到页面上,使用的style标签中添加display: none来控制是否显示

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

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>
<body>
  <div id="app">
    <h1 v-show="show">show</h1> <!-- v-show后是一个布尔表达式,若表达式为真则该元素将会被显示,否则不会显示 -->
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() { return { show: false } }
    });
  </script>
</body>

</html>

v-for

可以用of替代in作为分隔符,因为它更接近JavaScript迭代器的语法

遍历数组
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <ul>
      <li v-for="item in array">{{item}}</li> <!-- 遍历数组的项 -->
    </ul>
    <ul>
      <li v-for="(item,index) in array">{{index}} : {{item}}</li> <!-- 遍历数组项和索引 -->
    </ul>
    <ul>
      <li v-for="item in objArray">{{item.name}}</li> <!-- 遍历对象数组 -->
    </ul>
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() {
        return {
          array: ["one", "tow", "three"],
          objArray: [
            {name: "one"},
            {name: "tow"},
            {name: "three"},
          ]
        }
      }
    });
  </script>
</body>

</html>
遍历对象
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <ul>
      <li v-for="value in obj">{{value}}</li> <!-- 遍历对象,不包括键 -->
    </ul>
    <ul>
      <li v-for="(value,key) in obj">{{key}} : {{value}}</li> <!-- 遍历对象,包括键 -->
    </ul>
    <ul>
      <li v-for="(value,key,index) in obj">{{index}}、{{key}} : {{value}}</li> <!-- 遍历对象,包括键和索引 -->
    </ul>
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() {
        return {
          obj: {
            oneKey: "one",
            towKey: "tow",
            threeKey: "three"
          }
        }
      }
    });
  </script>
</body>

</html>
与v-if联用
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <ul>
      <li v-if="index>0" v-for="(item,index) in array">{{item}}</li> <!-- 可过滤要数组中的遍历项,从第二个开始遍历 -->
    </ul>
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() { return { array: ["one", "tow", "three"] } }
    });
  </script>
</body>

</html>
模板占位符
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <template v-for="(item,index) in array">  <!-- 此时的template标签只起到包裹作用,不会被渲染到页面上 -->
      <em>{{index}}</em> <strong>{{item}}</strong>
      <br>
    </template>
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() { return { array: ["one", "tow", "three"] } }
    });
  </script>
</body>

</html>

Diff算法

Diff算法的目的就是尽可能的复用页面中的DOM元素,减少删除添加DOM元素的操作,从而提高效率,但是这有时候会带来一些BUG,解决这个问题,简单的就为不希望复用的DOM元素绑定一个唯一的key值

列表渲染

使用v-for列表渲染时,默认就地更新的策略,若顺序被改变,不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素中的内容,并且确保它们在每个索引位置正确渲染

也就是说当前数组为[1,2,3]此时更改为[1,2,30],Vue会依次对比0号元素是否发生改变,1号元素是否发生改变,若改变则修改DOM中的值,这个默认的模式是高效的;但若元素的顺序发生变化时,此时更改为[0,1,2,3],Vue会对比所有元素进行内容替换,效率会很低,为了而重用和重新排序现有元素,所以要为每项绑定一个唯一 key,Vue会依次对比与变化之前key值相同的元素是否发生变化,对于没有的key值的元素就会插入一个DOM元素,从而提高效率(切勿将key值设置为索引值,因为在与虚拟DOM进行对比时和未绑定key的效果是一样的)

条件渲染

使用v-if条件渲染时,同样的使用就地更新策略,若两个条件渲染DOM元素相同时,不会移除并添加DOM,而是就地更新每个元素中的内容

比如页面中两个input标签进行切换,当已输入到第一个input中内容,之后在切换input标签,此时Vue为了复用DOM所以相同的DOM并不会切换,而是复用,导致input中的内容不会被清空,所以要为input标签绑定一个唯一key值即可

更新检测机制

由于JavaScript的限制,Vue不能检测数组和对象的属性增删变化,也就是说通过索引的方式修改数据不能达到数据响应式的功能,若想修改必须使用数组中的方法间接修改(这是因为Vue重写了这些方法)或修改整个数组中的引用,也可以使用Vue.set()vue.prototype.$set()方法进行修改(Vue.delete()vue.prototype.$delete()方法进行删除)

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

<head>
  <meta charset="UTF-8">
  <title>hello world</title>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><!-- CDN方式引入Vue -->
</head>

<body>
  <div id="app">
    <ul>
      <li v-for="item in array" :key="item">{{item}}</li>
    </ul>
  </div>
  <script>
    var app = new Vue({ //创建Vue实例
      el: "#app", //挂载元素
      data() { return { array: ["one", "tow", "three"] } }
    });
    app.array[0] = 1000; //虽然数据发生改变,但是页面并为发生改变
    app.array.splice(0,1,100);  //这种间接修改方式可以检测到数据发生变化
    Vue.set(app.array, 0, 10); //这种方式可以检测到数据发生变化,对象也是一样的,只不过索引变成了key值
    app.$set(app.array, 0, 1);	//实例方法也是一样
  </script>
</body>

</html>
此作者没有提供个人介绍
最后更新于 2022-01-16