Vue入门笔记

模板语法

文本

双大括号的文本插值

<span>Message:{{msg}}</span>

v-once指令:一次性的指令,数据改变时,插值处的内容不会改变。

<span v-once>Message:{{msg}}</span>

v-html指令:双括号会将数据解释为文本,v-html输出真正的HTML。

<span v-html="rawHtml"></span></p>

注意

你的站点上动态渲染的任意 HTML 可能会非常危险,因为它很容易导致 XSS 攻击。

请只对可信内容使用 HTML 插值,绝不要对用户提供的内容使用插值。

属性

v-bind指令:代表属性,在布尔特性的情况下,它的存在即暗示为 true。

<div v-bind:id="dynamicId"></div>

使用JavaScript表达式

对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持。

{{number+1}}

{{ok? 'yes':'no'}}

{{ message.split('').reverse().join('')}}

<div v-bind:id="'list-' + id"></div>

注意

只能访问全局变量的一个白名单,如 Math 和 Date。

不该在模板表达式中试图访问用户定义的全局变量。

指令

带有 v- 前缀的特殊特性。指令特性的值预期是单个 JavaScript 表达式 (v-for 是例外情况)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。

<p v-if="seen">现在你看到我了</p>

v-if 指令将根据表达式 seen 的值的真假来插入/移除 <p> 元素。

v-modal指令,实现表单输入和应用状态之间的双向绑定

<input v-modal="message"/>

<script>

new Vue({

  el:#app,

  data:{

   message:'hello',

  }

})

</script>

参数

一些指令能够接受一些参数,在指令名称之后,用冒号表示。

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

<a v-on:click="dosomething"></a>

动态参数

用方括号括起来的 JavaScript 表达式作为一个指令的参数。

<a v-bind:[attributeName]="url"> ... </a>

这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data 属性 attributeName,其值为 "href",那么这个绑定将等价于 v-bind:href。

使用动态参数为一个动态的事件名绑定处理函数。

<a v-on:[eventName]="doSomething"> ... </a>

同样地,当 eventName 的值为 "focus" 时,v-on:[eventName] 将等价于 v-on:focus.

修饰符

修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault():

<form v-on:submit.prevent="onSubmit">...</form>

缩写

v-bind缩写

<a :href="url">...</a>

v-on缩写

<a @click="doSomething">...</a>

计算属性和侦听器

计算属性

对于任何复杂逻辑,你都应当使用计算属性。

<div id="example">

  <p>Original message: "{{ message }}"</p>

  <p>Computed reversed message: "{{ reversedMessage }}"</p>

</div>

var vm = new Vue({

  el: '#example',

  data: {

   message: 'Hello'

  },

  computed: {

   // 计算属性的 getter

   reversedMessage: function () {

     // `this` 指向 vm 实例

     return this.message.split('').reverse().join('')

   }

  }

})

侦听器

通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

<div id="watch-example">

<input v-modal="question"/>

{{answer}}

</div>

<script>

var watchExampleVM = new Vue({

  el:#id="watch-example",

  data:{

   question:'',

   answer:'I cannot give you an answer until you ask a question!',

  },


  watch:{

   question:function(newQuestion, oldQuestion){//当question发生改变,调用这个函数。

     this.answer = 'Waiting for you to stop typing...'

     this.debouncedGetAnswer()

   }

  },

  created:function(){

   this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)

  }

  methods: {

   getAnswer: function () {

     if (this.question.indexOf('?') === -1) {

       this.answer = 'Questions usually contain a question mark. ;-)'

       return

     }

     this.answer = 'Thinking...'

     var vm = this

     axios.get('https://yesno.wtf/api')

       .then(function (response) {

         vm.answer = _.capitalize(response.data.answer)

       })

       .catch(function (error) {

         vm.answer = 'Error! Could not reach the API. ' + error

       })

   }

  }

})

</script>

class与style绑定

对象语法

当isActive或者hasError变化时,class列表也会相应的进行更新。

<div

  class="static" v-bind:class="{active:isActive,'text-danger':hasError}"

></div>

data:{

  isActive:true,

  hasError:false,

}

绑定的对象不必内联定义在模板里。

<div class="classObject"></div>

data:{

  classObject:{

    active:true,

    'text-danger':false

  }

}

同样可以绑定对象的计算属性

