阅读vue官方文档 知识点补充
- 关于data
- 只有当实例被创建时 data 中存在的属性才是响应式的。
- 使用 Object.freeze(),这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。
var obj = {
foo: 'bar'
}
Object.freeze(obj)
// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
el: '#app',
data: obj
})
<div id="app">
<p>{{ foo }}</p>
<!-- 这里的 `foo` 不会更新! -->
<button v-on:click="foo = 'baz'">Change it</button>
</div>
// 获得这个实例上的属性
// 返回源数据中对应的字段
vm.foo = obj.foo //=>true
- 关于箭头函数
不要在选项属性或回调上使用箭头函数,比如 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 之类的错误。
- Date.now() 不是响应式依赖:意味着下面的计算属性将不再更新
computed: {
now: function () {
return Date.now()
}
}
- 计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :
// ...
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]
}
}
}
// ...
-
watch侦听属性应用场景:当需要在数据变化时执行异步或开销较大的操作时
-
用 key 管理可复用的元素
//没有key值时,<input> 不会被替换掉——仅仅是替换了它的 placeholder。存在key时,输入框都将被重新渲染,<label> 元素仍然会被高效地复用,因为它们没有添加 key 属性。
<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-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
- 遍历
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
v-for="(value, name, index, item) in object"
How to do lists in Vue,title,0,item.title
- 数组更新检测
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
- 对象变更检测注意事项
- 向嵌套对象添加响应式属性
Vue.set(vm.userProfile, 'age', 27)
vm.$set(vm.userProfile, 'age', 27)
- 为已有对象赋值多个新属性
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
-
filter()、concat() 和 slice() 。它们不会改变原始数组,而总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组
-
v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。
//上面的代码将只渲染未完成的 todo。
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
-
在文本区域插值 (<textarea>{{text}}</textarea>) 并不会生效,应用 v-model 来代替。
-
v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:
-
text 和 textarea 元素使用 value 属性和 input 事件;
-
checkbox 和 radio 使用 checked 属性和 change 事件;
-
select 字段将 value 作为 prop 并将 change 作为事件。
-
复选框checkbox 多选select multiple ''
-
单选按钮radio 单选select []
- v-model修饰符
- .lazy 在“change”时而非“input”时更新
- .number HTML 输入元素的值由字符串变为number
- .trim 过滤空格
-
组件中的 data 必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝。
-
动态组件
is
<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component v-bind:is="currentTabComponent"></component>
在上述示例中,currentTabComponent 可以包括
- 已注册组件的名字
- 一个组件的选项对象
- 组件命名
- 定义时:PascalCase(MyComponentName) kebab-case(my-component-name) 都可以。
- 在 DOM (即非字符串的模板) 中使用时:只有 kebab-case 是有效的
- props 的大小写
- props命名:驼峰命名法(postTitle)
- 使用时:kebab-case(post-title)
- 静态props和动态props(通过 v-bind)
- 传入一个布尔值
<!-- 包含该 prop 没有值的情况在内,都意味着 `true`。-->
<blog-post is-published></blog-post>
<!-- 即便 `false` 是静态的,我们仍然需要 `v-bind` 来告诉 Vue -->
<!-- 这是一个 JavaScript 表达式而不是一个字符串。-->
<blog-post v-bind:is-published="false"></blog-post>
<!-- 用一个变量进行动态赋值。-->
<blog-post v-bind:is-published="post.isPublished"></blog-post>
- 传入一个对象的所有属性
post: {
id: 1,
title: 'My Journey with Vue'
}
<blog-post v-bind="post"></blog-post>
//等价于
<blog-post
v-bind:id="post.id"
v-bind:title="post.title"
></blog-post>
- 单向数据流(父向子传值)
- 改变prop传递过来的初始值:定义一个本地的 data 属性并将这个 prop 用作其初始值
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
- prop 以一种原始的值传入且需要进行转换:定义一个计算属性
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
- 替换/合并已有的特性
- 禁用特性继承
inheritAttrs: false
- .sync 修饰符:对一个 prop 进行“双向绑定”
//子组件
this.$emit('update:title', newTitle)
//父组件
<text-document
v-bind:title="doc.title"
v-on:update:title="doc.title = $event"
></text-document>
//等价于
<text-document v-bind:title.sync="doc.title"></text-document>
//当我们用一个对象同时设置多个 prop 的时候,也可以将这个 .sync 修饰符和 v-bind 配合使用:
<text-document v-bind.sync="doc"></text-document>
注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:title.sync=”doc.title + ‘!’” 是无效的)。取而代之的是,你只能提供你想要绑定的属性名,类似 v-model。
- 具名插槽的缩写
把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header
- keep-alive
<!-- 失活的组件将会被缓存!-->
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
- 异步组件
- 将异步组件和 webpack 的 code-splitting 功能一起配合使用
Vue.component('async-webpack-example', function (resolve) {
// 这个特殊的 `require` 语法将会告诉 webpack
// 自动将你的构建代码切割成多个包,这些包
// 会通过 Ajax 请求加载
require(['./my-async-component'], resolve)
})
- 在工厂函数中返回一个 Promise
Vue.component(
'async-webpack-example',
// 这个 `import` 函数会返回一个 `Promise` 对象。
() => import('./my-async-component')
)
- 处理加载状态
这里的异步组件工厂函数也可以返回一个如下格式的对象:
const AsyncComponent = () => ({
// 需要加载的组件 (应该是一个 `Promise` 对象)
component: import('./MyComponent.vue'),
// 异步组件加载时使用的组件
loading: LoadingComponent,
// 加载失败时使用的组件
error: ErrorComponent,
// 展示加载时组件的延时时间。默认值是 200 (毫秒)
delay: 200,
// 如果提供了超时时间且组件加载也超时了,
// 则使用加载失败时使用的组件。默认值是:`Infinity`
timeout: 3000
})
- 访问元素 & 组件
- 其根实例可以通过
$root
属性进行访问
// Vue 根实例
new Vue({
data: {
foo: 1
},
computed: {
bar: function () { /* ... */ }
},
methods: {
baz: function () { /* ... */ }
}
})
// 获取根组件的数据
this.$root.foo
// 写入根组件的数据
this.$root.foo = 2
// 访问根组件的计算属性
this.$root.bar
// 调用根组件的方法
this.$root.baz()
- 从一个子组件访问父组件的实例通过
$parent
- 访问子组件实例或子元素通过
ref
// 父组件里引用子组件 访问子组件实例 ref
<base-input ref="usernameInput"></base-input>
//使用
this.$refs.usernameInput
//该 <base-input> 组件也可以使用一个类似的 ref 提供对内部这个指定元素的访问
//子组件里
<input ref="input"/>
//父级组件定义方法
methods: {
// 用来从父级组件聚焦输入框
focus: function () {
this.$refs.input.focus()
}
}
//使用
this.$refs.usernameInput.focus()
refs。
- 依赖注入
provide
和inject
- provide 选项允许我们指定我们想要提供给后代组件的数据/方法。
provide: function () {
return {
getMap: this.getMap//<google-map> 内部的 getMap 方法
}
}
- 然后在任何后代组件里,我们都可以使用 inject 选项来接收指定的我们想要添加在这个实例上的属性
inject: ['getMap']
- 程序化的事件侦听器
$emit
的用法,它可以被v-on
侦听,但是 Vue 实同时在其事件接口中提供了其它的方法:
- 通过 $on(eventName, eventHandler) 侦听一个事件
- 通过 $once(eventName, eventHandler) 一次性侦听一个事件
- 通过 $off(eventName, eventHandler) 停止侦听一个事件
- 过渡 & 动画
网友评论