{ {}}
v-if / v-for
v-on
简单介绍了一个vue实例有哪些元素组成
API文档
- data对象中的所有的 property 被加入到 Vue 的响应式系统中。
- 只有当实例被创建时就已经存在于 data 中的 property 才是响应式的。
- Object.freeze()加入其中,响应系统无法再追踪变化(不再响应式)
- 实例属性与方法参考API文档
- 定义:每个 Vue 实例在被创建时都要经过一系列的初始化过程运行的一些函数。
用户可以在不同阶段添加自己的代码。- 生命周期钩子的 this 上下文指向调用它的 Vue 实例。
- 不要在选项 property 或回调上使用箭头函数,比如 created: () => console.log(this.a) 或 vm.$watch(‘a’, newValue => this.myMethod())。
因为箭头函数并没有 this,this 会作为变量一直向上级词法作用域查找,直至找到为止
经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。- 生命周期钩子函数
beforeCreated
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed
文本
- “Mustache”语法 (双大括号) 的文本插值:{ {}}
- 一次性地插值,当数据改变时,插值处的内容不会更新:v-once
原始HTML
- v-html
Attribute
- 属性变量:v-bind
使用JavaScript表达式
- 双大括号,v-bind内可以写单个表达式
参数
- v-bind 响应式更新 HTML attribute
- v-on 监听dom事件
动态参数
- 2.6.0新增 代码如下
修饰符
- .prevent
- v-bind: -> :
- v-on: -> @
// 动态参数
// 如果attributeName为herf 相当于:href="url"
<a v-bind:[attributeName]="url">a>
// eventName可以为click,focus等 相当于@click="doSomething"
<a v-on:[eventName]="doSomething">a>
// 1. 动态参数为null时,可以被显性地用于移除绑定。
// 2. **非字符串类型** 某些字符,如**空格和引号** 无效并触发警告
// 3. 可以使用计算属性代替复杂的表达式
// 4. 避免使用大些字符
- 基础例子
<p>{
{reversedMessage}}}p>
computed: {
reversedMessage: function() {
return this.xxx.join('')
}
}
- 计算属性缓存vs方法
计算属性是基于它们的响应式依赖进行缓存的有缓存,减小开销- 计算属性vs侦听属性
computed: {
fullName: {
get: function () {
return this.firstName + ' ' + this.lastName
},
set: fucntion (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
- 当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
<div id="watch-example">
<p>
Ask a yes/no question:
<input v-model="question">
p>
<p>{
{ answer }}p>
div>
// 执行异步操作(访问API)设置中间状态
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
var watchExampleVM = new Vue({
el: '$watch-example',
data: {
question: '',
answer: 'I cannot give you an answer until you ask a question!'
},
watch: {
question: function (newQ, oldQ) {
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 (res) {
vm.answer = _.capitalize(res.data.answer)
}).catch(function (err) {
vm.answer = 'Error! Could not reach the API.' + err
})
}
}
})
// 一、绑定HTML Class
// 1.对象语法
<div
v-bind:class="{ active: isActive }"
>div>
<div
v-bind:class="{ active: isActive, 'text-danger': hasError }"
>div>
<div
v-bind:class="classObject"
>div>
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
// 2.数组语法
<div v-bind:class="[activeClass, errorClass]">div>
<div v-bind:class="[isActive ? activeClass : '', errorClass]">div>
// 3.数组内有对象
<div v-bind:class="[{ active: isActive }, errorClass]">div>
// 4.组件内class
<my-component class="baz boo">my-component>
<my-component v-bind:class="{ active: isActive }">my-component>
// 二、绑定内联样式
// 1.对象
<div v-bind:style="{
color: activeColor, fontSize: fontSize + 'px' }">div>
// 2.抽成对象
<div v-bind:style="styleObject">div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
// 3.数组(多个样式对象)
<div v-bind:style="[baseStyles, overridingStyles]">div>
// 4.自动添加针对不同浏览器的前缀
// 5.多重值(往后备用样式)
<div :style="{
display: ['-webkit-box', '-ms-flexbox', 'flex'] }">div>
1.v-if v-else-if v-else 条件性的渲染
在 元素上使用 v-if 条件渲染分组
用 key 管理可复用的元素
// 加了key就会被重新渲染而不复用该标签
<template v-if="loginType === 'username'">
<label>Usernamelabel>
<input placeholder="Enter your username" key="username-input">
template>
<template v-else>
<label>Emaillabel>
<input placeholder="Enter your email address" key="email-input">
template>
1.(不支持template元素) 始终被渲染并保留在DOM中 相当于display切换
1.v-if 切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
2.v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。
3.频繁地切换用 v-show 否则 v-if
1.不推荐同时(同一个标签内)使用 v-if 和 v-for
2.当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级
遍历数组:
v-for="item in items / (item, index) in items / item of items"
(序号 index)
遍历对象:
v-for="(value, name) in object / value in object / v-for="(value, name, index) in object""
(键名 name 索引 index)
用字符串或数值类型的值作为 v-for 的 key。
数组更新检测
1.变更方法(变更原数组):push() pop() shift() unshift() splice() sort() reverse()
2.非变更方法(返回新数组):filter() concat() slice()
3.由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。深入响应式原理
显示过滤/排序后的结果
计算属性
双层循环不能计算属性时可以直接用方法
<ul v-for="set in sets">
<li v-for="n in even(set)">{
{ n }}li>
ul>
data: {
sets: [[ 1, 2, 3, 4, 5 ], [6, 7, 8, 9, 10]]
},
methods: {
even: function (numbers) {
return numbers.filter(function (number) {
return number % 2 === 0
})
}
}
v-for循环整数: v-for=“n in 10”
上可使用 v-for 渲染分组
v-on
v-on:click=“greet”
1.v-on:click=“say(‘hi’)”
2.在内联语句处理器中访问原始的 DOM 事件:
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
button>
methods: {
warn: function (message, event) {
if (event) {
event.preventDefault()
}
alert(message)
}
}
1.为了方法只有纯粹的数据逻辑,而不是去处理 DOM 事件细节
2. .stop (click: 阻止事件继续传播)
3. .prevent (submit: 不再重载页面)
4. .capture (click: 使用事件捕获模式)
5. .self (click: 是当前元素自身时触发)
6. .once (click: 2.1.4新增–只会触发一次)
7. .passive (scroll: 2.3.0 新增–立即触发)
8. 串联调用时顺序很重要,不同顺序会产生不同结果
<input v-on:keyup.enter="submit">
<input v-on:keyup.page-down="onPageDown">
别名:
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
.ctrl
.alt
.shift
.meta
<input v-on:keyup.alt.67="clear">
<div v-on:click.ctrl="doSomething">Do somethingdiv>
.exact (2.5.0新增–修饰符允许你控制由精确的系统修饰符组合触发的事件。)
<button v-on:click.ctrl="onClick">Abutton>
<button v-on:click.ctrl.exact="onCtrlClick">Abutton>
<button v-on:click.exact="onClick">Abutton>
鼠标按钮修饰符 (2.2.0新增)
.left
.right
.middle
文本
多行文本
复选框
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jacklabel>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">Johnlabel>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mikelabel>
单选按钮
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">Onelabel>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Twolabel>
选择框
<select v-model="selected">
<option disabled value="">请选择option>
<option>Aoption>
<option>Boption>
<option>Coption>
select>
<select v-model="selected" multiple style="width: 50px;">
<option>Aoption>
<option>Boption>
<option>Coption>
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
选择框的选项
// 不知道这个会在哪种场景下使用???
<select v-model="selected">
<option v-bind:value="{ number: 123 }">123option>
select>
// 选中时
// typeof vm.selected // => 'object'
// vm.selected.number // => 123
.lazy
在“change”时而非“input”时更新
.number
自动将用户的输入值转为数值类型
.trim
自动过滤用户输入的首尾空白字符
1.每用一次组件,就会有一个它的新实例被创建
2.一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝
嵌套的组件树
两种组件的注册类型:全局注册和局部注册
父传子
每个组件必须只有一个根元素
1.子组件向父组件派发事件并监听
2.使用事件抛出一个值
// 子组件
<button v-on:click="$emit('enlarge-text', 0.1)">
Enlarge text
button>
// 父组件
<blog-post
...
v-on:enlarge-text="postFontSize += $event"
>blog-post>
// 或父组件
<blog-post
...
v-on:enlarge-text="onEnlargeText"
>blog-post>
// 作为第一个参数传入
methods: {
onEnlargeText: function (enlargeAmount) {
this.postFontSize += enlargeAmount
}
}
3.在组件上使用 v-model
// 子组件
Vue.component('custom-input', {
props: ['value'],
template: `
`
})
// 父组件
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
>custom-input>
// 或
<custom-input v-model="searchText">custom-input>