Vue的模板语法、指令、修饰符

876 阅读5分钟

一、模板template的三种写法

第一种写法,Vue完整版,写在.html里

引入vue的完整版

<body>
  <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.min.js"></script>
    <!-- 引入vue的完整版 -->
</body>

.html

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

以下代码把上述<div>变成含有n的值的dom节点,写在main.js里面

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

第二种写法,Vue完整版,写在选项里new Vue(options)

.html

<div id=app>
    <!-- 这一部分内容写在new Vue的template``里面 -->
</div>

main.js

new Vue({
    template:`
      <div id = xxx>
        {{n}}
        <button @click="add">+1</button>
      </div>
    `
    //注意一个细节:div#app被替代为template里面的div
    data:{n:0},//data 可以改成函数
    methods:{add(){this.n +=1}}
}).$mount("#app")

注意一个细节:div#app被替代为template里面的div

'.$mount("#app")'是element的替换写法

第三种写法,Vue非完整版,配合xxx.vue文件

引入vue的运行时版

<body>
  <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.runtime.min.js"></script>
    <!-- 引入vue的运行时版 -->
</body>

xxx.vue里的<template>标签

<template>
      <div >
        <!-- div 不需要写 id = xxx -->
        <!-- id是用来让其他元素挂载到我这里,而这里的div已经是内容,不需要被挂载,所以不需要写id -->
        {{n}}
        <button @click="add">+1</button>
      </div>
</template>    

id是用来让其他元素挂载到我这里,而这里的div已经是内容,不需要被挂载,所以不需要写id。

<template> </template>里面不是HTML,而是XML语法。

因为XML语法代替松散的HTML,更容易写编译器,写出的解析器体积更小一些。

HTML和XML的区别

<input name = "username"> -HTML
<input name = "username" /> -XML

<div></div> -HTML
<div /> -XML

xxx.vue里的<script>标签

<script>
   export default {
   //不需要再写template
     data(){ return {n:0}},
     //这里的环境是组件xxx.vue,所以data必须是函数;data函数返回一个data对象。
     methods:{add(){this.n += 1}}
}
<script>

<style> 这里写 css </style>

在main.js里面导入组件xxx.vue

import Xxx from  "./xxx.vue"
//Xxx 是一个 options 对象//组件Xxx首字母一般大写,防止与原生组件冲突

new Vue({
    render: h => h(Xxx)
    //把Xxx组件传给Vue的render函数
}).$mount("#app")

二、template里面重要的语法

template:是用来表示HTML结构的字符串。

展示内容-template里面的内容三种展示方法如下:

1、表达式:{{展示里面的内容}}

new Vue({
    template:`
    <div id = xxx>
     {{object.a}}//把构造选项options的data{}里面的object.a显示到HTML里面
     {{ n + 1 }}//任何运算
     {{不支持写if else}}//vue不认识if else语句
     如果值为undefined或null就不显示
   </div>
    `
}).$mount("#app")

{{}}表达式的另一种写法为<div v-text= '表达式'> </div>

2、HTML内容:允许展示内容显示html标签效果

hi

假设 data.x 值为 <strong>hi</strong>

<div v-html = 'x'></div>即可显示粗体的hi

3、展示包括花括号在内的内容
{{ n }}

<div v-pre>{{ n }}</div>

v-pre 不会对template内容进行编译。

绑定属性v-bind

<img v-bind:src = 'x' /> //绑定src
<img :src='x' /> //可省略v-bind

<div
  :style='{border: '1px solid red', height:100}'>
  <!-- 这里可以把'100px'写成100 -->
</div>  

绑定事件v-on

<button v-on:click="add">+1</button>
//点击之后,Vue会运行add()
<button v-on:click="xxx(1)">xxx</button>
//点击之后,Vue会运行xxx(1)

缩写

<button @click="add">+1</button>//v-on缩写为@

template语法总结

Vue模板主要特点:

  • 使用XML语法
  • 使用{{}}插入表达式
  • 使用v-html v-on v-bind等指令操作DOM(这些声明式编程会被vue转化为DOM操作指令,即命令式编程)
  • 使用v-if v-for等指令实现 条件判断 和 循环
  • v-show实现显示或隐藏
