Vue模板语法

关于Vue模板官方这样说:Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循规范的浏览器和 HTML 解析器解析。
在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。

<div id="app">
 <p>{{title}}</p>
 <article-card></article-card>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  //定义一个局部注册的组件的选项对象
  let ArticleCard = {
    template: `<div id="ArticleCard">{{articleTitle}}</div>`,
    data() {
      return {
        articleTitle: '文章标题'
      }
    }
  };
  let vm = new Vue({
    el:"#app",
    data:{
      title:"Hello world",
    },
    components: {ArticleCard}
  });
</script>

Vue仅处理挂点下面的内容(dom节点),挂载点内部的为模板。
以这个例子为例,id为app的div是根组件的挂载点,即Vue实例的el选项对应的dom,article-card元素是组件ArticleCard的挂载点。
模板可以写在挂载点内部,也可以写在实例的template属性里,模板很像DOM但并不是DOM,Vue实例下面的$el对应的才是DOM,Vue把组件和模板经过内部各种处理得到DOM渲染到页面中。

组件中定义模板的方法

Vue模板语法

还记得《理解MVVM框架,简单实现双向数据绑定》中我们在解析器函数吗?我们遍历text节点,替换掉节点中的{{}},解析了属性v-model,与之类似的,Vue的模板语法的内容无外乎插值和指令。

1、Vue的插值表达式{{}}

插值表达式语法也称为Mustache语法,是使用双大括号{{}}的文本插值,主要作用是进行数据绑定,通过它可以轻松地在视图显示数据并及时自动更新,无需手动控制。

  • 插值表达式实际上也是Vue框架提供的指令;
  • 属性节点中不能使用插值表达式,如果要为元素节点动态绑定数据,要用v-bind动态绑定属性;
  • 插值表达式支持单个表达式,不支持语句和控制流。
<div id="app">
  <dl>
    <dt>字符串</dt>
    <dd>字符串:{{ str }}</dd>
    <dd>length属性:{{ str.length }}</dd>
    <dd>字符串连接:{{ num1 + '2'}}</dd>
    <dd>三目运算符:{{ num1 > num2 ? "是" : "否" }}</dd>
  </dl>
  <dl>
    <dt>数值</dt>
    <dd>数值:{{ num1 }}</dd>
    <dd>四则运算:{{ num1+num2 }}</dd>
    <dd>比较运算符:{{ num1 > num2 }}</dd>
    <dd>数值类型的内置方法:{{ num1.toFixed(2) }}</dd>
  </dl>
  <dl>
    <dt>布尔值</dt>
    <dd>{{ flag }}</dd>
  </dl>
  <dl>
    <dt>数组</dt>
    <dd>数组(转成了字符串):{{ arr }}</dd>
    <dd>数组长度:{{ arr.length }}</dd>
    <dd>数组的索引取值:{{ arr[0] }}</dd>
  </dl>
  <dl>
    <dt>对象</dt>
    <dd>{{ obj }}</dd>
    <dd>{{ obj.name }}</dd>
  </dl>
  <dl>
    <dt>null</dt>
    <dd>{{ arg1 }}</dd>
  </dl>
  <dl>
    <dt>undefined</dt>
    <dd>{{ arg2 }}</dd>
  </dl>
  <dl>
    <dt>NaN</dt>
    <dd>{{ arg3 }}</dd>
  </dl>
</div>
<script src="./vue.js"></script>
<script>
  let vm = new Vue({
    el:"#app",
    data:{
      str: 'string',
      num1: 1,
      num2:2,
      flag: true,
      arr: [1,2,3],
      obj:{
        name:'Lily',
        age:18
      },
      arg1: null,
      arg2: undefined,
      arg3: NaN
    }
  });
</script>

插值表达式语法支持的单个表达式如:

  1. 字符串及其length属性、字符串连接运算
  2. 数值、数值四则运算(加减乘除)、比较运算符、三目运算符、数值类型的一些内置方法
  3. 数组、数组length属性、数组的索引取值方法
  4. 布尔值
  5. 对象:支持对象的属性
  6. window内置对象的Math的属性和方法

2、指令

Vue中的指令是带有v-前缀的特殊属性,通过这些特殊属性能够操作元素。
一般在模板中指令的写法是

v-指令名:参数.修饰符 ="指令的绑定值"

Vue中的常用指令

v-text

作用:用于渲染普通文本
v-text和{{}}表达式作用一样,渲染数据但不解析标签。

  <dl>
	<dt>v-text:</dt>
	<dd v-text="msg1"></dd>
  </dl>
v-html

作用:渲染数据,而且可以解析标签

v-once

作用:一次性渲染插值表达式,数据改变时,插值处的内容不会更新。

