Vue零基础教程|从前端框架到GIS开发系列课程(三)模板语法

模板

1) 什么是模板

由Vue解析的HTML字符串Vue的主要工作
1编译模板
2挂载

2) 如何确定模板


确定模板有几种方式
1没有指定template选项, 以容器的innerHTML做为模板
2指定template选项, 以template选项做为模板
3指定render选项, 以render函数做为模板

优先级: render函数 > template > 容器
render函数在后续有专门的章节介绍, 这里我们先介绍template选项
示例

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <!-- 容器指定的innerHTML模板 < template指定模板 -->    <div id="app">由容器指定的模板</div>
    <script>      const { createApp, h } = Vue
      const app = createApp({        template: `<h1>由template指定的模板</h1>`,        render: () => h('div', '由render函数指定的模板'),      })
      app.mount('#app')</script>  </body></html>

 

模板语法

1) 什么是模板语法

什么是模板语法
在模板字符串中, 具有特殊意义的语法

2) 模板语法分类

模板语法分为
●插值语法: 在{{}}中书写的语法
●指令语法: 以v-开头的语法

插值语法
语法
在{{}}中书写的语法
{{}}里书写js表达式, 叫做插值表达式
应用
主要应用于文本节点

示例

<div id="app">  {{msg}}</div>

指令语法

语法
以v-开头的指令.
在属性值中书写js表达式, 叫做指令表达式
应用
主要应用于属性节点

示例

<a v-bind:href="url">百度</a>

插值语法细节

1) 直接使用实例上的属性

在{{}}内, 可以直接访问当前实例上的属性
示例

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <!-- 直接使用instance实例上的属性 -->      姓名: {{name}} <br />      女友: {{gf.name}} <br />      喜欢的书: {{books[0].name}} <br />    </div>
    <script>      const { createApp } = Vue
      const vm = createApp({        data() {          return {            name: 'xiaoming',            age: 20,            gf: {              name: 'xiaomei',              age: 18,            },            books: [{ name: 'Vue' }, { name: 'React' }],          }        },      }).mount('#app')</script>  </body></html>

2) 使用表达式

在{{}}内, 可以书写js表达式, 但是不能书写语句
示例

{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}

错误的情况

<!-- 这是一个语句,而非表达式 -->{{ var a = 1 }}
<!-- 条件控制也不支持,请使用三元表达式 -->{{ if (ok) { return message } }}

 

插值语法细节

1) 直接使用实例上的属性

在{{}}内, 可以直接访问当前实例上的属性
示例

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <!-- 直接使用instance实例上的属性 -->      姓名: {{name}} <br />      女友: {{gf.name}} <br />      喜欢的书: {{books[0].name}} <br />    </div>
    <script>      const { createApp } = Vue
      const vm = createApp({        data() {          return {            name: 'xiaoming',            age: 20,            gf: {              name: 'xiaomei',              age: 18,            },            books: [{ name: 'Vue' }, { name: 'React' }],          }        },      }).mount('#app')</script>  </body></html>

2) 使用表达式

在{{}}内, 可以书写js表达式, 但是不能书写语句
示例

{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}

错误的情况

<!-- 这是一个语句,而非表达式 -->{{ var a = 1 }}
<!-- 条件控制也不支持,请使用三元表达式 -->{{ if (ok) { return message } }}

 

属性绑定指令

如果要将某一个属性的值和data中的状态绑定, 需要使用绑定指令
属性绑定

将一个元素的一个属性值和data中的一个变量绑定​​​​​​​

<!-- 完整的写法 --><a v-bind:href="url">百度</a><!-- 简写(推荐) --><a :href="xzd">新中地</a>

vue官方更推荐简写的方式

图片

const vm = createApp({  data() {    return {      url: 'http://www.baidu.com',    }  },}).mount('#app')

将a标签href属性和data中的url变量绑定
●相当于<a href="http://baidu.com"></a>
💡特别说明
在指令后面的引号中, 可以使用类似于{{}}中一样的语法.
●可以使用js表达式
●直接访问vm实例上的属性和方法
●不能是js语句

 

事件绑定指令

