Vue入门——基础语法

原文链接

Vue入门——基础语法

Vue是什么?

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

Vue的优势

对于前端开发人员来说,大家使用过很多的Javascript框架。比如原生的JavaScript,Jquery,angularjs和rectjs等。那么Vue与这些框架相比,它的优势体现在哪里?

  1. Vue 只关注视图层, 采用自底向上增量开发的设计。Vue关注的是视图层,操作的对象是HTML元素。它是渐进的,没有强主张,你可以在原有大系统的上面,把一两个组件改用它实现,当jQuery用;也可以整个用它全家桶开发,当Angular用;还可以用它的视图,搭配你自己设计的整个下层用。你可以在底层数据逻辑的地方用OO和设计模式的那套理念,也可以函数式,都可以,它只是个轻量视图而已,只做了自己该做的事,没有做不该做的事,仅此而已。
  2. Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。Vue.js 是一个更加灵活开放的解决方案。它允许你以希望的方式组织应用程序,而不是在任何时候都必须遵循 AngularJS 制定的规则,这让 Vue 能适用于各种项目.在 Vue 中指令和组件分得更清晰。指令只封装 DOM 操作,而组件代表一个自给自足的独立单元——有自己的视图和数据逻辑。
  3. Vue 学习起来非常简单.在 API 与设计两方面上 Vue.js非常简单,因此你可以快速地掌握它的全部特性并投入开发。Vue 的整体思想是拥抱经典的 Web 技术,并在其上进行扩展。基于 HTML 的模板使得将已有的应用逐步迁移到 Vue 更为容易。

声明式渲染

<div id="app"> {
  { message }} </div> 
var app = new Vue({  el: '#app', data: {  message: 'Hello Vue!' } }) 

如上几行代码就是一个简单的vue程序,你会发现id为app的div里显示了message的值,看起来这跟渲染一个字符串模板非常类似,但是 Vue 在背后做了大量工作。现在数据和 DOM 已经被建立了关联,所有东西都是响应式的。我们要怎么确认呢?打开你的浏览器的 JavaScript 控制台 (就在这个页面打开),并修改app.message的值,你将看到上例相应地更新。

指令

Vue有很多v-开头的指令,其本质是自定义属性。比如v-cloak,v-text,v-bind,v-model,v-on等等,下面将逐个介绍。

v-cloak

在上面的程序中,如果你的网速太慢,会发现最一开始网页会显示{ {message}}而非它的值,这涉及到Vue的生命周期,我们以后再聊。不过这样一个过程可能给用户带来不好的体验,因此你可以使用v-cloak指令防止页面加载时的闪烁。