<dl>
  <dt>v-once:</dt>
  <dd v-once>{{msg1}}</dd>
</dl>

在这里插入图片描述

v-show

作用:v-show指令根据表达式的真假值(true/false)来显示或隐藏元素。
当v-show赋值为false时,元素被隐藏,在Elements面板中可以看到该元素上会多一个内联样式style=“display:none”。

<dl>
  <dt>v-show:</dt>
  <dd v-show="flag">v-show切换的内容</dd>
</dl>

在这里插入图片描述

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

作用:根据表达式的真假值(true/false)在DOM中生成或移除元素。
v-if和v-show在页面效果上看很像,但v-show控制的是css,v-if控制的是DOM。
在这里插入图片描述

  • v-if赋值为false时,其所在的元素将会被移除DOM,重赋值为true时新建DOM。这意味着v-if有更高的切换消耗,而v-show有更高的初始渲染消耗。因此,如果需要频繁切换,则使用v-show更好。
  • 同编程语言的else类型,Vue中的v-else-if,v-else指令,需要和v-if结对出现,即要求前一个兄弟节点必须要使用 v-if 指令。
<dl>
  <dt>v-if、v-else-if和v-else:</dt>
  <dd v-if="num>100">v-if</dd>
  <dd v-else-if="num===1">v-else-if</dd>
  <dd v-else>v-else</dd>
</dl>
v-for

作用:根据变量的值来循环渲染元素,是专门用于迭代的指令,v-for可以迭代数组、字符串、数值、对象,实际工作中通常用来迭代对象组成的数组(或称对象数组、集合)。
语法:v-for 指令需要以 item in items形式的特殊语法, items指代源数据,item指代迭代的当前项目。
在迭代Array和String类型的数据时,可以获取索引值,当迭代对象属性时,可以获取键名和索引值。

<dl>
  <dt>v-for迭代数组:</dt>
  <dd v-for="(item,i) in arr">{{i+1}}、{{item}} </dd>
</dl>
<dl>
  <dt>v-for迭代对象组成的数组:</dt>
  <dd v-for="(item,i) in list">{{i+1}}、{{item.name}} {{item.age}}</dd>
</dl>
<dl>
  <dt>v-for迭代对象:</dt>
  <dd v-for="(item,key,index) in obj">{{index+1}}、{{key}}:{{item}}</dd>
</dl>
v-bind

作用:动态绑定DOM元素的属性,如常见的属性class,href,style,src等等,只要是属性,都可以用v-bind绑定。
语法:v-bind指令用冒号连接属性名,“v-bind”本身可以省略。
PS:Vue中的一些指令可以接收一个“参数”,在指令名称之后以冒号表示。

  <dl>
    <dt>v-bind:</dt>
    <dd v-bind:style="{fontSize: fontSize + 'px',color: color}">v-bind</dd>
  </dl>
v-model

作用:实现数据和视图的双向绑定,常用于<input><textarea>这类表单元素,这个指令实际上是帮助我们监听事件和更新视图。
v-model可以和.lazy、.trim和.number修饰符一起使用

  • v-model.lazy 修饰符,在表单元素发生一个blur时才触发
  • v-model.trim 将用户输入的前后的空格去掉
  • v-model.number 将用户输入的字符串转换成number
<dl>
  <dt>v-model:</dt>
  <dd><input type="text" v-model="msg1"></dd>
</dl>
<dl>
  <dt>v-model.lazy:</dt>
  <dd ><input type="text" v-model.lazy="msg1"></dd>
</dl>
<dl>
  <dt>v-model.trim:</dt>
  <dd ><input type="text" v-model.trim="msg1"></dd>
</dl>
<dl>
  <dt>v-model.number:</dt>
  <dd ><input type="text" v-model.number="msg1"></dd>
</dl>
<dl>
  <dt>源数据</dt>
  <dd><pre>{{msg1}}</pre> 类型:{{typeof msg1}}</dd>
</dl>

在这里插入图片描述

v-on

作用:用来绑定事件监听器,实现交互。
在这里插入图片描述
语法1: 同v-bind指令相似,v-on指令用冒号连接要监听的数据类型,v-on:可以简写为@;表达式可以是一个方法名或一个内联js语句,如果没有修饰符也可以省略。
语法2: 如果绑定的事件方法需要传递参数,传递形式有如下3种:

  • 方法名后面没有() ,形参就是“事件对象”
  • 方法名后面有(),但没有传递实参,形参就是undefined
  • 如果显式传递了参数(实参),就使用传递的参数

语法3: 当表达式是一个方法时,需要把方法定义在实例的methods选项中,methods中的事件方法中,可以通过this关键字调用vue实例的data数据,this代表vue实例对象。
语法4: v-on用在普通元素上时,只能监听原生 DOM 事件; 如用在自定义元素组件上,可以监听子组件触发的自定义事件。