<div class="classObject"></div>

data:{

  isActive:true,

  error:null

},

computed:{

  classObject:function(){

    return {

      active:this.isActive && !this.error,

      'text-danger':this.error && this.error.type === 'fatal'

    }

  }

}

数组语法

<div v-bind:class="[activeClass, errorClass]"></div>

data:{

  activeClass: 'active',

  errorClass: 'text-danger'

}

根据条件切换列表中的class,可以用三元表达式。

<div v-bind:class="[isActive? activeClass:'',errorClass]"></div>

在数组语法中,使用对象语法

<div v-bind:class="[{active:isActive},errorClass]"></div>

绑定内联样式

对象语法

v-bind:style,CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用单引号括起来) 来命名:

<div v-bind:style="{color:activeColor,fontSize:fontSize +'px'}"></div>

data:{

  activeColor:'red',

  fontSize:30

}

直接绑定到样式对象

<div v-bind:style="styleObject"></div>

data: {

  styleObject: {

    color: 'red',

    fontSize: '13px'

  }

}

数组语法

v-bind:style 的数组语法可以将多个样式对象应用到同一个元素上

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

多重值

为 style 绑定中的属性提供一个包含多个值的数组,常用于提供多个带前缀的值,例如:

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

这样写只会渲染数组中最后一个被浏览器支持的值。

在本例中,如果浏览器支持不带浏览器前缀的 flexbox,那么就只会渲染 display: flex。

条件渲染

v-if,v-else

v-if用于条件性的渲染一块内容。这块内容,只有在指令的表达式返回truthy值的时候被渲染,也可以用v-else添加一个else块。

<h1 v-if="awesome">good</h1>

<h1 v-else>bad</h1>

在 <template> 元素上使用 v-if 条件渲染分组

因为 v-if 是一个指令,所以必须将它添加到一个元素上。但是如果想切换多个元素呢?此时可以把一个 template 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 template 元素。

<template v-if="ok">

  <h1>Title</h1>

  <p>Paragraph 1</p>

  <p>Paragraph 2</p>

</template>

v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。

v-else-if

充当 v-if 的“else-if 块”,可以连续使用,v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后.

<div v-if="type === 'A'">

  A

</div>

<div v-else-if="type === 'B'">

  B

</div>

<div v-else-if="type === 'C'">

  C

</div>

<div v-else>

  Not A/B/C

</div>

用 key 管理可复用的元素

input 是两个独立的元素,不复用,label会被复用。

<template v-if="loginType === 'username'">

  <label>Username</label>

  <input placeholder="Enter your username" key="username-input">

</template>

<template v-else>

  <label>Email</label>

  <input placeholder="Enter your email address" key="email-input">

</template>

v-show

另一个用于根据条件展示元素的选项,不同的是带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。

<h1 v-show="ok">ok</h1>

注意,v-show 不支持 template 元素,也不支持 v-else。

列表渲染

v-for把一个数组对应为一组元素,也可以用 of 替代 in 作为分隔符

<ul id="example-2">

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

    {{ parentMessage }} - {{ index }} - {{ item.message }}

  </li>

</ul>

var example2 = new Vue({

  el: '#example-2',

  data: {

    parentMessage: 'Parent',

    items: [

      { message: 'Foo' },

      { message: 'Bar' }

    ]

  }

})

一个对象的 v-for

<ul id="v-for-object" class="demo">

  <li v-for="value in object">

    {{ index }}. {{ key }}: {{ value }}

  </li>

</ul>

new Vue({

  el: '#v-for-object',

  data: {

    object: {

      firstName: 'John',

      lastName: 'Doe',

      age: 30

    }

  }

})

key

为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的唯一 id。

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

  <!-- 内容 -->

</div>

变异方法

push() 向数组的末尾添加一个或多个元素,并返回新的长度

pop() 删除并返回数组的最后一个元素

shift() 把数组的第一个元素从其中删除,并返回第一个元素的值

unshift() 向数组的开头添加一个或更多元素,并返回新的长度

splice() 从数组中添加/删除项目,然后返回被删除的项目

sort() 对数组的元素进行排序

reserve() 颠倒数组中元素的顺序

会改变被这些方法调用的原始数组。相比之下,也有非变异 (non-mutating method) 方法,例如:filter(), concat() 和 slice() 。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组:

