1.vue实例
1.每个 Vue 应用都是通过用 Vue 函数创建一个新的 Vue 实例开始的,所有的 Vue 组件都是 Vue 实例,并且接受相同的选项对象 (一些根实例特有的选项除外)。
var vm = new Vue({
data(){
return{
age:18
}
}
})
复制代码
2.只有当实例被创建时data中存在的属性才是响应式的,后添加的属性并不会响应式改变。
3.除了data属性,vue实例还暴露了一些实例属性和方法,都有前缀$以区分用户定义的属性。
vm.$data == data //true
vm.$el == document.getElementById('app')//true
vm.$watch('a',function(newValue, oldValue){
//这个回调将在 `vm.a` 改变后调用
})
}
复制代码
4.实例实名周期钩子
生命周期钩子的 this 上下文指向调用它的 Vue 实例,在生命周期函数中不要使用箭头函数,因为箭头函数没有this。
2.模板语法
1.插值
- 文本
<span>Message: {{ msg }}</span>
- HTML
<span v-html="rawHtml"></span></p>
- 特性
<div v-bind:id="dynamicId"></div>
- js表达式
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
复制代码
2.指令
- 条件渲染
<p v-if="seen">现在你看到我了</p>
- 参数
<a v-bind:href="url">...</a>
- 事件绑定
<a v-on:click="doSomething">...</a>
3.计算属性和侦听器
1.计算属性
主要用于处理复杂逻辑。
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
复制代码
-
当message改变时,所有依赖vm.reverseMessage的绑定都会进行更新。
-
计算属性computed和方法methods的区别:
-
计算属性只在相关依赖发生改变时才会重新进行求值,当依赖不发生改变时,访问计算属性中的方法均返回之前计算的缓存结果,而不是再次执行函数。
-
相比之下,methods在触发重新渲染时,总会再次执行其中的函数。
-
计算属性默认只有getter,不过在你需要时可以提供一个setter,现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstName 和 vm.lastName 也会相应地被更新。
computed: {
fullName: {
// getter
get: function () {
return this.firstName + ' ' + this.lastName
},
// setter
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
复制代码
2.侦听器watch
当数据变化时需要执行异步或开销较大的操作时,使用watch更有用。
var watchExampleVM = new Vue({
el: '#watch-example',
data: {
question: '',
answer: 'I cannot give you an answer until you ask a question!'
},
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
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
})
}
}
})
复制代码
在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
4.class与style绑定
1.class
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div
data: {
isActive: true,
hasError: false
}
复制代码
2.style
<div v-bind:style="styleObject"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
复制代码
5.条件渲染
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
复制代码
当两个模板使用了相同的元素时,vue会复用已有元素,如果想要独立渲染,需要添加唯一值key。 v-if与v-for一起使用时,v-for有更高的优先级。
6.列表渲染
1.遍历数组
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
复制代码
2.遍历对象
<ul id="v-for-object" class="demo">
<li v-for="(value ,name ,index) in object" :key = 'index'>
{{ index }} . {{ name }}: {{ value }}
</li>
</ul>
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
})
结果:
0. title: 'How to do lists in Vue',
1. author: 'Jane Doe',
2. publishedAt: '2016-04-10'
复制代码
不要使用对象或数组之类的非基本类型值作为 v-for 的 key。请用字符串或数值类型的值。
变异方法:可以触发视图更新的数组方法 push() pop() shift() unshift() splice() sort() reverse() 使用length改变数组内容不会响应式改变视图。
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的
可以使用Vue.set(vm.items, indexOfItem, newValue)
复制代码
对象: 对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性
添加多个属性可以用下列方法
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
复制代码
V-if与v-for一起使用时,尽可能将v-if置于外层元素或template上,这样可以跳过一些v-for循环。
<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>
复制代码
7.事件处理
1.
@click = 'dosomething(congig)'
methods:{
dosomething:function(config){
//事件逻辑
}
}
复制代码
2.事件修饰符
<!-- 阻止单击事件继续传播 -->
<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>
复制代码
3.按键修饰符
<input v-on:keyup.12 ='submit'>
为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
8.组件
1.组件中的data
组件中的data必须是一个函数,不然复用该组件的实例会相互影响。
2.父子组件传值
父向子组件传值要使用props
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
<blog-post title="My journey with Vue"></blog-post>
复制代码
子组件向父组件传值使用$emit
<button v-on:click="$emit('enlarge-text', 0.1)">
Enlarge text
</button>
<blog-post
...
v-on:enlarge-text="onEnlargeText"
></blog-post>
methods: {
onEnlargeText: function (enlargeAmount) {
this.postFontSize += enlargeAmount
}
}
复制代码
3.基础组件的自动化全局注册
如果你使用了 webpack (或在内部使用了 webpack 的 Vue CLI 3+),那么就可以使用 require.context 只全局注册这些非常通用的基础组件。
import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'
const requireComponent = require.context(
// 其组件目录的相对路径
'./components',
// 是否查询其子目录
false,
// 匹配基础组件文件名的正则表达式
/Base[A-Z]\w+\.(vue|js)$/
)
requireComponent.keys().forEach(fileName => {
// 获取组件配置
const componentConfig = requireComponent(fileName)
// 获取组件的 PascalCase 命名
const componentName = upperFirst(
camelCase(
// 获取和目录深度无关的文件名
fileName
.split('/')
.pop()
.replace(/\.\w+$/, '')
)
)
// 全局注册组件
Vue.component(
componentName,
// 如果这个组件选项是通过 `export default` 导出的,
// 那么就会优先使用 `.default`,
// 否则回退到使用模块的根。
componentConfig.default || componentConfig
)
})
复制代码