VUE(五)-template语法

2,118 阅读8分钟

一、template三种写法

(一)在Vue完整版里----写在HTML里(没有用到*.vue文件)

在index.html里直接写

<div id=xxx>
  {{n}}
  <button @click= " add">+1< /button>
</div>

在main.js的new Vue()options里就不需要写template属性

new Vue({
 el: '#xxx'
 data:{n:0}, // data可以改成函数
 methods:{add(){}}
 })

(二)在Vue完整版里----写在options的template属性里(没有用到*.vue文件)

首先得在index.html里写好挂载点,但是注意:被选为挂载点的这个标签div#app会被替代为template属性里的内容

<div id=app>
</div>

在main.js的new Vue()options里写template属性

new Vue( {
  template:`
      <div>
       {{n}}
       <button @click= " add">+1</button> 
      </div>`,
  data:{n:0}, 
  methods:{add(){ this.n +=1 }}
}).$mount( ' #app' )

(三)在Vue非完整版里----配合vue文件(vue单文件组件),写在他的template标签里(重点在*.vue文件中,js文件只要render即可)

在xxx.vue文件里写

<template>     //template标签里必须写XML语法,XML更紧凑,解析器体积会小点
  <div>
    {{n}}
    <button @click=" add">
      +1
    < /button>
  </div>
</template>

<script>         //默认导出一个对象,这个对象和options一模一样,除了以下两点
export default {       ①不用写template属性了,上面写了
   data(){ return {n:0} },   ② data属性必须是函数(不然写对象的话会出现多个组件公用一个data的情况),这个函数返回一个对象,就是我们的数据
   methods:{add(){ this.n += 1 } }
}
</script>

<style>这里写CSS </style> 

然后在main.js里

import Xxx from './xxx. vue' // 导入这个options 对象,并且取组件名(开头要大些)Xxx

new Vue({
 render: h => h(Xxx)  //视图用render
}).$mount( ' #app' )
复制代码

但是注意:被选为挂载点的这个标签div#app会被替代为<template>标签里的内容

template语法

注意template里面只能有一个根组件,所以必须用一个div包住,还有模板语法只支持js,所以模板不需要类型,和ts兼容性不太好

(一)使用XML语法

  • XML的自闭合标签必须有
  • XML的空标签可以直接闭合

(二)指令Directive

1、什么是指令

<div v-text="x"></div>

<div v-html="x"></div>

v-开头的东西就是指令

2、语法

 `v-指令名:参数=值`,如`v-on:click=add`
  • 如果值里没有特殊字符,则可以不加引号(那我还是都加引号!防止bug)
  • 有些指令没有参数和值,如v-pre
  • 有些指令没有值,如V-on:click.prevent

3、修饰符:用来修饰指令

(1)有哪些

v-on支持的有(修饰事件,把事件的触发条件进一步缩小或者对事件传播进行限定)

  • .{keycode | keyAlias} 

<input @keypress.13='y'>在input里,键盘按下回车(回车的keycode=13),就执行函数y

<input @keypress.enter='y'>在input里,键盘按下回车,就执行函数y

  • .stop 重点
  • .prevent 重点
  • .capture
  • .self
  • .once
  • .passive
  • .native

(快捷键相关)

  • .ctrl
  • .alt
  • .shift
  • .meta
  • .exact

(鼠标相关)

  • .left
  • .right
  • .middle

②v-bind支持的有

  • .prop
  • .camel
  • .sync 重点 

③v-model支持的有

  • .lazy 重点
  • .number 重点
  • .trim 重点

(2)重点讲解

  • .stop 阻止事件传播/冒泡

    @click.stop = "add"

  • .prevent 阻止事件的默认动作

    @click.prevent点击时,阻止点击时的默认动作

    @click.prevent = "add"点击时,阻止点击时的默认动作,并且执行add函数

  • .{keycode | keyAlias}

<input @keypress.13='y'>在input里,键盘按下回车(回车的keycode=13),就执行函数y

<input @keypress.enter='y'>在input里,键盘按下回车,就执行函数y

4、具体用法

①插入(普通文本)表达式{{ }}

  • 完整写法(但没人用)<div v - text="表达式" ></div>
  • {{object.a}} 把options的data里的object.a显示在这
  • {{n+1}}可以写任何运算(但不支持if和else)
  • {{fn(n)}}可以调用函数(默认在methods里找)
  • 如果值为undefined 或null就不显示
  • 只支持运算不支持语法(不支持if和else )

在vue眼中如果一个data值为空,那么它不是undefined而是直接去掉不发挥作用,例如{{}}和v-bind:data 如果一个值是fasasy 那么vue就会把那部分代码跳过

②v-html指令插入HTML内容

  • 假设data. x值为<strong>hi</strong>
  • 那么<div v-html="x"></div> 即可显示粗体的hi
  • 意思是我这个"x"是粗体的hi而不是strong标签包着的hi,hi即是富文本你得把他当做富文本显示到页面

③v-pre指令写啥就展示啥

  • <div v-pre>{{ n }}</div>:我就想展示{{n}}
  • v-pre指令不会对模板进行编译