example1.items = example1.items.filter(function (item) {

  return item.message.match(/Foo/)

})

替换数组

filter() 创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素

concat() 连接两个或多个数组

slice() 从已有的数组中返回选定的元素

split() 方法用于把一个字符串分割成字符串数组

注意事项

由于 JavaScript 的限制,Vue 不能检测以下变动的数组

当你利用索引直接设置一个项时

当你修改数组的长度时

var vm = new Vue({

  data: {

    items: ['a', 'b', 'c']

  }

})

解决办法

Vue.set(vm.items, indexOfItem, newValue)||vm.$set()

vm.items.splice(newLength)

对象更改检测注意事项

Vue 不能检测对象属性的添加或删除,对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, key, value) 方法向嵌套对象添加响应式属性。例如:

var vm = new Vue({

  data: {

    userProfile: {

      name: 'Anika'

    }

  }

})

Vue.set(vm.UserProfile,'age',27)||vm.$set()

有时你可能需要为已有对象赋予多个新属性,比如使用 Object.assign() 或 _.extend()

vm.userProfile=Object.assign({},vm.userProfile,{

  age:27,

  favouriteColor:'pink'

})

显示过滤/排序结果

创建返回过滤或排序数组的计算属性

<li v-for="n in evenNumbers">{{n}}</li>

data:{

  numbers:[1,2,3,4,5]

},

computed:{

  evenNumbers:function(){

    return this.numbers.filter(function(number){

      return number%2===0;

    })

  }

}

在计算属性不适用的情况下 (例如,在嵌套 v-for 循环中) 你可以使用一个 method 方法:

<li v-for:"n in even(numbers)">{{n}}</li>

data:{

  numbers:[1,2,3,4,5]

},

methods:{

  even:function(numbers){

    return this.numbers.filter(function(number){

      return number%2===0;

    })

  }

}

一段取值范围的v-for

v-for 也可以取整数。在这种情况下,它将重复多次模板

<div v-for="n in 10">{{n}}</div> 1,2,3,4,5,6,7,8,9,10

v-for on a template

<ul>

  <template v-for="item in items">

    <li>{{ item.msg }}</li>

    <li class="divider" role="presentation"></li>

  </template>

</ul>

v-for with v-if 注意

不推荐同时使用 v-if 和 v-for

当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你想为仅有的一些项渲染节点时,这种优先级的机制会十分有用,如下:

<li v-for="todo in todos" v-if="!todo.isComplete">{{todo}}</li>

//只传递未完成的todo

而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 template)上。如:

<ul v-if="todos.length">

  <li v-for="todo in todos">{{todo}}</li>

</ul>

<p v-else>No todos left!</p>

一个组件的v-for

2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的

<my-component

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

  v-bind:index="index"

  v-bind:item="item"

  v-bind:key="item.id"

>

</my-component>

事件处理

监听事件

可以用 v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码。

<div id="example1">

  <button v-on:click="counter+=1">Add 1</button>

  <p>{{counter}}</p>

</div>

事件处理方法

v-on 还可以接收一个需要调用的方法名称

<button v-on:click="greet">Greet</button>

data: {

    name: 'Vue.js'

  },

methods: {

    greet: function (event) {

      alert('Hello ' + this.name + '!')

      if (event) {

        alert(event.target.tagName)

      }

    }

}

内联处理器中的方法

除了直接绑定到一个方法,也可以在内联 JavaScript 语句中调用方法:

<button v-on:click="say('hi')">Say hi</button>

methods: {

    say: function (message) {

      alert(message)

    }

  }

有时也需要在内联语句处理器中访问原始的 DOM 事件。可以用特殊变量 $event 把它传入方法:

<button v-on:click="warn('Form cannot be submitted yet.', $event)">

  Submit

</button>

methods: {

  warn: function (message, event) {

    if (event) event.preventDefault()

    alert(message)

  }

}

事件修饰符(待补充)

.stop

.prevent

.capture

.self

.once

.passive

<!-- 阻止单击事件继续传播 -->

<a v-on:click.stop="doThis"></a>

<!-- 提交事件不再重载页面 -->

<form v-on:submit.prevent="onSubmit"></form>

<!-- 修饰符可以串联 -->

<a v-on:click.stop.prevent="doThat"></a>

<!-- 只有修饰符 -->

<form v-on:submit.prevent></form>