1) 什么是事件绑定

将JS事件和对应的处理函数绑定

2) 语法​​​​​​​

v-on:事件名="函数名"// 简写@事件名="函数名"

示例

给一个按钮绑定点击事件template部分

<button @click="handleClick">点击</button>

js部分​​​​​​​

methods: {  handleClick() {    alert('hello')  }}

●methods中定义的函数会挂载到vm实例对象上
●methods中定义的普通函数内部this指向vm
●methods中, 不推荐使用箭头函数

3) 是否加括号

●不加括号(70%): 直接写函数名称, 可以在回调函数中, 直接拿到事件对象event
●加括号(20%): 加括号主要为了传参, 在回调函数中, 拿到参数
●加括号(10%): 有时, 除了拿到参数外, 还需要原生的事件对象, 通过$event传递
示例​​​​​​​

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <!-- 访问vm实例上的属性 -->
      <!-- 70%: 在指令表达式中不加(). 就可以通过默认参数获取事件对象 -->      <button @click="handleClick">点击了{{count}}次</button>
      <!-- 20%: 加() 目的是为了传参数 -->      <button @click="handleClick(100)">点击了{{count}}次</button>
      <!-- 10%: 加() 在参数的最后, 通过$event也可以将事件对象传递 -->      <button @click="handleClick(100, $event)">点击了{{count}}次</button>    </div>
    <script>      const { createApp } = Vue
      const vm = createApp({        data() {          return {            count: 0,          }        },        methods: {          // 在methods中定义的就是事件回调函数, 默认情况可以接收事件对象 做为参数          handleClick(a, b) {            console.log(a, b)            // 事件回调. 当点击事件触发, 会被调用            this.count++          },        },      }).mount('#app')
      // const div = document.querySelector('#app')      // div.addEventListener('click', function (e) {      //   console.log(e)      // })</script>  </body></html>

4) 事件修饰符

在绑定事件的时候, 可以添加事件修饰符, 常用的事件修饰符如下:
●.prevent: 阻止默认行为
●.stop: 阻止冒泡
●.once: 事件只会触发一次

示例prevent示例​​​​​​​

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <a @click.prevent="" href="http://www.baidu.com">baidu</a>    </div>
    <script>      const { createApp } = Vue
      const vm = createApp({}).mount('#app')
      // 原生js方式      // document.querySelector('a').addEventListener('click', function (e) {      //   // 调用事件对象的preventDefault方法, 阻止默认行为      //   // 对于a元素而言, 默认行为就是跳转页面      //   e.preventDefault()      // })</script>  </body></html>

stop示例​​​​​​​

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <ul @click="handleUl">        <!--           1. `.stop` 阻止事件向上冒泡          2. 事件修饰符可以连用         -->        <li @click.stop="handleLi">1</li>        <li>2</li>        <li>3</li>      </ul>    </div>
    <script>      const { createApp } = Vue
      const vm = createApp({        methods: {          handleUl() {            console.log('ul被点击了...')          },          handleLi() {            console.log('li被点击了...')          },        },      }).mount('#app')</script>  </body></html>


5) 按键修饰符

主要针对键盘事件
常用按键修饰符
●.enter: 回车键
●.up: 上
●.down: 下
●.left: 左
●.right: 右
系统功能键
●.ctrl
●.alt
●.shift
示例​​​​​​​

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <input type="text" @keyup.enter="submit" />    </div>
    <script>      const { createApp } = Vue
      const vm = createApp({        methods: {          submit() {            console.log('输入了数据, 按下回车键')          },        },      }).mount('#app')</script>  </body></html>

指令语法的完整示意图:

图片

 

双向绑定指令

1) 什么是双向绑定
双向绑定指令通常应用于表单元素
●数据的改变会影响视图
●视图的改变会影响数据

2) 原理
表单元素, 如inputselecttextarea是具有交互性的:用户可以操作
当用户操作时, 会触发特定的事件如:input事件change事件
在事件处理的回调中, 可以对数据进行修改双向绑定原理
1通过绑定input框的value属性和data中的一个变量, 实现了数据->视图的绑定
2监听input框的input事件, 当事件触发时, 更新data中的变量, 实现了视图->数据的绑定

