安装
npm install vue
概述
vue模板
new Vue({
data: {
a: 1
},
created: function () {
},
})
vue定义了许多系统自带的属性attribute,一般用$
开头来访问,有一些常用的attribute:
$root
访问组件的根元素,如果没有根元素就访问自己
$parent
访问父组件的实例
$ref
定义子组件的ID引用, $refs
引用所有的子组件ID
//通过 ref 这个 attribute 为子组件赋予一个 ID 引用
<base-input ref="usernameInput"></base-input>
//调用
this.$refs.usernameInput
vue生命周期
生命周期方法:
beforeCreate -> created -> beforeMount -> mounted -> beforeUpdated -> updated -> activated -> deactivated -> beforeDestory -> destoryed -> errorCaptured
vue基本语法
模板
- 双大括号可以插入文本{{}}
<span>Message: {{ msg }}</span>
//或者还可以解析一段原始的html文本
<span>Message: {{ rawHtml }}</span>
//如果要插入一段生效的html代码,可以用*v-html*
<span v-html="rawHtml"></span>
//也可以支持插入一段表达式
<span>{{ message.split('').reverse().join('') }}</span>
使用v-once指令,此处的值只会更新一次,不进行响应式更新
<span v-once>这个将不会改变: {{ msg }}</span>
- 属性Attribute插入值可以用v-bind指令
<button v-bind:disabled="isButtonDisabled">Button</button>
//支持表达式
<div v-bind:id="'list-' + id"></div>
- 基本的指令描述可以表现为v-加一个指令,冒号:后跟调用指令作用参数
v-DIRECTIVES:PARAM
半角句号.表示修饰符,用于指出一个指令应该以特殊方式绑定
<a v-on:click="doSomething">...</a>
//修饰符应用
<form v-on:submit.prevent="onSubmit">...</form>
使用方括号[]把参数括起来可以支持使用动态参数
<a v-on:[eventName]="doSomething"> ... </a>
v-bind可以简写用冒号:
v-on可以简写用@
- class动态绑定
对象绑定和数组绑定
//class绑定一个对象
data: {
isActive: true,
hasError: false
}
<div v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
data: {
classObject: {
active: true,
'text-danger': false
}
}
<div v-bind:class="classObject"></div>
//class 绑定一个数组
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
<div v-bind:class="[activeClass, errorClass]"></div>
//最终渲染的结果都为
<div class="active text-danger"></div>
style的绑定同理
计算属性
封装一段逻辑代码,可以直接做为属性值来使用。它与方法最大区别是计算属性是基于它们的响应式依赖进行缓存的,而方法每次使用都会做一次重新计算
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
条件渲染
- v-if v-else-if v-else
- v-show
列表渲染v-for
- 渲染数组
<ul id="example">
<li v-for="(item, index) in items" :key="item.id">
{{ index }} - {{ item.message }}
</li>
</ul>
- 渲染对象,遍历一个对象的属性
<div v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</div>
建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。
事件
v-on 指令监听 DOM 事件,并在触发时运行一些 JavaScript 代码
<div>
<!-- 事件传递一个处理方法名 -->
<button v-on:click="greet">Greet</button>
<!-- 或者也可以传递一个调用方法 -->
<button v-on:click="greet('hi')">Greet</button>
</div>
- 可以在内联语句调用方法中传递一个DOM事件,用$event
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
Submit
</button>
- 事件修饰符
.stop .prevent .capture .self .once .passive
<a v-on:click.stop="doThis"></a>
- 按键修饰符
<input v-on:keyup.enter="submit">
<input v-on:keyup.13="submit">
表单
修饰符
.lazy 在默认情况下,v-model
在每次 input
事件触发后将输入框的值与数据进行同步 。你可以添加 lazy
修饰符,从而转为在 change
事件之后进行同步
<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg">
.number 如果想自动将用户的输入值转为数值类型,可以给 v-model 添加 number 修饰符
<input v-model.number="age" type="number">
.trim 如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符
<input v-model.trim="msg">
组件
组件是可复用的 Vue 实例,且带有一个名字
基本组件示例
Vue.component('custom-input', {
props: ['value'],
template: `
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
使用组件
<custom-input v-model="searchText"></custom-input>
组件注册
-全局注册
Vue.component('MyComponentName', { /* ... */ })
-局部注册
import ComponentA from './ComponentA.vue'
export default {
components: {
ComponentA,
[componentbName]: componentB
},
// ...
}
Prop
Vue.component('blog-post', {
// 在 JavaScript 中是 camelCase 的
props: ['postTitle'],
template: '<h3>{{ postTitle }}</h3>'
})
<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>
prop类型限制:
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
prop验证的几种方式:
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
使用inheritAttrs: false
可以禁用根元素继承attribute
prop与其父控件之间是单向下行数据流向,父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
插槽Slot
预先设定一段待填充代码片段,待调用的时候能使用户自定义填充
<navigation-link url="/profile">
Your Profile
</navigation-link>
<navigation-link> 的模板中可能会写为:
<a v-bind:href="url" class="nav-link">
<slot></slot>
</a>
slot可以设定一个默认内容
<a v-bind:href="url" class="nav-link">
<slot>This is default value</slot>
</a>
如果有多个slot,需用name
区分不同的slot,slot默认name为default
下面是<base-layout> 组件
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
使用v-slot:name
调用组件
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。即子模板不能返回父模板的数据。
- slot访问父级模板数据的方式
1.以绑定数据model的方式在模板定义时把要访问的数据model添加到slot
<current-user>
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
2.使用v-slot:name="slotProp"
的方式在调用时传入数据
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
slot支持缩写语法,用
#
替换v-slot:
,即为#slotName
,如
<template #header>
<h1>Here might be a page title</h1>
</template>
混入Mixin
把一个功能混入到另一个组件中,有点类似于其它语言的扩展函数功能
var mixin = {
data: function () {
return {
message: 'hello',
foo: 'abc'
}
}
}
new Vue({
mixins: [mixin],
data: function () {
return {
message: 'goodbye',
bar: 'def'
}
},
created: function () {
console.log(this.$data)
// => { message: "goodbye", foo: "abc", bar: "def" }
}
})
1.数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。
2.混入对象的钩子将在组件自身钩子之前调用
过滤器
Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化。过滤器有两种方式:
1.双大括号插值
2.v-bind
表达式
过滤器第一个参数总是一个表达式的值,如下述的message
,后面跟过滤器,多个过滤器可以通过|
符号分隔开,有点像java中的管道,链式过滤。
<!-- 在双花括号中 -->
{{ message | capitalize }}
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>
过滤器的定义也有两种方式:
1.组件中定义本地过滤器
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
2.全局过滤器
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
其它
Keep-alive
缓存组件的状态,避免重复渲染
<!-- 失活的组件将会被缓存!-->
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
依赖注入
使用provide
选项允许我们指定可以提供给后代组件的数据方法,这种方式可以作为组件间交互方式的补充
provide: function () {
return {
getMap: this.getMap
}
}
后代通过inject
来接收想要添加到这个实例的属性:
inject: ['getMap']
事件侦听器
vue扩展了一些侦听器,可以接收$emit
发出的事件
$on(eventName, eventHandler)
侦听一个事件
$once(eventName, eventHandler)
一次性侦听一个事件
$off(eventName, eventHandler)
停止侦听一个事件