<!-- 添加事件监听器时使用事件捕获模式 -->

<!-- 即元素自身触发的事件先在此处理,然后才交由内部元素进行处理 -->

<div v-on:click.capture="doThis">...</div>

<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->

<!-- 即事件不是从内部元素触发的 -->

<div v-on:click.self="doThat">...</div>

注意

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。v-on:click.prevent.self 会阻止所有的点击。v-on:click.self.prevent 只会阻止对元素自身的点击。

按键修饰符

Vue 允许为 v-on 在监听键盘事件时添加按键修饰符:

<!-- 只有在 `key` 是 `Enter` 时调用 `vm.submit()` -->

<input v-on:keyup.enter="submit">

按键码

.enter

.tab

.delete (捕获“删除”和“退格”键)

.esc

.space

.up

.down

.left

.right

你还可以通过全局 config.keyCodes 对象自定义按键修饰符别名:

// 可以使用 `v-on:keyup.f1`

Vue.config.keyCodes.f1 = 112

表单输入绑定

基础用法

用 v-model 指令在表单 input、textarea 及 select 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。

v-model 在内部使用不同的属性为不同的输入元素并抛出不同的事件:

text 和 textarea 元素使用 value 属性和 input 事件;

checkbox 和 radio 使用 checked 属性和 change 事件;

select 字段将 value 作为 prop 并将 change 作为事件。

文本、多行文本

<input v-model="message" placeholder="edit me">

<p>Message is: {{ message }}</p>

<textarea v-model="message" placeholder="add multiple lines"></textarea>

在文本区域插值 (<textarea>{{text}}</textarea>) 并不会生效,应用 v-model 来代替。

复选框

当个复选框,绑定到布尔值

<input type="checkbox" id="checkbox" v-model="checked">

<label for="checkbox">{{ checked }}</label>

多个复选框,绑定到同一数组

<div id='example-3'>

  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">

  <label for="jack">Jack</label>

  <input type="checkbox" id="john" value="John" v-model="checkedNames">

  <label for="john">John</label>

  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">

  <label for="mike">Mike</label>

  <br>

  <span>Checked names: {{ checkedNames }}</span>

</div>

new Vue({

  el: '#example-3',

  data: {

    checkedNames: []

  }

})

单选按钮

<div id="example-4">

  <input type="radio" id="one" value="One" v-model="picked">

  <label for="one">One</label>

  <br>

  <input type="radio" id="two" value="Two" v-model="picked">

  <label for="two">Two</label>

  <br>

  <span>Picked: {{ picked }}</span>

</div>

new Vue({

  el: '#example-4',

  data: {

    picked: ''

  }

})

下拉框

单选时

<div id="example-5">

  <select v-model="selected">

    <option disabled value="">请选择</option>

    <option>A</option>

    <option>B</option>

    <option>C</option>

  </select>

  <span>Selected: {{ selected }}</span>

</div>

new Vue({

  el: '...',

  data: {

    selected: ''

  }

})

多选时绑定到一个数组

用 v-for 渲染的动态选项:

<select v-model="selected">

  <option v-for="option in options" v-bind:value="option.value">

    {{ option.text }}

  </option>

</select>

<span>Selected: {{ selected }}</span>

new Vue({

  el: '...',

  data: {

    selected: 'A',

    options: [

      { text: 'One', value: 'A' },

      { text: 'Two', value: 'B' },

      { text: 'Three', value: 'C' }

    ]

  }

})

值绑定

对于单选按钮,复选框及选择框的选项,v-model 绑定的值通常是静态字符串 (对于复选框也可以是布尔值):

<!-- 当选中时,`picked` 为字符串 "a" -->

<input type="radio" v-model="picked" value="a">

<!-- `toggle` 为 true 或 false -->

<input type="checkbox" v-model="toggle">

<!-- 当选中第一个选项时,`selected` 为字符串 "abc" -->

<select v-model="selected">

  <option value="abc">ABC</option>

</select>

复选框

<input

  type="checkbox"

  v-model="toggle"

  true-value="yes"

  false-value="no"

>

// 当选中时

vm.toggle === 'yes'

// 当没有选中时

vm.toggle === 'no'

单选按钮

<input type="radio" v-model="pick" v-bind:value="a">

// 当选中时

vm.pick === vm.a

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容