Vuejs(一):Vuejs模板语法

一:vuejs介绍

Vue (读音 /vjuː/,类似于 view)
Vue是一个渐进式的框架,什么是渐进式的呢?

  • 渐进式意味着你可以将Vue作为你应用的一部分嵌入其中,带来更丰富的交互体验。
  • 或者如果你希望将更多的业务逻辑使用Vue实现,那么Vue的核心库以及其生态系统。
  • 比如Core+Vue-router+Vuex,也可以满足你各种各样的需求。

Vue有很多特点和Web开发中常见的高级功能

  • 解耦视图和数据
  • 可复用的组件
  • 前端路由技术
  • 状态管理
  • 虚拟DOM

二:修改webstorm为2个空格

Vuejs基础语法
Vuejs基础语法
Vuejs基础语法

三:插值操作

<div id="app">
<!--  mustach语法,不仅仅可以直接写变量,也可以写简单的表达式 -->
  <h2>{{message}}</h2>
  <h2>{{firstName + lastName}}</h2>
  <h2>{{firstName + ' ' + lastName}}</h2>
  <h2>{{firstName}} {{lastName}}</h2>
  <h2>{{counter * 2}}</h2>
</div>

3.1 v-once

该指令后面不需要跟任何表达式(比如之前的v-for后面是由跟表达式的)
该指令表示元素和组件只渲染一次,不会随着数据的改变而改变。

<div id="app">
  <h2>{{message}}</h2>
  <h2 v-once>{{message}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      message: 'Hello',
    }
  })
</script>

v-once

3.2 v-html

某些情况下,我们从服务器请求到的数据本身就是一个HTML代码,如果我们直接通过{{}}来输出,会将HTML代码也一起输出。 但是我们可能希望的是按照HTML格式进行解析,并且显示对应的内容。

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

  • 可以使用v-html指令
  • 该指令后面往往会跟上一个string类型
  • 会将string的html解析出来并且进行渲染
<div id="app">
  <h2>{{url}}</h2>
  <h2 v-html="url"></h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      url: '<a href="https://www.badiu.com">Baidu</a>'
    }
  })
</script>

vuejs基础语法

3.3 v-pre

v-pre用于跳过这个元素和它子元素的编译过程,用于显示原本的Mustache语法。
比如下面的代码:

  • 第一个h2元素中的内容会被编译解析出来对应的内容
  • 第二个h2元素中会直接显示{{message}}
<div id="app">
  <h2>{{message}}</h2>
  <h2 v-pre>{{message}}</h2>
</div>

Vuejs基础语法

3.4 v-cloak

在某些情况下,我们浏览器可能会直接显然出未编译的Mustache标签。
cloak: 斗篷

  <style>
    [v-cloak] {
      display: none;
    }
  </style>
</head>
<body>
<div id="app">
  <h2 v-cloak>Hello {{message}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  # 在vue解析之前,div中有一个属性v-cloak
  # 在vue解析之后,div中没有一个属性v-cloak
  const app = new Vue({
    el: "#app",
    data: {
      message: 'Andy Low'
    }
  })
</script>

代码是由上而下执行的,当执行到div标签时,页面会直接显示{{message}},执行到js代码后才会将{{message}}替换为Andy Low,这样页面在显示时会出现一个闪动效果。

四:绑定属性(v-bind)

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

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

这个时候,我们可以使用v-bind指令:

  • 作用:动态绑定属性
  • 预期:any (with argument) | Object (without argument)
  • 参数:attrOrProp (optional)

v-bind用于绑定一个或多个属性值,或者向另一个组件传递props值
在开发中,有哪些属性需要动态进行绑定呢?
还是有很多的,比如图片的链接src、网站的链接href、动态绑定一些类、样式等等

<div id="app">
  <img v-bind:src="imgUrl" alt="">  # imgUrl如同上面的message一样,是data中定义的变量
  <a :href="aHref">Baidu</a>		# v-bind可以省略(语法糖)
</div>

4.1 v-bind绑定class

v-bind可以绑定普通字符串,对象,数组

<div id="app">
  <!-- {}表示是一个对象,里面写键值对 -->
  <h2 :class="{active:isActive, line:isLine}">{{message}}</h2>
  <button @click="btnClick">Button</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      message: 'Andy Low',
      isActive: true,
      isLine: true
    },
    methods: {
      btnClick: function() {
        this.isActive = !this.isActive
      }
    }
  })
</script>

如果过于复杂,可以入在一个methods或者computed中:

<div id="app">
  <!-- {}表示是一个对象,里面写键值对 -->
  <h2 :class="getClasses()">{{message}}</h2>
  <button @click="btnClick">Button</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      message: 'Andy Low',
      isActive: true,
      isLine: true
    },
    methods: {
      btnClick: function() {
        this.isActive = !this.isActive
      },
      getClasses: function() {
        return {active:this.isActive, line:this.isLine}
      }
    }
  })
</script>

v-bind的数组语法:

<div id="app">
  <!-- [active, line]数组中的元素不加引号是变量,加引号是普通字符串 -->
  <h2 :class="[active, line]" class="title">{{message}}</h2>
</div>

4.2 v-bind绑定style

在写CSS属性名的时候,比如font-size

  • 我们可以使用驼峰式 (camelCase) fontSize
  • 或短横线分隔 (kebab-case,记得用单引号括起来) ‘font-size’

绑定方式一:对象语法

:style="{color: currentColor, fontSize: fontSize + 'px'}"

绑定方式二:数组语法

<div v-bind:style="[baseStyles, overridingStyles]"></div>

如果过于复杂,可以放到methods或computed中:

<template>
  ..................................
    <div :style="activeStyle"><slot name="item-text"></slot></div>
  </div>
</template>

<script>
  export default {
    name: "TabBarItem",
    props: {
      path: String,
      activeColor: {
        type: String,
        default: 'red',
      }
    },
    data() {
      return {
      }
    },
    computed: {
      isActive() {
        return this.$route.path.indexOf(this.path) != -1
      },
      activeStyle() {
        return this.isActive ? {color: this.activeColor} : {}
      }
    },
    ....................
  }
</script>

五:计算属性

5.1 基础使用

我们知道,在模板中可以直接通过插值语法显示一些data中的数据。
但是在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示

  • 比如我们有firstName和lastName两个变量,我们需要显示完整的名称。
  • 但是如果多个地方都需要显示完整的名称,我们就需要写多个{{firstName}} {{lastName}}
<div id="app">
  <h2>{{fullName}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      firstName: 'Andy',
      lastName: 'Low'
    },
    computed: {
      fullName: function() {
        return this.firstName + ' ' + this.lastName
      }
    }
  })
</script>

计算属性较为复杂的操作:

<div id="app">
  <h2>总价格:{{totalPrice}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      books: [
        {id: 110, name: 'Unix', price: 119},
        {id: 113, name: 'Linux', price: 90},
        {id: 115, name: 'Python', price: 50},
        {id: 118, name: 'Java', price: 158}
      ]
    },
    computed: {
      totalPrice: function() {
        let result = 0
        for (let i = 0; i < this.books.length; i++) {
          result += this.books[i].price
        }
        return result
      }
    }
  })
</script>

5.2 setter与getter

计算属性中的方法完整的写法如下:

computed: {
      fullName: {
        set: function() {
          // 设置fullName值时会被调用
          console.log('------');
        },
        get: function() {
          return 'abc'
        }
      }
    }

由于一般我们在计算属性中的方法不需要做设置值的操作,也就是方法中只有get方法,于是我们简写成了上面5.1节中的写法

5.3 计算属性的缓存

我们可能会考虑这样的一个问题:

  • methods和computed看起来都可以实现我们的功能,
  • 那么为什么还要多一个计算属性这个东西呢?
  • 原因:计算属性会进行缓存,如果多次使用时,计算属性只会调用一次;而methods中的方法调用几次会执行几次

六: 事件监听

在前端开发中,我们需要经常和用户进行交互。

  • 这个时候,我们就必须监听用户发生的时间,比如点击、拖拽、键盘事件等等
  • 在Vue中如何监听事件呢?使用v-on指令
    v-on介绍
  • 作用:绑定事件监听器
  • 缩写:@
  • 预期:Function | Inline Statement | Object
  • 参数:event

6.1 v-on参数

当通过methods中定义方法,以供@click调用时,需要注意参数问题:

  • 情况一:如果该方法不需要额外参数,那么方法后的()可以不添加。但是注意:如果方法本身中有一个参数,那么会默认将原生事件event参数传递进去
  • 情况二:如果既要传入某个参数,又要传递event时,可以通过$event传入事件。
<div id="app">
  <button @click="btnClick()">Button1</button>
  <button @click="btnClick">Button2</button>
  <!-- 如果btn2Click方法需要一个参数,但这里在监听时没有给参数,那么vue会默认将浏览器生成的event事件作为参数传递到函数中 -->
  <button @click="btn2Click(123)">Button3</button>
  <button @click="btn3Click(10, $event)">Button4</button>