语法5: v-on可以和事件修饰符一起使用
事件修饰符有5个:

  • .stop:阻止事件冒泡。
  • .prevent:阻止浏览器默认行为,比如页面滚动等。
  • .capture:翻转事件传播方向,本来事件是按照最内元素到外元素执行的,叫事件冒泡,capture正好相反,让元素从外到内传播事件。
  • .self:元素只在绑定的元素上执行。
  • .once:绑定的事件只执行一次,之后失效。
  <dl v-on:click="add">
    <dt>v-on:</dt>
    <dd>
      <button id="btn0" v-on:click="add">加1</button>
      <button id="btn1" v-on:click.stop="add">.stop|加1</button>
    </dd>
  </dl>
  <script>
	let vm = new Vue({
		el:"#app",
 	    data:{num:0},
 	    methods:{
      add(e){
        console.log(e.target);
        this.num++;
      }
    }
    </script>

在这里插入图片描述

修饰符

Vue提供了很多修饰符,Vue中修饰符 (modifier) 是以半角句号( . )指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。
例如:.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():
修饰符可以理解成将一段代码包装成另一段代码的方式 —— 字面上的“修饰”,它类似高阶函数,将一个函数作为另一个函数的参数或者方法,来实现一些功能的组合。
Vue中常用的修饰符,大致可分为:

  • 表单修饰符
    如:v-model的修饰符 .lazy、.trim、.number
  • 事件修饰符
    如:v-on的修饰符 .stop、 .prevent 、.capture、.self、.once 、.passive、.native
  • 鼠标按钮修饰符
    如:.left 左键点击 .right 右键点击 .middle 中键点击
  • 键值修饰符
    实际上是用来修饰事件修饰符中的键盘事件(keyup)的修饰符

关于修饰符,请参考vue修饰符–可能是东半球最详细的文档(滑稽)

自定义指令

指令在定义的时候,指令的名称前面,不需要加 v- 前缀,但是,在调用的时候,必须 在指令名称前 加上 v- 前缀来进行调用
和组件类似,自定义指令的注册分为全局自定义指令和局部指令。
1、 注册全局自定义指令
语法:Vue.directive(“指令名字”,options对象)
2、注册局部自定义指令
在组件的选项中设置directives来注册局部自定义指令

new Vue({
    el:"#app",
    directives: {
    指令名字: options对象
  }
})

options对象里包含 bind,inserted,update,componentUpdated,unbind选项,它们都是Vue提供的钩子函数。

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind:只调用一次,指令与元素解绑时调用。

钩子函数
钩子函数和 回调函数有些类似,一般都可用来处理事件的“回调”,回调函数做的处理过程跟钩子函数中要调用的方法一样。
与回调函数相比,Vue中的钩子函数不需要我们手动去监听,而是帮助我们监听一些事件,预留下钩子,钩住我们的回调方法。

  <dl>
    <dt>自定义指令</dt>
    <dd><input type="text" v-if="flag" v-model="msg1" v-test v-focus></dd>
    <dd><button v-on:click="create">创建</button>
      <button v-on:click="update">更新</button>
      <button v-on:click="destory">关闭</button></dd>
  </dl>
  <script>
  //全局注册自定义指令focus,使元素获得焦点
  Vue.directive('focus', {
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
  })
  let vm = new Vue({
    el:"#app",
    data:{
      msg1: 'hello world',
      flag: false,
      num: 0
      },
    directives:{
      // 注册一个局部的自定义指令 test
      "test": {
        /*只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
        和style有关的操作,最好在bind中去执行*/
        bind: function (el) {
          console.log('触发了bind钩子',el);
        },
        /*被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
        和js行为有关的操作,最好在 inserted 中去执行,否者 JS行为不生效*/
        inserted: function (el) {
          console.log('触发了inserted钩子',el.parentNode);
        },
        /*当VNode更新的时候,会执行 updated, 可能会触发多次*/
        update: function (el) {
          console.log('触发了update钩子',el.innerHTML);
        },
        /*指令所在组件的 VNode 及其子 VNode 全部更新后调用*/
        componentUpdated: function (el) {
          console.log('触发了componentUpdated钩子',el.innerHTML);
        },
        /*只调用一次,指令与元素解绑时调用。*/
        unbind: function (el) {
          console.log('触发了unbind钩子',el);
        }
      }
    },
    methods:{
      create(){
        console.log('=======创建========');
        this.flag=true
      },
      update(){
        console.log('=======更新========');
        this.num++;
      },
      destory(){
        console.log('=======销毁========');
        this.flag=false
      }
    }
  </script>

在这里插入图片描述
在Vue中自定义指令

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值