3) 简写指令
v-model: 双向绑定指令
将表单元素的 值 和 data中定义的状态绑定💡注意
不同的表单元素, 绑定的属性和监听的事件不同

图片


作业
使用v-model实现一个form表单

图片

 

应用实例条件渲染

1) 什么是条件渲染


当条件满足时, 渲染到页面
主要指令:v-if和v-show

2) 示例​​​​​​​

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <!-- 当一个内容有复杂逻辑时, 使用v-if -->      <div v-if="flag">我是通过v-if控制的</div>      <div v-else>我是通过v-else控制的</div>      <!-- 当一个内容需要切换显示时, 使用v-show -->      <div v-show="flag">我是通过v-show控制的</div>      <div v-show="!flag">我是通过v-show控制的</div>    </div>
    <script>      const { createApp } = Vue
      const vm = createApp({        data() {          return {            flag: true,          }        },      }).mount('#app')</script>  </body></html>

●当flag为true时, 两个元素都可以显示
●当flag为false时, 两个元素都不显示,区别是
○v-if: 不会创建元素
○v-show: 创建元素, 但是display=none

3) 使用表达式

在指令表达式中, 除了使用变量外, 也可以使用表达式

<div v-if="flag == true">这是用v-if渲染的元素</div>

案例
💡需求
通过按钮控制元素的显示/隐藏
示例​​​​​​​

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <button @click="flag = !flag">切换显示/隐藏</button>      <div v-show="flag">div显示的内容</div>    </div>
    <script>      const { createApp } = Vue
      const vm = createApp({        data() {          return {            flag: true,          }        },        methods: {          toggle() {            // if (this.flag == true) {            //   this.flag = false            // } else {            //   this.flag = true            // }            this.flag = !this.flag          },        },      }).mount('#app')</script>  </body></html>

●绑定按钮的点击事件
○当flag==true时点击, flag先取反, 再保存, 此时flag为false
○当flag==false时点击, flag先取反, 再保存, 此时flag为true

 

列表渲染

1) 什么是列表渲染


列表渲染也称"循环渲染", 通过v-for遍历数组或者对象

2) 遍历数组

获取元素
如果只希望得到每个数组元素的值, 不需要得到下标
语法

v-for="item in items"

示例​​​​​​​

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <ul>        <!-- 在指令表达式中, in前面的参数表示数组元素 -->        <!-- <li v-for="item in items">{{item}}</li> -->        <!-- (元素, 下标) in 数组 -->        <li v-for="(value, key) in items">{{key}} -- {{value}}</li>      </ul>    </div>
    <script>      const { createApp } = Vue
      const vm = createApp({        data() {          return {            items: ['test1', 'test2', 'test3'],          }        },      }).mount('#app')</script>  </body></html>

获取元素和下标
如果只希望得到每个数组元素的值和下标
语法

v-for="(item, index) in items"

3) 遍历对象

●只取值:v-for="value in obj"
●取键和值:v-for="(value, key) in obj"
●取键和值和索引:v-for="(value, key, index) in obj"

4) 绑定key


在遍历时, 通常会给每个渲染的元素绑定一个唯一值key

什么是key
key是Vue内置的属性,不会渲染到DOM中

语法

<li v-for="item in items" :key="item.id">

key的作用
key是vue给每个元素定义的唯一标识, 来用复用DOM
💡需求
1制作一个人员列表, 如下

图片


2在输入框中依次输入对应的名字
3当点击按钮时, 在列表的最上方添加一个用户:小强

示例​​​​​​​

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <h1>用户列表</h1>      <button @click="addUser">添加一个用户</button>      <ul>        <li v-for="user in users" :key="user.id">          {{user.name}}          <input type="text" />        </li>      </ul>    </div>
    <script>      const { createApp } = Vue
      const vm = createApp({        data() {          return {            users: [              { id: 1, name: '小明' },              { id: 2, name: '小美' },              { id: 3, name: '小胖' },            ],          }        },        methods: {          addUser() {            this.users.unshift({ id: 4, name: '小强' })          },        },      }).mount('#app')</script>  </body></html>

