vue
2020-03-24 本文已影响0人
xyz098
https://cn.vuejs.org/v2/guide
核心:元素、属性、事件、组件
实例
Vue实例:数据属性,实例属性与方法(有前缀$)。看成一个类,实例化后有属性和方法。
Vue实例过程:数据监听、编译模板、将实例挂载到DOM并在数据变化时更新 DOM。
Vue生命周期钩子:允许用户在vue实例过程不同阶段添加代码的机会。
action (指令)
v-bind (属性绑定)
<!-- 动态传值 -->
<!-- 完整语法 href 与 url 绑定 -->
<a v-bind:href="url">...</a>
<!-- 缩写 -->
<a :href="url">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a :[key]="url"> ... </a>
v-on (事件绑定)
<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>
<!-- 缩写 -->
<a @click="doSomething">...</a>
<!-- 动态参数的缩写 (2.6.0+) -->
<a @[event]="doSomething"> ... </a>
<!-- 事件修饰符 -->
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
v-model (表单输入双向数据绑定)
实质: 绑定属性 & 执行事件
- text 和 textarea 元素使用 value 属性和 input 事件
- checkbox 和 radio 使用 checked 属性和 change 事件
- select 字段将 value 作为 prop 并将 change 作为事件
<input v-model="searchText">
<!-- 等价于 -->
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
<!-- 当选中时,`picked` 为字符串 "a" -->
<input type="radio" v-model="picked" value="a">
<!-- 修饰符 -->
<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg" >
<!-- 自动将用户的输入值转为数值类型 -->
<input v-model.number="age" type="number">
<!-- 自动过滤用户输入的首尾空白字符 -->
<input v-model.trim="msg">
v-if & v-show (元素绑定)
- v-if 惰性的。条件为假则什么也不做,条件为真才会渲染
- v-show 元素总是会被渲染,本质是基于切换CSS的
display
属性 (不支持template元素,也不支持 v-else) - 比较
-
v-if
切换开销高,而v-show
初始渲染开销高 - 频繁地切换用
v-show
;在运行时条件很少改变用v-if
-
<!-- v-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>
<!-- v-show -->
<h1 v-show="ok">Hello!</h1>
v-for (列表元素绑定)
- 就地更新策略: 当 Vue 正在更新使用 v-for 渲染的元素列表时, 如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。
<!-- 数组遍历 -->
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
<!-- object遍历 -->
<div v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</div>
<!-- key 属性 保证每个节点独立,不复用 -->
<div v-for="item in items" v-bind:key="item.id">
<!-- 内容 -->
</div>
<!-- 把模板重复对应次数 -->
<div>
<span v-for="n in 10">{{ n }} </span>
</div>
component (组件)
Vue组件都是vue实例,便于复用
注册
// 全局注册
Vue.component('component-a', { /* ... options ... */ })
// 局部注册
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
props (传参 父到子)
<!-- 父组件 -->
new Vue({
el: '#blog-post-demo',
data: {
posts: [
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
]
}
})
<!-- v-bind绑定动态title值 -->
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:title="post.title"
></blog-post>
<!-- 子组件 -->
<!-- props 获取父组件的值 -->
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
$emit (回传 子到父)
<!-- 父组件 -->
<!-- v-on绑定事件 enlarge-text -->
<blog-post
...
v-on:enlarge-text="postFontSize += 0.1"
></blog-post>
<!-- 子组件 -->
<!-- $emit 方法并传入事件名 -->
<button v-on:click="$emit('enlarge-text')">
Enlarge text
</button>
<!-- 组件间传递值 -->
<!-- 父组件-->
<!-- $event 访问到被抛出的这个值 -->
<blog-post
...
v-on:enlarge-text="postFontSize += $event"
></blog-post>
<!-- 子组件 -->
<button v-on:click="$emit('enlarge-text', 0.1)">
Enlarge text
</button>
slot (插槽 分发内容 父到子)
<!-- 父组件 -->
<!-- 渲染出: Error! Something bad happened. -->
<alert-box>
Something bad happened.
</alert-box>
<!-- 子组件 -->
<!-- <slot></slot> 代表分发的内容 -->
Vue.component('alert-box', {
template: `
<div class="demo-alert-box">
<strong>Error!</strong>
<slot></slot>
</div>
`
})
attribute (属性)
is (动态/异步组件、特殊元素)
<!-- 动态组件 -->
<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component v-bind:is="currentTabComponent"></component>
<!-- HTML特殊元素 -->
<!-- <li>、<tr> 和 <option>,只能出现在其它某些特定的元素内部 -->
<!-- is="todo-item" 属性 与 效果<todo-item>相同,不过为了DOM约束条件元素使用 is 属性 -->
<ul>
<!-- <todo-item> -->
<li
is="todo-item"
v-for="(todo, index) in todos"
v-bind:key="todo.id"
v-bind:title="todo.title"
v-on:remove="todos.splice(index, 1)"></li>
</ul>
key (元素不复用)
vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。
<!-- <label> 元素会被高效地复用 -->
<!-- <input> 元素完全独立,不被复用 -->
<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>
computed & watch & method
-
计算属性:(有缓存) 基于响应式依赖进行缓存,只在相关响应式依赖发生改变时才会重新求值。
-
方法: (无缓存)每当触发重新渲染时,调用方法将总会再次执行函数。
-
侦听器:当需要在数据变化时执行异步或开销较大的操作时。
<!-- computed -->
<!-- 反正字符串 -->
<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: {
reversedMessage: {
// getter
get: function () {
return this.message.split('').reverse().join('')
},
// setter
set: function (newValue) {
this.reversedMessage = newValue.split(' ')
}
}
}
})
<!-- 数组排序 -->
<li v-for="n in evenNumbers">{{ n }}</li>
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
}
<!-- method -->
<li v-for="n in even(numbers)">{{ n }}</li>
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
even: function (numbers) {
return numbers.filter(function (number) {
return number % 2 === 0
})
}
}
<!-- watch -->
<div id="demo">{{ fullName }}</div>
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
},
watch: {
firstName: function (val) {
this.fullName = val + ' ' + this.lastName
},
lastName: function (val) {
this.fullName = this.firstName + ' ' + val
}
}
})