</div>

6.2 v-on修饰符

在某些情况下,我们拿到event的目的可能是进行一些事件处理。
Vue提供了修饰符来帮助我们方便的处理一些事件:

  • .stop - 调用 event.stopPropagation(),阻止冒泡
  • .prevent - 调用 event.preventDefault(),阻止默认事件
  • .{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
  • .native - 监听组件根元素的原生事件。
  • .once - 只触发一次回调
<div id="app">
  <div @click="divClick">
    <button @click.stop="btnClick">Button</button>		# .stop阻止冒泡
  </div>
</div>

其它修饰符:

<button @click.prevent></button>				# 阻止默认行为
<form action="" @submit.prevent></form>			# 阻止默认行为,没有表达式
<button @click.stop.prevent></button>			# 串联修饰符
<input type="text" @keyup.enter="onEnter">		# 键修饰符,键别名
<input type="text" @keyup.13="onEnter">			# 键修饰符,键代码
<button @click.once="doThis"></button>			# 点击回调只会触发一次

七: 条件判断

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

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

v-if的原理:

  • v-if后面的条件为false时,对应的元素以及其子元素不会渲染。也就是根本没有不会有对应的标签出现在DOM中。
<div id="app">
  <h2 v-if="score>=90">优秀</h2>
  <h2 v-else-if="score>=80">良好</h2>
  <h2 v-else-if="score>=60">及格</h2>
  <h2 v-else>不及格</h2>
</div>

7.1 切换小案例

<div id="app">
  <span v-if="isUser">
    <label for="username">username</label>
    <input type="text" id="username" placeholder="username">
  </span>
  <span v-else>
    <label for="email">email</label>
    <input type="text" id="email" placeholder="email">
  </span>
  <button @click="isUser = !isUser">Switch</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      isUser: true
    }
  })
</script>

该案例很简单,点击按钮时input输入框进行切换。但是你会发现如果我们在有输入内容的情况下,切换了类型,会发现文字依然显示之前的输入的内容。按道理讲,我们应该切换到另外一个input元素中了。在另一个input元素中,我们并没有输入内容。为什么会出现这个问题呢?
这是因为Vue在进行DOM渲染时,出于性能考虑,会尽可能的复用已经存在的元素,而不是重新创建新的元素。在上面的案例中,Vue内部会发现原来的input元素不再使用,直接作为else中的input来使用了。
解决方案:如果我们不希望Vue出现类似重复利用的问题,可以给对应的input添加key,并且我们需要保证key的不同

<input type="text" id="username" placeholder="username" key="username">
<input type="text" id="email" placeholder="email" key="email">

7.2 v-show

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

  • v-if当条件为false时,压根不会有对应的元素在DOM中。
  • v-show当条件为false时,仅仅是将元素的display属性设置为none而已。

开发中如何选择呢?

  • 当需要在显示与隐藏之间切片很频繁时,使用v-show
  • 当只有一次切换时,通过使用v-if

八: 循环遍历

8.1 遍历数组

  <ul>
    <li v-for="item in movies">{{item}}</li>
    <li>-------------------------------</li>
    <li v-for="(item,index) in movies">{{index}} - {{item}}</li>	# index为数组下标
  </ul>

8.2 遍历对象

  <ul>
    <!-- 下面item获取到的是对象的value -->
    <li v-for="item in info">{{item}}</li>
    <!-- 下面的遍历获取到的是对象的value,key -->
    <li v-for="(value,key) in info">{{key}} - {{value}}</li>
    <!-- 下面的遍历获取到的是对象的value,key,index -->
    <li v-for="(value,key,index) in info">{{key}} - {{value}} - {{index}}</li>
  </ul>

8.3 key属性

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

8.4 检测数组更新

因为Vue是响应式的,所以当数据发生变化时,Vue会自动检测数据变化,视图会发生对应的更新。
Vue中包含了一组观察数组编译的方法,使用它们改变数组也会触发视图的更新。

		// 1: push
        this.letters.push('FF')
        // 2: pop
        this.letters.pop()
        // 3: unshift 向数组的开头添加一个或更多元素,并返回新的长度
        this.letters.unshift('why', 'zs')
        // 4: shift 把数组的第一个元素从其中删除,并返回第一个元素的值
        this.letters.shift()
        // 5: splice 传递一个参数(index),将对应index以及后面的所有元素删除
        this.letters.splice(2)
        // 6: sort 排序
        this.letters.sort()
        // 7:reverse
        this.letters.reverse()

并不是所有的操作都是响应式的:

btnClick() {
        // this.letters[1] = 'kobe'			# 该操作改变了数组,但页面不会立即渲染
        # 下面的操作都是响应式
        this.letters.splice(1,1,'kobe')
        # set(要修改的对象,索引值,修改后的值)
        Vue.set(this.letters, 1, 'kobe')
      }

九: v-model

表单控件在实际开发中是非常常见的。特别是对于用户信息的提交,需要大量的表单。
Vue中使用v-model指令来实现表单元素和数据的双向绑定。

<input type="text" v-model="message">
<h2>{{message}}</h2>

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

9.1 v-model原理

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

  • v-bind绑定一个value属性
  • v-on指令给当前元素绑定input事件
<div id="app">
  <input type="text" :value="message" @input="valueChange">
  <h2>{{message}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      message: 'Hello'
    },
    methods: {
      valueChange(event) {
        this.message = event.target.value
      }
    }
  })
</script>

9.2 v-model与radio

<div id="app">
  <label for="male">
    <input type="radio" id="male" name="sex" value="male" v-model="sex">Male
  </label>
  <label for="female">
    <input type="radio" id="female" name="sex" value="female" v-model="sex">Female
  </label>
  <h2>你的选择是:{{sex}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      sex: 'male'	# 默认选择male
    },
  })
</script>

注意:radio类型中必须有name属性,否则不能互斥(两个都可以选择),如果使用了v-model进行双向绑定时,name属性可以不写,radio也是互斥的

9.3 v-model与checkbox

单个勾选框:

  • v-model即为布尔值。
  • 此时input的value并不影响v-model的值
<div id="app">
  <label for="agree">
    <input type="checkbox" id="agree" v-model="isAgree">同意协议
  </label>
  <h2>你选择的是:{{isAgree}}</h2>
  <button :disabled="!isAgree">下一步</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      isAgree: false
    },
  })
</script>

多个复选框:

  • 当是多个复选框时,因为可以选中多个,所以对应的data中属性是一个数组。
  • 当选中某一个时,就会将input的value添加到数组中。
<div id="app">
    <input type="checkbox" value="football" v-model="hobbies">Football
    <input type="checkbox" value="basketball" v-model="hobbies">BasketBall
    <input type="checkbox" value="tennis" v-model="hobbies">Tennis
    <h2>你的爱好是:{{hobbies}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      hobbies: []
    },
  })
</script>

9.4 v-model与select

单选:只能选中一个值。

  • v-model绑定的是一个值。
  • 当我们选中option中的一个时,会将它对应的value赋值到mySelect中
<div id="app">
  <select name="fruit" id="" v-model="fruit">
    <option value="Apple">Apple</option>
    <option value="Pear">Pear</option>
    <option value="Banana">Banana</option>
    <option value="Orange">Orange</option>
  </select>
  <h2>your choice is: {{fruit}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      fruit: 'Orange'
    },
  })
</script>

多选:可以选中多个值。

  • v-model绑定的是一个数组。
  • 当选中多个值时,就会将选中的option对应的value添加到数组mySelects中
<div id="app">
  <select name="fruits" id="" v-model="fruits" multiple>
    <option value="Apple">Apple</option>
    <option value="Pear">Pear</option>
    <option value="Banana">Banana</option>
    <option value="Orange">Orange</option>
  </select>
  <h2>your choice is: {{fruits}}</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  const app = new Vue({
    el: "#app",
    data: {
      fruits: []
    },
  })
</script>

9.5 修饰符

lazy修饰符:

  • 默认情况下,v-model默认是在input事件中同步输入框的数据的。
  • 也就是说,一旦有数据发生改变对应的data中的数据就会自动发生改变。
    lazy修饰符可以让数据在失去焦点或者回车时才会更新:
<input type="text" v-model.lazy="message">
<p>当前内容:{{message}}</p>

number修饰符:

  • 默认情况下,在输入框中无论我们输入的是字母还是数字,都会被当做字符串类型进行处理。
  • 但是如果我们希望处理的是数字类型,那么最好直接将内容当做数字处理。
    number修饰符可以让在输入框中输入的内容自动转成数字类型:
<input type="number" v-model.number="age">
<p>age: {{age}}, type: {{typeof age}}</p>

trim修饰符:

  • 如果输入的内容首尾有很多空格,通常我们希望将其去除
  • trim修饰符可以过滤内容左右两边的空格
<input type="text" v-model.trim="message">
发布了45 篇原创文章 · 获赞 3 · 访问量 1535

猜你喜欢

转载自blog.csdn.net/pcn01/article/details/102974697
今日推荐