0
点赞
收藏
分享

微信扫一扫

Vue 基础指令

丹柯yx 2022-04-02 阅读 64
vue.js

Vue 基础指令(模板语法)

✍目录总览:(模板语法概述、基础指令

Vue模板语法

1. 如何理解前端渲染?

  • 把数据填充到HTML标签中

2. 前端渲染的方式

  • 前端渲染的方式主要有三种:
    • 原生js拼接字符串
    • 使用前端模板引擎
    • 使用vue特有的模板语法
2.1 原生js拼接字符串
  • 基本上就是将数据以字符串的方式拼接到HTML标签中,前端代码风格大体上如下图所示。
var d = data.weather;
var info = document.getElementById('info');
info.innerHTML = '';
for(var i=0;i<d.length;i++){
	var date = d[i].date;
	var day = d[i].info.day;
	var night = d[i].info.night;
	var tag = '';
	tag += '<span>日期:'+date+'</sapn><ul>';
	tag += '<li>白天天气:'+day[1]+'</li>'
	tag += '<li>白天温度:'+day[2]+'</li>'
	tag += '<li>白天风向:'+day[3]+'</li>'
	tag += '<li>白天风速:'+day[4]+'</li>'
	tag += '</ul>';
	var div = document.createElement('div');
	div.innerHTML = tag;
	info.appendChild(div);
}

**缺点:**不同开发人员的代码风格差别很大,随着业务的复杂,后期的维护变得逐渐困难起来。

2.2 使用前端模板引擎
  • 下图代码是基于模板引擎art-template的一段代码,与拼接字符串相比,代码明显规范了很多,它拥有自己的一套模板语法规则
<script id="abc" type="text/html">
	{{if isAdmin}}
	<h1>{{title}}</h1>
	<ul>
		{{each list as value i}}
			<li>索引 {{i + 1}} :{{value}}</li>
		{{/each}}
	</ul>
	{{/if}}
</script>

**优点:**大家都遵循同样的规则写代码,代码可读性明显提高了,方便后期的维护。

**缺点:**没有专门提供事件机制。

2.3 使用vue特有的模板语法(重点)
  • Vue基础指令:

    • 差值表达式

    • 指令

    • 事件绑定

    • 属性绑定

    • 样式绑定

    • 分支循环结构

Vue指令

一、内容渲染指令

1.1 插值表达式(mustache语法)

内容渲染指令就是插值操作,如何将data中的文本数据,插入到HTML中呢?插值表达式

可以通过Mustache语法(也就是 双大括号{{}}),也叫做插值表达式
  1. 双括号里面是变量
<div id="app">
  <h1>{{message}}</h1>
</div>

<script src="../js/vue.js"></script>
<script>
   // 1.创建Vue的实例对象
   const app = Vue.createApp({
    data(){
      return {
        message: '你好Vue3!'
      }
    }
   }).mount('#app');
</script>

  1. 双括号里面是表达式
<div id="app">
  <h1>{{message}}</h1>
  <h1>{{message+site}}</h1>
  </div>

<script src="../js/vue.js"></script>
<script>
   // 1.创建Vue的实例对象
   const app = Vue.createApp({
    data(){
      return {
        message: '你好Vue3!',
        site: 'www.newmood.top',
      }
    }
   }).mount('#app');
</script>

  1. 双括号里面表达式加空格或者字符
<div id="app">
  <h1>{{message}}</h1>
  <h1>{{message+ '空格或者字符' + site}}</h1>
</div>

<script src="../js/vue.js"></script>
<script>
   // 1.创建Vue的实例对象
   const app = Vue.createApp({
    data(){
      return {
        message: '你好Vue3!',
        site: 'www.newmood.top',
      }
    }
   }).mount('#app');
</script>

  1. 双括号后加双括号
<div id="app">
  <h1>{{message}}</h1>
  <h1>{{message}} {{site}}</h1>
</div>

<script src="../js/vue.js"></script>
<script>
   // 1.创建Vue的实例对象
   const app = Vue.createApp({
    data(){
      return {
        message: '你好Vue3!',
        site: 'www.newmood.top',
      }
    }
   }).mount('#app');
</script>

  1. 双括号后跟字符
<div id="app">
  <h1>{{message}}</h1>
  <h1>{{message}},生命里那束光</h1>
</div>

<script src="../js/vue.js"></script>
<script>
   // 1.创建Vue的实例对象
   const app = Vue.createApp({
    data(){
      return {
        message: '你好Vue3!',
        site: 'www.newmood.top',
      }
    }
   }).mount('#app');
</script>

  1. 双括号只能写在标签内部,不能写在标签属性里面
<div id="app">
  <h1>{{message}}</h1>
  <!-- <h1 {{message}}> {{message}},生命里那束光 </h1> 报错--> 
</div>
  1. 双括号里面还能进行变量计算
<div id="app">
  <h1>{{message}}</h1>
  <h1>计算{{count * 2}}</h1>
</div>

1.2 v-once

我们有时候希望展示的部分数据不会随着Vue的响应式而发生变化,要怎么做呢?先来看一个例子:

<div id="app">
  <h1>会变化{{message}}</h1>
  <h1>不会变化{{message}}</h1>
</div>

<script src="../js/vue.js"></script>
<script>
   // 1.创建Vue的实例对象
   const app = Vue.createApp({
    data(){
      return {
        message: '你好Vue3',
      }
    }
   }).mount('#app');
</script>

我们在Console控制台修改 app.messgae="Vue3",会发现message都发生了变化

要想第二个message不发生变化,我们给第二个h1标签添加v-once属性

<div id="app">
  <h1>会变化{{message}}</h1>
  <h1 v-once>不会变化{{message}}</h1>
</div>

1.3 v-text

v-text 作用和 插值表达式 比较相似:都是用于将数据显示在界面中

  • v-text 是放在标签属性中
<div id="app">
  <h1>{{message}}</h1>
  <h1 v-text="message"></h1>
</div>

  • 对于v-text和插值表达式语法,我们更推荐使用插值表达式语法。

1.4 v-html

某些情况下,我们从服务器请求到的数据本身就是一个HTML代码

  • 如果我们直接通过{{}} 来输出,会将HTML代码也一起输出

  • 但是我们希望是按照HTML格式进行解析,并且显示对应的内容

如果我们希望解析出HTML展示

  • 可以使用v-html指令
  • 该指令后面往往会跟上一个string类型
  • 会将string的html解析出来并且进行渲染

我们来看一个插值表达式例子:

<div id="app">
  <h1>{{site}}</h1>
</div>

<script src="../js/vue.js"></script>
<script>
   // 1.创建Vue的实例对象
   const app = Vue.createApp({
    data(){
      return {
        message: '你好Vue3!',
        site: '<a href="www.newmood.top">那束光の博客</a>'
      }
    }
   }).mount('#app');
</script>

  • 有时候服务器给客户端返回的数据是带标签的数据,我们客户端拿到之后解析肯定不能如上图那样直接使用 mustache 语法,我们要对其进行处理

1.5 v-pre

该指令的作用是用于跳过这个元素和它子元素的编译过程,用于显示原本的 Mustache 语法

一般我们的mustache语法会去data里面找对应的变量然后解析,可是如果我们就想让其显示为 {{message}} ,这个时候需要加 v-pre 属性,如下:

<div id="app">
  <h1>{{message}}</h1>
</div>

<script src="../js/vue.js"></script>
<script>
   // 1.创建Vue的实例对象
   const app = Vue.createApp({
    data(){
      return {
        message: '你好Vue3!',
      }
    }
   }).mount('#app');
</script>

我们给标签增加 v-pre 属性

<div id="app">
  <h1 v-pre>{{message}}</h1>
</div>

1.6 v-cloak

在实际开发中,我们data里面的数据可能是从服务器端获取来的,如果网络不好获取的比较慢,浏览器可能会直接显示出未编译的Mustache标签。那么页面在渲染时可能会先显示 {{message}} 之后变为 你好Vue3!。这种效果不是我们想要的,我们可以给标签添加 v-cloak 来避免这种效果。

解决办法:

  • 加上v-clock 属性,并加上css。
  • vue解析之前有 v-clock 属性时,让其不显示
  • Vue解析之后没有v-clock 属性,再让其显示
<style>
    [v-cloak] {
      display: none;
    }
</style>

<div id="app">
  <h1 v-cloak>{{message}}</h1>
</div>

<script>
  // 在vue解析之前, div中有一个属性v-cloak
  // 在vue解析之后, div中没有一个属性v-cloak
  setTimeout(function () {
    const app = new Vue({
      el: '#app',
      data: {
        message: '你好Vue3!'
      }
    })
  }, 1000)
</script>

二、属性绑定指令

2.1 v-bind

前面的指令主要作用是将值插入到我们的模板的内容当中,但是,除了内容需要动态来决定外,某些属性我们也希望动态来绑定。

  • 比如动态绑定a元素的 href 属性
  • 比如动态绑定img元素的 src 属性

绑定 href、src 用法

在实际开发中,照片img的url值可能也是由服务器端获取,a标签的href值可能也是由服务器端获取的,那么我们如何动态绑定呢?例如我们看下面的例子:

<div id="app">
  <h1>{{message}}</h1>
  <a href="url">百度</a>
</div>

<script src="../js/vue.js"></script>
<script>
   // 1.创建Vue的实例对象
   const app = Vue.createApp({
    data(){
      return {
        message: '你好Vue3!',
        url: 'http://www.baidu.com'
      }
    }
   }).mount('#app');
</script>

  • 如上图,我们给a标签的href是不能直接写url的,因为它不会解析。这个时候就需要给href前添加v-bind指令了。
<div id="app">
  <h1>{{message}}</h1>
  <a v-bind:href="url">百度</a>
</div>

语法糖写法如下:href="url"

<div id="app">
  <h1>{{message}}</h1>
  <a :href="url">百度</a>
</div>

三、样式绑定指令

3.1 class样式处理

  • 对象语法
<div v-bind:class="{ active: isActive }"></div>
  • 数组语法
<div v-bind:class="[activeClass, errorClass]"></div>

样式绑定相关语法细节:

  1. 对象绑定和数组绑定可以结合使用
<div v-bind:class='[activeClass, errorClass, {test: isTest}]'>测试样式</div>

data: {
	activeClass: 'active',
	errorClass: 'error',
	isTest: true
}
  1. class绑定的值可以简化处理
<div v-bind:class='arrClasses'>测试样式</div>
data: {
	arrClasses: ['active', 'error']
}
  1. 默认的class会保留(base)

3.2 style样式处理

  • 对象语法
<div v-bind:style="{ color: activeColor, fontSize: fontSize }"></div>
  • 数组语法
<div v-bind:style="[baseStyles, overridingStyles]"></div>

四、事件监听指令

4.1 v-on

1. Vue如何处理事件?

  • v-on指令用法
<input type=‘button' v-on:click='num++'/>
  • v-on简写形式
<input type=‘button' @click='num++'/>

2. 事件函数的调用方式

  • 直接绑定函数名称
<button v-on:click='say'>Hello</button>
  • 调用函数
<button v-on:click='say()'>Say hi</button>

3. 事件函数参数传递

  • 普通参数和事件对象
<button v-on:click='say("hi",$event)'>Say hi</button>

4.2 v-on修饰符

4. 事件修饰符

  • .stop 阻止冒泡
<a v-on:click.stop="handle">跳转</a>
  • .prevent 阻止默认行为
<a v-on:click.prevent="handle">跳转</a>

5. 按键修饰符

  • .enter 回车键
<input v-on:keyup.enter='submit'>
  • .esc 退出键
<input v-on:keyup.delete='handle'>

6. 自定义按键修饰符

  • 全局 config.keyCodes 对象
Vue.config.keyCodes.f1 = 112

4.3 小结

  • .stop - 调用 event.stopPropagation()
  • .prevent - 调用 event.preventDefault()
  • .{keyCode|keyAlias} - 只当事件是从特定键触发时才触发回调
  • .once - 只触发一次回调

五、条件渲染指令(分支结构)

条件渲染指令用来辅助开发者按需控制 DOM 的显示与隐藏 。

v - ifv-else-ifv-else

  • 这三个指令与JavaScript的条件语句 if、else、else if 类似
  • Vue 的条件指令可以根据表达式的值在DOM中渲染或销毁元素或组件

5.1 v-if

<div id="app">
  <p v-if="flag">今天要下雨</p>
  <p v-else>今天不要下雨</p>
</div>


<script src="../js/vue.js"></script>
<script>
   // 1.创建Vue的实例对象
   const app = Vue.createApp({
    data(){
      return{
        flag: true
      }
    }
   }).mount('#app');
</script>
</body>

v-if的原理:

  • v-if 后面的条件为 false时,对应的元素以及子元素不会渲染
  • 也就是根本没有对应的标签出现在DOM中

5.2 v-if、v-else-if、v-else

我们一般不会使用 v-else-if,因为这样的代码不美观,我们一般想要切换的话使用如下代码:

<body>
<div id="app">
  <p v-if="flag">今天要下雨</p>
  <p v-else>今天不要下雨</p>
  <button @click="toggle()">切换</button>
</div>

<script src="../js/vue.js"></script>
<script>
   // 1.创建Vue的实例对象
   const app = Vue.createApp({
    data(){
      return{
        flag: true
      }
    },
     methods:{
       toggle(){
         return this.flag = !this.flag;
       }
     }
   }).mount('#app');
</script>
</body>

5.3 v-show

v-show的用法和v-if非常相似,也用于决定一个元素是否渲染:

  • v-if 指令会 动态地创建或移除 DOM 元素 ,从而控制元素在页面上的显示与隐藏
  • v-show 指令会动态为元素 添加或移除 style=“display: none;” 样式 ,从而控制元素的显示与隐藏
<body>
<div id="app">
  <p v-show="flag">今天要下雨</p>
  <p v-show="!flag">今天不要下雨</p>
  <button @click="toggle()">切换</button>
</div>

<script src="../js/vue.js"></script>
<script>
   // 1.创建Vue的实例对象
   const app = Vue.createApp({
    data(){
      return{
        flag: true
      }
    },
     methods:{
       toggle(){
         return this.flag = !this.flag;
       }
     }
   }).mount('#app');
</script>
</body>

5.4 v-if与v-show的区别

  • v-if控制元素是否渲染到页面(是否创建)
  • v-show控制元素是否显示(已经创建,是否显示)
  1. 当需要在显示与隐藏之间切片很频繁时,使用 v-show
  2. 当只有一次切换时,通过 v-if

六、列表渲染指令(循环结构)

6.1 v-for(遍历数组)

  • 遍历数组
//语法1
<li v-for='item in list'>{{item}}</li>
//语法2
<li v-for='(item,index) in list'>{{item}} + '---' +{{index}}</li>

例子:

<div>水果列表</div>
    <ul>
      <li :key='item.id' v-for='(item, index) in myFruits'>
        <span>{{item.ename}}</span>
        <span>-----</span>
        <span>{{item.cname}}</span>
      </li>
    </ul>
</div>

data: {
        fruits: ['apple', 'orange', 'banana'],
        myFruits: [{
          id: 1,
          ename: 'apple',
          cname: '苹果'
        }, {
          id: 2,
          ename: 'orange',
          cname: '橘子'
        }, {
          id: 3,
          ename: 'banana',
          cname: '香蕉'
        }]
}

6.2 组件的key属性

  • 官方推荐我们在使用 v-for时,给对应的元素或组件加上一个 :key属性,key的作用主要是为了高效的更新虚拟DOM

  • 列表的数据变化时,默认情况下, vue 会尽可能的复用已存在的 DOM 元素,从而提升渲染的性能

  • 但这种默认的性能优化策略,会导致有状态的列表无法被正确更新 。为了给 vue 一个提示,以便它能跟踪每个节点的身份, 从而在保证有状态的列表被正确更新的前提下, 提升渲染的性能 。此时,需要为每项提供一个唯一的 key 属性

<div id="app">
  <ul>
    <li v-for="item in myFruits" :key="item">{{item.id}}</li>
  </ul>
</div>
  • key 的值只能是字符串或数字类型
  • key 的值必须具有唯一性(即:key 的值不能重复)
  • 建议把 数据项 id 属性的值 作为 key 的值(因为 id 属性的值具有唯一性)
  • 使用 index 的值当作 key 的值没有任何意义(因为 index 的值不具有唯一性)
  • 建议使用 v-for 指令时一定要指定 key 的值(既提升性能、又防止列表状态紊乱)
不绑定key的后果:

  • 向数组添加数据

6.3 v-for(遍历对象)

<div v-for='(value, key, index) in object'></div>
v-if和v-for结合使用
<div v-if='value==12' v-for='(value, key, index) in object'></div>

例子:

//v-if判断值为13的记录,进行输出  v-for对obj里面的属性进行遍历
<div id="app">
    <div v-if='v==13' v-for='(v,k,i) in obj'>{{v + '---' + k + '---' + i}}</div>
</div>
//定义的对象
data: {
        obj: {
          uname: 'zhangsan',
          age: 13,
          gender: 'female'
        }
}

七、双向绑定指令

7.1 v-model

  • 双向绑定指令也叫表单元素绑定,vue提供了 v-model 双向数据绑定 指令,用来辅助开发者在 不操作 DOM 的前提下, 快速获取表单的数据。
  • vue中使用 v-model 指令来实现表单元素和数据的双向绑定,经常用于表单 input 和 textarea 元素。
<body>
  <div id="app">
    <input type="text" v-model="message">
  </div>
  
  <script src="../js/vue.js"></script>
  <script>
     // 1.创建Vue的实例对象
     const app = Vue.createApp({
      data(){
        return {
          message: '你好Vue3!'
        }
      }
     }).mount('#app');
  </script>
</body>

理解双向绑定:

  • 我们来看上述代码,当我们在输入框输入内容时
  • 因为 input 中的 v-model 绑定了message,所以会实时的将输入的内容传递给 message,message发生改变。
  • 当message 发生改变时,因为上面我们使用 Mustache 语法,将 message 的值插入到 DOM 中,所以 DOM 会发生响应的改变。
  • 所以,通过 v-model 实现了 双向的绑定

7.2 v-model底层原理实现

v-model 其实是一个语法糖,它的背后本质上是包含两个操作:

  • v-bind 绑定一个 value 属性
  • v-on 指令给当前元素绑定 input 事件

也就是说下面的代码,等同于下面的代码:

<input type="text" v-model="message">
<!-- 等同于 -->
<input type="text" v-bind:value="message" v-on:input="message = $event.target.value">

7.3 dom类型与 v-model

v-model:radio(单选框)

使得单选框只能选一个

<body>
  <div id="app">
    <label><input name="sex" type="radio" value="男" v-model="sex">男</label>
    <label><input name="sex" type="radio" value="女" v-model="sex">女</label>

    <h2>选择的性别是:{{sex}}</h2>
  </div>



  <script src="../js/vue.js"></script>
  <script>
     // 1.创建Vue的实例对象
     const app = Vue.createApp({
      data(){
        return {
          sex: '男'
        }
      }
     }).mount('#app');
  </script>
</body>

v-model:checkbox(单/多勾选框)

复选框分为两种情况:单个勾选框多个勾选框

  • v-moduel 即为布尔值
  • 此时 input 的 value 并不影响v-model的值
<body>
  <div id="app">
    <label><input  type="checkbox"  v-model="isAgree">同意会员协议</label>
    <h2>是否同意协议:{{isAgree ? '同意' : '不同意'}}</h2>
  </div>


  <script src="../js/vue.js"></script>
  <script>
     // 1.创建Vue的实例对象
     const app = Vue.createApp({
      data(){
        return {
          isAgree: 'false'
        }
      }
     }).mount('#app');
  </script>
</body>

  • 当是多个复选框时,因为可以选中多个,所以对应的 data 中属性是一个数组
  • 当选中某一个时,就会将 input 的 value 添加到数组中
<body>
  <div id="app">
    <input type="checkbox" value="篮球" v-model="hobbies">篮球
    <input type="checkbox" value="足球" v-model="hobbies">足球
    <input type="checkbox" value="乒乓球" v-model="hobbies">乒乓球
    <input type="checkbox" value="羽毛球" v-model="hobbies">羽毛球
    <h2>您的爱好是: {{hobbies}}</h2>
  </div>

  <script src="../js/vue.js"></script>
  <script>
     const app = Vue.createApp({
      data(){
        return {
          hobbies: [], // 多选框,
        }
      }
     }).mount('#app');
  </script>
</body>

v-model:select(单选/多选下拉表单)

和 checkbox 一样,select 也分单选和多选两种情况

  • v-model 绑定的是一个值
  • 当我们选中 option 中的一个时,会将它对应的 vaule 赋值到 city 中
<body>
  <div id="app">
    <p>选择所在的城市:</p>
    <select name="city" v-model="city">
      <option value="上海">上海</option>
      <option value="北京">北京</option>
      <option value="天津">天津</option>
    </select>
    <p>选择的城市是:{{city}}</p>
  </div>



  <script src="../js/vue.js"></script>
  <script>
     // 1.创建Vue的实例对象
     const app = Vue.createApp({
      data(){
        return {
          city: '上海'
        }
      }
     }).mount('#app');
  </script>
</body>

  • v-model 绑定的是一个数组
  • 当选中多个值时,就会将选中的 option 对应的 value 添加到数组 mySelects中
<body>
  <div id="app">
    <p>选择所在的城市:</p>
    <select name="cities" v-model="cities" multiple>
      <option value="上海">上海</option>
      <option value="北京">北京</option>
      <option value="天津">天津</option>
    </select>
    <p>选择的城市是:{{cities}}</p>
  </div>



  <script src="../js/vue.js"></script>
  <script>
     // 1.创建Vue的实例对象
     const app = Vue.createApp({
      data(){
        return {
          cities: []
        }
      }
     }).mount('#app');
  </script>
</body>

7.4 v-model修饰符

为了方便对用户输入的内容进行处理,vue 为 v-model 指令提供了 3 个修饰符

修饰符作用示例
.number自动将用户的输入值转化为数值类型<input v-model.number = "age" />
.trim自动过滤用户输入的首尾空白字符<input v-module.trim = "msg" />
.lazychange 时而非 input 时更新(失去焦点或回车时)<input v-model.lazy = "msg" />
举报

相关推荐

0 条评论