④v-bind指令绑定一个标签的属性

  • 完整写法:<img v- bind:src="x"/>,<img src={{x}}/>也可以但是不要这样写,花括号用来展现文本,x的双引号是v-bind的一部分
  • 简写为:<img :src="x" />
  • 还可以绑定对象
<div :style="{border:'1px solid red',height :100}">
</div>  //注意这里可以把'100px'写成100,但是100vm就不能省略单位了

v-bind(:冒号),如果有冒号那么后面的双引号就不是代码一部分,如下type是个变量而不是字符串

li :class="type"        //变量
li class="type"   //字符串
li :class="333"    //数字
li class="333"          //字符串

⑤v-on指令绑定事件

  • 完整写法(没人用):v-on:事件名
//事件处理函数可以为函数名
<button v-on:click="add">+1< / button>  //点击之后,Vue会运行add()

//事件处理函数可以为函数的调用形式
<button v-on:click="xxx(1) ">XXX< / button>  //点击之后,Vue会运行xxx(1)

//事件处理函数可以直接写代码
<button v-on:click="n+=1">XXX< / button>  //点击之后,Vue会运行n+=1
即发现函数就加括号调用之,否则就直接运行代码

vue会对xxx(1)做处理不会立即调用,这导致一个问题,如果xxx(1)返回一个函数咋办,如果我们就是为了xxx(1)返回一个函数来调用怎么办,没办法尽量别写 

  • 缩写:<button @click="add">+1</button>
  • 如果一个@click触发一个methods,如果这个函数不创参数,那么vue会自动传一个参数,就是这个事件的信息
  • 强制类型,因为vue和ts结合的不是很好,比如在vue的模板中的一个按钮上写事件,下面的ts代码并不知道监听的是什么元素,所以ts会不知道event.target到底有没有textcontent


⑥v-if和v-else-if和v-else条件判断

如果满足条件,这个标签就出现在DOM树里,从而出现在页面

<div v-if="x>0">
   x大于0
</div>
<div v-else-if="x=== 0">          //接在if后面
   x为0
</div>
<div v-else>
   x小于0
</div>

⑦v-for循环

v-for="(value, key) in 对象或数字" :key="每个元素不会重合的值。"

<ul>
 <li v-for="(u, index) in users" :key="index">  //一定要绑定key="index"
  索引: {{index}} 值: {{u. name}}
 </li>
</ul>

<ul>
  <li v-for="(value, name) in obj" :key="name" >
    属性名: {{name}}, 属性值: {{value}}
  </li>
</ul>

⑧v-show(通过css)显示和隐藏,而不是添加入DOM树而显示隐藏

  • <div v- show= "n%2===0"> n是偶数 </div>

如果表达式的布尔值为true,就将这个标签(通过添加css样式的dispaly)显示在页面

  • 是语法糖
  • 近似等于
<div :style="{display :n%2===0? 'block': 'none'}"> n是偶数</div>

之所以近似等于,是因为

看得见的元素display不只有block

tabledisplaytable

lidisplaylist-item

尽量少用,可以用css切换

⑨v-once

只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

<!-- 单个元素 -->
<span v-once>This will never change: {{msg}}</span>

<!-- 有子元素 -->
<div v-once>
  <h1>comment</h1>
  <p>{{msg}}</p>
</div>

<!-- 组件 -->
<my-component v-once :comment="msg"></my-component>
<!-- `v-for` 指令-->
<ul>
  <li v-for="i in list" v-once>{{i}}</li>
</ul>


操作dom

v-html,v-on,v-bind来操作dom元素

<div v-html="x"></div> 

v-html,声明式编程,告诉div里面有什么


show和if的区别

v-show是展示出来,已经存在在dom树里

v-if还没有出现在dom树里


插槽

<Layout>  <p>Money</p>  </Layout>

Layout是一个组件

要把<p>Money</p>传给组件,就需要在Layout组件里加入插槽<slot/>即可

Class 与 Style 绑定

操作元素的 class 列表和内联样式是数据绑定的一个常见需求。因为它们都是属性,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind 用于 classstyle 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。

我们可以传给 v-bind:class 一个对象,以动态地切换 class:

<div v-bind:class="{ active: isActive }"></div>

上面的语法表示 active 这个 class 存在与否将取决于数据属性 isActive 的 truthiness。

<div
  class="static"
  v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>

和如下 data:

data: {
  isActive: true,
  hasError: false
}

结果渲染为:

<div class="static active"></div>

我的实例

   <button class="g-button" :class="{[iconPosition]:true}">

props: {
            iconPosition:{
                type:String,
                default:'left',
                validator(value){
                   return !(value !== 'left' && value !== 'right');
                }
            }

这个例子只动左边有点不一样

最后的结果就是class='xxx'(xxx是你传进来的)

除了对象数组也可以

我们可以把一个数组传给 v-bind:class,以应用一个 class 列表:

<div v-bind:class="[activeClass, errorClass]"></div>

渲染为:

<div class="active text-danger"></div>
<div class="col" :class="{[`col-${span}`]:true}">

等价于

<div class="col" :class="[`col-${span}`]">