期望的结果

图片


实际的情况

图片


为什么会出现这种现象呢?
原因
vue在渲染每个元素时, 会给元素设置一个自定义属性key
●根据元素的key直接复用之前的DOM, 不会生成新的DOM

图片


 

图片

 

样式绑定

1) 什么是样式绑定


通过绑定class属性 或者style属性 修改样式

2) 绑定class属性


常见有两种语法
●数组写法
●对象写法
示例​​​​​​​

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>    <style>      .red {        color: red;      }      .blue {        color: skyblue;      }</style>  </head>  <body>    <div id="app">      <!-- 原生的写法 -->      <span class="red blue">一段文字</span>
      <!-- 绑定class属性 -- 对象的写法 -->      <span :class="obj">对象的写法</span>
      <!-- 绑定class属性 -- 数组的写法(推荐) -->      <span :class="arr">数组的写法</span>
      <span :class="foo">绑定一个变量</span>
      <span :class="flag ? 'red' : 'blue'">使用表达式</span>    </div>
    <script>      const { createApp } = Vue
      const vm = createApp({        data() {          return {            obj: {              red: true,              blue: true,            },            arr: ['red', 'blue'],            foo: 'red',            flag: true,          }        },      }).mount('#app')</script>  </body></html>

3) 绑定style属性对象写法


示例​​​​​​​

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <script src="../node_modules/vue/dist/vue.global.js"></script>  </head>  <body>    <div id="app">      <!-- 原生的写法 -->      <div style="font-size: 32px; color: red">原生的写法</div>      <!-- 绑定style属性 -- 对象写法 -->      <div :style="obj">对象的写法</div>    </div>
    <script>      const { createApp } = Vue
      const vm = createApp({        data() {          return {            obj: {              // 'font-size': '32px',              fontSize: '32px',              color: 'red',            },          }        },      }).mount('#app')</script>  </body></html>

4) 作业需求


实现京东tab栏切换

图片

参考答案​​​​​​​

<!DOCTYPE html><html lang="en">  <head>    <meta charset="UTF-8" />    <meta http-equiv="X-UA-Compatible" content="IE=edge" />    <meta name="viewport" content="width=device-width, initial-scale=1.0" />    <title>Document</title>    <!-- 1.1 引入vue.js -->    <script src="../node_modules/vue/dist/vue.global.js"></script>    <!-- 2.2 实例静态页面(CSS部分) -->    <style>      * {        margin: 0;        padding: 0;      }      li {        list-style: none;      }
      .menu-tab {        display: flex;        justify-content: space-between;        margin: 50px auto;        height: 40px;        width: 700px;        border: 1px solid #eee;        border-bottom: 1px solid #e4393c;        background-color: #f7f7f7;        box-sizing: border-box;      }      .menu-tab .menu-item {        flex: 1;        display: flex;        justify-content: center;        align-items: center;
        font-size: 14px;        color: #666;        cursor: pointer;      }      .menu-tab .menu-item:hover {        color: #e4393c;      }      .menu-tab .menu-item.current {        color: #fff;        background-color: #e4393c;      }</style>  </head>  <body>    <!-- 1.2 编写页面容器 -->    <div id="app">      <!-- 2.1 实例静态页面(HTML部分) -->      <ul class="menu-tab">        <!-- <li          v-for="(item, index) in items"          class="menu-item"          :class="index == active ? 'current' : '' "          @click="active = index"        > -->        <li          v-for="(item, index) in items"          class="menu-item"          :class="index == active ? 'current' : '' "          @click="handleClick(index)"        >          {{item}}        </li>      </ul>    </div>
    <!-- 1.3 创建vue实例对象 -->    <script>      const { createApp } = Vue
      const vm = createApp({        data() {          return {            items: ['商品介绍', '规格与包装', '售后保障', '商品评价(2000+)', '手机社区'],            active: 0,          }        },        methods: {          handleClick(i) {            console.log(i)            this.active = i          },        },      }).mount('#app')</script>  </body></html>

图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值