<div v-show="n%2===0">n 是偶数 </div>
//近似等于
<div :style = "{display:n%2===0?'block':'none'}"> n 是偶数 </div>
//注意:显示的元素display不只有block
//table的display为table
//li的diplay为list-item

命令式编程:

div.innerHTML = x//在div里面插入一个x
img.src = x
button.onclick = add

声明式编程:

<div v-html = 'x'></div>//div里面有一个x
<img :src=x />
<button @click = 'add'/>

三、指令与修饰符

指令

v-on:click
v-bind:src
v-model
v-if 
v-for

还没有讲的指令

  • v-model
  • v-slot
  • v-cloak
  • v-once

修饰符

指令后面可以接修饰符

@click.stop = "add"//表示阻止事件传播/冒泡
@click.prevent = "add"//表示阻止默认动作
@click.stop.prevent = "add"//同时表示两种意思

重点了解 .sync 修饰符(同步数据)

项目示例 codesandbox.io/s/boring-td…

main.js

// 此处是「非完整版」vue
import Vue from "vue";
import App from "./App.vue";

Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

App.vue

<template>
  <div class="app">
    App.vue 我现在有 {{total}}
    <hr>
    <Child :money.sync="total"/>
    //等价于<Child :money="total" v-on:update:money = "total = $event"/>
    //"Child :money='total' "表示组件App.vue给子组件Child.vue传一个变量money='total'
    //规定必须用"update:money"来表示事件名
    //"update:money"是一个字符串,中间没有空格
    //也就是,我把数据money传给你,但是你子组件Child.vue要改的话要通知我App.vue来改,子组件不能自己改
    
    //v-on用于监听
    //$event用于获取$emit('update:money',money-100)后面的参数"money-100"$event是一个单独的变量,不属于this。
    //$event将触发事件后变化的参数"money-100",传回给total,total再传回给"update:money"
    //然后组件App.vue再将变化后的变量money='total'传回给子组件Child.vue
    
    //由于<Child :money="total" v-on:update:money = "total = $event"/>语句太长,于是封装了一个修饰符'.sync'来简化代码
    //即把"total -> money -> 'money-100' -> $emit -> $event -> total -> money"这样一个数据闭环简写为.sync
    
  </div>
</template>

<script>
import Child from "./Child.vue";
export default {
  data() {
    return { total: 10000 };
  },
  components: { Child: Child }
};
</script>

<style>
.app {
  border: 3px solid red;
  padding: 10px;
}
</style>

Child.vue

<template>
  <div class="child">
    {{money}}
    <button @click="$emit('update:money', money-100)">
    <!-- <button @click="this.$emit('update:money', money-100)"> -->
    //在vue.template里面,this表示当前实例,当前实例继承了eventbus,可以触发事件。
    //在vue.template里面,不要写this.直接用$emit
    
      <span>花钱</span>
    </button>
  </div>
</template>

<script>
export default {
  props: ["money"]
};
</script>


<style>
.child {
  border: 3px solid green;
}
</style>

回顾知识点1、eventbus

eventBus主要用于对象间通信。它使得M和V,C互相不知道对方的细节,但是却可以调用对方的功能。即满足最小知识原则。 详见 juejin.cn/post/684490…

回顾知识点2、$emit

在项目中,自定义了一个组件App.vue,在点击子组件Child.vue时,触发选中事件,并通过$emit,将子组件的数据传递给父组件。

<button @click="$emit('update:money', money-100)">
//在点击子组件时,触发选中事件

参见 juejin.cn/post/684490…

Vue规则(不用问为什么,直接使用)

  • 组件不能修改props外部数据(比如Child.vue不能修改App.vue传给它的money数据)
  • this.$emit可以触发事件,并传参
  • $event可以获取$emit的参数
<Child :money.sync="total"/>
    //等价于<Child :money="total" v-on:update:money = "total = $event"/>

什么叫语法糖?

.sync这种写法叫语法糖,API糖,因为使用起来很甜,像吃糖一样。

重点记忆四个修饰符

@click.stop="xxx"
@click.prevent="xxx"
@keypress.enter="xxx"
:money.sync="total"

更多修饰符参见:

cn.vuejs.org/v2/guide/ev… cn.vuejs.org/v2/guide/ev…