<style type="text/css"> /* 1、通过属性选择器 选择到 带有属性 v-cloak的标签 让他隐藏 */ [v-cloak]{  /* 元素隐藏 */ display: none; } </style> <body> <div id="app"> <!-- 2、 让带有插值 语法的 添加 v-cloak 属性 在 数据渲染完场之后,v-cloak 属性会被自动去除, v-cloak一旦移除也就是没有这个属性了 属性选择器就选择不到该标签 也就是对应的标签会变为可见 --> <div v-cloak >{
  {msg}}</div> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> var vm = new Vue({  // el 指定元素 id 是 app 的元素  el: '#app', // data 里面存储的是数据 data: {  msg: 'Hello Vue' } }); </script> </body> </html> 

v-text

  • v-text指令用于将数据填充到标签中,作用于插值表达式类似,但是没有闪动问题
  • 如果数据中有HTML标签会将html标签一并输出
  • 注意:此处为单向绑定,数据对象上的值改变,插值会发生变化;但是当插值发生变化并不会影响数据对象的值
<div id="app"> <!-- 注意:在指令中不要写插值语法 直接写对应的变量名称 在 v-text 中 赋值的时候不要在写 插值语法 一般属性中不加 {
   {}} 直接写 对应 的数据名 --> <p v-text="msg"></p> <p> <!-- Vue 中只有在标签的 内容中 才用插值语法 --> {
  {msg}} </p> </div> <script> new Vue({  el: '#app', data: {  msg: 'Hello Vue.js' } }); </script> 

v-html

  • 用法和v-text相似 但是他可以将HTML片段填充到标签中
  • 可能有安全问题, 一般只在可信任内容上使用v-html,永不用在用户提交的内容上(因为谁也不知道某些傻叉用户会提交啥。。。)
  • 它与v-text区别在于v-text输出的是纯文本,浏览器不会对其再进行html解析,但v-html会将其当html标签解析后输出。
<div id="app"> <p v-html="html"></p> <!-- 输出:html标签在渲染的时候被解析 --> <p>{
  {message}}</p> <!-- 输出:<span>通过双括号绑定</span> --> <p v-text="text"></p> <!-- 输出:<span>html标签在渲染的时候被源码输出</span> --> </div> <script> let app = new Vue({  el: "#app", data: {  message: "<span>通过双括号绑定</span>", html: "<span>html标签在渲染的时候被解析</span>", text: "<span>html标签在渲染的时候被源码输出</span>", } }); </script> 

v-pre

  • 跳过编译过程显示原始信息
<span v-pre>{
  { this will not be compiled }}</span> <!-- 显示的是{
   { this will not be compiled }} --> <span v-pre>{
  {msg}}</span> <!-- 即使data里面定义了msg这里仍然是显示的{
   {msg}} --> <script> new Vue({  el: '#app', data: {  msg: 'Hello Vue.js' } }); </script> 

v-once

  • 只渲染一次,当数据改变时,插值的内容不会有响应式的改变
<!-- 即使data里面定义了msg 后期我们修改了 仍然显示的是第一次data里面存储的数据即 Hello Vue.js --> <span v-once>{
  { msg}}</span> <script> new Vue({  el: '#app', data: {  msg: 'Hello Vue.js' } }); </script> 

v-on

  • v-on是用来绑定事件的指令,如:v-on:click
  • 该指令还有一个语法糖,上述指令可以缩写为:@click
<body> <div id="app"> <div>{
  {num}}</div> <div> <button v-on:click="num++">点击1</button> <button @click="num++">点击2</button> <button @click='handle'>点击3</button> <button @click='handle()'>点击4</button> </div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> var vm = new Vue({  el: '#app', data: {  num: 0 }, methods: {  handle: function(){  this.num ++; } }, }) </script> </body> 

上面代码中四个按钮都可以实现对num加一 的操作,但是按钮3和4值得注意一下,按钮3在调用方法时没有加括号而按钮4加了括号,两种方式都是可以的。原因在于如果我们的方法不需要参数,在调用时就无须括号。

实际上,如果方法内只需要一个event事件对象参数,我们在调用时也无须写括号,因为vue会帮助我们自动传入event对象,前提是方法的声明处只有一个参数。如果方法需要多个参数而我们没有传入,则默认传入event作为第一个参数,其他的会是undefined。

事件修饰符

  • 在事件处理程序中调用event.preventDefault()或event.stopPropagation()是非常常见的需求。
  • Vue 不推荐我们操作DOM 为了解决这个问题,Vue.js 为v-on提供了事件修饰符
  • 修饰符是由点开头的指令后缀来表示的
<!-- 阻止单击事件继续传播 --> <a v-on:click.stop="doThis"></a> <!-- 提交事件不再重载页面 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 修饰符可以串联 即阻止冒泡也阻止默认事件 --> <a v-on:click.stop.prevent="doThat"></a> <!-- 只当在 event.target 是当前元素自身时触发处理函数 --> <!-- 即事件不是从内部元素触发的 --> <div v-on:click.self="doThat">...</div> 使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 v-on:click.prevent.self 会阻止所有的点击,而 v-on:click.self.prevent 只会阻止对元素自身的点击。

按键修饰符

  • 在做项目中有时会用到键盘事件,在监听键盘事件时,我们经常需要检查详细的按键。Vue 允许为v-on在监听键盘事件时添加按键修饰符
<!-- 只有在 `keyCode` 是 13 时调用 `vm.submit()` --> <input v-on:keyup.13="submit"> <!-- -当点击enter 时调用 `vm.submit()` --> <input v-on:keyup.enter="submit"> <!--当点击enter或者space时 时调用 `vm.alertMe()` --> <input type="text" v-on:keyup.enter.space="alertMe" > 常用的按键修饰符
.enter =>    enter键
.tab => tab键
.delete (捕获“删除”和“退格”按键) =>  删除键
.esc => 取消键
.space =>  空格键
.up =>  上
.down =>  下
.left =>  左
.right =>  右 <script> var vm = new Vue({  el:"#app", methods: {  submit:function(){ }, alertMe:function(){ }, } }) </script> 

自定义按键修饰符

  • 在Vue中可以通过config.keyCodes自定义按键修饰符别名
<div id="app"> 预先定义了keycode 116(即F5)的别名为f5,因此在文字输入框中按下F5,会触发prompt方法 <input type="text" v-on:keydown.f5="prompt()"> </div> <script> Vue.config.keyCodes.f5 = 116; let app = new Vue({  el: '#app', methods: {  prompt: function() {  alert('我是 F5!'); } } }); </script> 

v-bind

  • v-bind 指令被用来响应地更新 HTML 属性
  • v-bind:href 可以缩写为 :href;
<!-- 绑定一个属性 --> <img v-bind:src="imageSrc"> <!-- 缩写 --> <img :src="imageSrc"> 

绑定对象

  • 我们可以给v-bind:class 一个对象,以动态地切换class。
  • 注意:v-bind:class指令可以与普通的class特性共存
1、 v-bind 中支持绑定一个对象 
	如果绑定的是一个对象 则 键为 对应的类名  值 为对应data中的数据 <!-- HTML最终渲染为 <ul class="box textColor textSize"></ul> 注意: textColor,textSize 对应的渲染到页面上的CSS类名 isColor,isSize 对应vue data中的数据 如果为true 则对应的类名 渲染到页面上 当 isColor 和 isSize 变化时,class列表将相应的更新, 例如,将isSize改成false, class列表将变为 <ul class="box textColor"></ul> --> <ul class="box" v-bind:class="{textColor:isColor, textSize:isSize}"> <li>学习Vue</li> <li>学习Node</li> <li>学习React</li> </ul> <div v-bind:style="{ color:activeColor,fontSize:activeSize}">对象语法</div> <sript> var vm= new Vue({
    el:'.box',
    data:{
        isColor:true,
        isSize:true,
    	activeColor:"red",
        activeSize:"25px",
    }
}) </sript> <style> .box{  border:1px dashed #f0f; } .textColor{  color:#f00; background-color:#eef; } .textSize{  font-size:30px; font-weight:bold; } </style> 

绑定class

2、  v-bind 中支持绑定一个数组    数组中classA和 classB 对应为data中的数据

这里的classA  对用data 中的  classA
这里的classB  对用data 中的  classB <ul class="box" :class="[classA, classB]"> <li>学习Vue</li> <li>学习Node</li> <li>学习React</li> </ul> <script> var vm= new Vue({  el:'.box', data:{  classA:‘textColor‘, classB:‘textSize‘ } }) </script> <style> .box{  border:1px dashed #f0f; } .textColor{  color:#f00; background-color:#eef; } .textSize{  font-size:30px; font-weight:bold; } </style> 

绑定对象和数组的区别

  • 绑定对象的时候 对象的属性 即要渲染的类名 对象的属性值对应的是 data 中的数据
  • 绑定数组的时候数组里面存的是data 中的数据

绑定style

<div v-bind:style="styleObject">绑定样式对象</div>' <!-- CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来) --> <div v-bind:style="{  color: activeColor, fontSize: fontSize,background:'red' }">内联样式</div> <!--组语法可以将多个样式对象应用到同一个元素 --> <div v-bind:style="[styleObj1, styleObj2]"></div> <script> new Vue({  el: '#app', data: {  styleObject: {  color: 'green', fontSize: '30px', background:'red' }, activeColor: 'green', fontSize: "30px" }, styleObj1: {  color: 'red' }, styleObj2: {  fontSize: '30px' } </script> 

分支结构

v-if 使用场景

  • 多个元素 通过条件判断展示或者隐藏某个元素。或者多个元素
  • 进行两个视图之间的切换
<div id="app"> <!-- 判断是否加载,如果为真,就加载,否则不加载--> <span v-if="flag"> 如果flag为true则显示,false不显示! </span> </div> <script> var vm = new Vue({  el:"#app", data:{  flag:true } }) </script> ---------------------------------------------------------- <div v-if="type === 'A'"> A </div> <!-- v-else-if紧跟在v-if或v-else-if之后 表示v-if条件不成立时执行--> <div v-else-if="type === 'B'"> B </div> <div v-else-if="type === 'C'"> C </div> <!-- v-else紧跟在v-if或v-else-if之后--> <div v-else> Not A/B/C </div> <script> new Vue({  el: '#app', data: {  type: 'C' } }) </script> 

v-show 和 v-if的区别

  • v-show本质就是标签display设置为none,控制隐藏
    • v-show只编译一次,后面其实就是控制css,而v-if不停的销毁和创建,故v-show性能更好一点。
  • v-if是动态的向DOM树内添加或者删除DOM元素
    • v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件

循环结构

v-for

  • 用于循环的数组里面的值可以是对象,也可以是普通元素
<ul id="example-1"> <!-- 循环结构-遍历数组 item 是我们自己定义的一个名字 代表数组里面的每一项 items对应的是 data中的数组--> <li v-for="item in items"> {
  { item.message }} </li> </ul> <script> new Vue({  el: '#example-1', data: {  items: [ {  message: 'Foo' }, {  message: 'Bar' } ]} }) </script> 
  • 不推荐同时使用v-if和v-for
  • 当v-if与v-for一起使用时,v-for具有比v-if更高的优先级。
<!-- 循环结构-遍历对象 v 代表 对象的value k 代表对象的 键 i 代表索引 ---> <div v-if='v==13' v-for='(v,k,i) in obj'>{
  {v + '---' + k + '---' + i}}</div> <script> new Vue({  el: '#example-1', data: {  items: [ {  message: 'Foo' }, {  message: 'Bar' } ], obj: {  uname: 'zhangsan', age: 13, gender: 'female' } } }) </script> 

key 的作用

  • key来给每个节点做一个唯一标识
  • key的作用主要是为了高效的更新虚拟DOM
<ul> <li v-for="item in items" :key="item.id">...</li> </ul> 

购物车案例

需求说明:

  • 表格显示购物车的商品内容
  • 可以增加或者减少物品的数量,并且可以删除
  • 显示购物车商品的总价

实现图:

mark

代码:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> </head> <body> <div id="app" class="container"> <table class="table table-hover table-bordered"> <thead> <tr> <th scope="col">ID</th> <th scope="col">书籍名称</th> <th scope="col">出版日期</th> <th scope="col">价格</th> <th scope="col">购买数量</th> <th scope="col">操作</th> </tr> </thead> <tbody> <tr v-for="(book,index) in books"> <td>{
  {index+1}}</td> <td>{
  {book.name}}</td> <td>{
  {book.date}}</td> <td>{
  {book.price | showPrice}}</td> <td> <button class="btn btn-sm btn-secondary" @click="decrement(index)">-</button> {
  {book.count}} <button class="btn btn-sm btn-secondary" @click="increment(index)">+</button> </td> <td> <button class="btn btn-sm btn-danger" @click="removeItem(index)">删除</button> </td> </tr> </tbody> </table> <span>总价格:{
  {totalPrice | showPrice}}</span> </div> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> const app = new Vue({  el: "#app", data: {  books: [ {  name: '《算法导论》', date: '2016-9', price: 85, count: '1' }, {  name: '《UNIX编程艺术》', date: '2016-2', price: 99, count: '1' }, {  name: '《编程珠玑》', date: '2008-10', price: 108, count: '1' }, {  name: '《代码大全》', date: '2006-3', price: 79, count: '1' } ], }, filters: {  showPrice(value){  return '¥' + value.toFixed(2); } }, computed: {  totalPrice(){  let total = 0; for (let item of this.books){  total += item.price * item.count; } return total; } }, methods: {  increment(index){  this.books[index].count++; }, decrement(index){  if (this.books[index].count > 0){  this.books[index].count--; } }, removeItem(index){  this.books.splice(index,1); } } }); </script> </body> </html> 
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务