基础
创建实例
创建 Vue 实例并挂载到指定的 DOM 节点上:
<div id="app" />
<script>
// 定义配置
const options = {
el: '#app',
data() {
return {};
},
};
// 创建Vue实例
const vm = new Vue(options);
// 获取实例属性和调用实例方法
vm.$propertyName;
vm.$methodName();
</script>
模板语法
<div>文本插值 {{text}}</div>
<div v-text="text"></div>
<div v-html="html"></div>
<div v-once>内容不会改变 {{msg}}</div>
<input v-modle="value" />
<div :attribute="varOrExp"></div>
<div @event="varOrExp"></div>
<div :[attribute]="varOrExp"></div>
<div @:[event]="varOrExp"></div>
样式语法
元素的class
和style
属性通常为复杂的字符串。所幸 Vue 支持:class
和:style
的对象形式和数组形式:
const options = {
data() {
return {
obj: {
a: true,
b: false,
},
arr: ['a', 'b'],
};
},
};
<div class="default" :class="obj"></div>
<div class="default" :class="arr"></div>
<!--会被渲染成-->
<div class="default a"></div>
<div class="default a b"></div>
元素的style
属性同理,且 Vue 会智能地为其添加浏览器引擎前缀。
条件渲染
v-if
是真正意义上的条件渲染,v-show
则是惰性渲染(先渲染,通过切换display
属性来切换元素的显示与否),当需要频繁切换显示状态时,应使用后者:
<div v-if="varOrExp1"></div>
<div v-else-if="varOrExp2"></div>
<div v-else></div>
<div v-show="varOrExp3"></div>
条件渲染在切换时,默认复用元素,可以添加key
属性来防止复用:
<!--<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>
循环渲染
使用v-for
指令进行循环渲染。其中的key
属性是为了标识 vdom,使得在 vdom diff 时,能通过尽可能地移动已有元素来降低 DOM 操作成本;当未设key
属性时,则采取就地更新的原则:
<div v-for="(val,idx) of [1,2,3]" :key="val.id"></div>
<div v-for="(val,key,idx) of {a:1,b:2,c:3}" :key="val.id"></div>
<div v-for="val in 10" :key="val" />
组件
注册组件
组件实际上是带预定配置、可复用的 Vue 实例:
// 局部组件ComponentLocal,
// 只能在全局组件ComponentGlobal内部使用
Vue.component('ComponentGlobal', {
components: { ComponentLocal },
template: '<div><component-local /><span>hello!</span></div>',
});
自动化注册请见此文。
生命周期钩子
const options = {
// 在实例创建后=
beforeCreate() {},
// 在options初始化后
created() {},
// 在模板编译为vdom后
beforeMount() {},
// 在vdom挂载到dom后
mounted() {},
// 在数据更新后
beforeUpdate() {},
// 在虚拟dom和dom更新后
updated() {},
// 在实例销毁前
beforeDestroy() {},
// 在实例销毁后
destroyed() {},
};
props
HTML 中的 attribute 名称大小写不敏感,如title
等同于Title
;所以在 Vue 中的 proppostTitle
在 HTML 中应写成post-title
:
const options = {
name: 'blog-post',
props: {
postTitle: {
type: String,
default: 'DEFAULT POST TITLE',
},
},
};
<blog-post post- />
可以一次性传入所有的props
:
const options = {
name: 'blog-post',
data() {
return {
post: {
id: 1,
title: 'My Journey with Vue',
},
};
},
};
<blog-post v-bind="post"></blog-post>
<!--等价于-->
<blog-post :id="post.id" :></blog-post>
props
由父组件单向传播给子组件。$attrs
为父组件传给子组件、但未注册为props
的属性,该属性会作为 HTML attribute,被添加到子组件根标签中;若将子组件的inheritAttrs
设为false
,则该属性不会被添加到子组件根标签中,但$attrs
的值不受影响。
methods
<div @click="method1"></div>
<div @click="method2('param')"></div>
<div @click="method3('param',$event)"></div>
const options = {
methods: {
method1(event) {},
method2(param) {},
method3(param, event) {},
},
};
事件具有修饰符,如不带修饰符默认在冒泡阶段监听事件,带修饰符.capture
在捕获阶段监听事件,以及其他的修饰符.prevent
、.stop
、.self
和.once
。除此以外,还有按键修饰符@keyup.page-down
,鼠标修饰符@click.left
,系统修饰符@click.ctrl
和@keyup.alt
,精确修饰符.exact
。
watch 和 computed
const options = {
// 侦听器
watch: {
a: {
deep: true,
immediate: true,
handler(newVal, oldVal) {},
},
},
// 计算属性:基于侦听器
computed: {
// 侦听firstName和lastName,会将结果缓存
fullName: {
get() {
return this.firstName + this.lastName;
},
set(val) {
// ...
},
},
},
};
filters
<div>{msg | transform('param')}</div>
// 全局
Vue.filter('upper', function (value, param) {
return '...';
});
// 局部
const options = {
filters: {
upper(value, param) {
return '';
},
},
};
directives
<div v-focus></div>
// 全局
Vue.directive('focus', {
// 参数有el、binding、vnode、oldVnode
bind() {},
inserted() {},
update() {},
componentUpdated() {},
unbind() {},
});
// 局部
const options = {
directives: {
focus: {
// ...
},
},
};
mixins
混入规则为,同名钩子函数合并为数组,依次调用,其余属性直接被替代:
const mixinOptions = {
// ...
};
// 全局混入
Vue.mixin(mixinOptions);
// 局部混入
Vue.component('component-be-mixin', {
minxins: [mixinOptions],
// ...
});
双向绑定
<input v-model="varOrExp" />
<!--等价于-->
<input :value="varOrExp" @input="varOrExp = $event.target.value" />
v-model
指令对于不同的元素,有着不同的绑定属性和事件:
- 对于
<text>
元素和<textarea>
元素,对应value
属性和input
事件。 - 对于
<checkbox>
元素和<radio>
元素,对应checked
属性和change
事件。 - 对于
<select,对应>
元素,对应value
属性和change
事件。
亦可自定义对应的属性和事件:
const options = {
model: {
prop: 'checked',
event: 'change',
},
};
v-model
有修饰符,如.lazy
、.number
和.trim
。
同步 props
.sync
修饰符,用于在子组件中便捷地修改prop
的值:
<!--template-parent-->
<child :inner- @update:inner-></child>
// component-child
this.$emit('update:inner-title', newTitle);
父组件模板可简写为:
<child :inner-title.sync="title"></child>
访问子组件
<component-name ref="a" />
const childComponent = this.$refs['a'];
插槽
默认插槽:
<!--template-->
<div>
<strong>Error!</strong>
<slot></slot>
</div>
<!--use-->
<alert-box> Something bad happened. </alert-box>
具名插槽:
<!--template-->
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<!--name="default"-->
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
<!--use-->
<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>
作用域插槽(让父组件访问到子组件插槽内部的数据):
<!--template-->
<span>
<slot :user="user"> {{ user.lastName }} </slot>
</span>
<!--use,slotProps是default插槽作用域-->
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
动态组件和异步组件
动态组件:
<!--默认不缓存状态-->
<component-name :is="currentComponent" />
<!--使用keep-alive组件缓存状态-->
<keep-alive>
<component-name :is="currentComponent" />
</keep-alive>
异步组件:
// 第2个参数返回的类型为Promise
Vue.component('async-component', function (resolve, reject) {
setTimeout(function () {
const options = {
template: '<div>I am async!</div>',
};
resolve(options);
}, 1000);
});
处理异步组件的加载状态:
Vue.component('async-component', () => ({
// 需要加载的组件 (类型应该为Promise)
component: import('./MyComponent.vue'),
// 正在加载时使用的组件
loading: LoadingComponent,
// 加载失败时使用的组件
error: ErrorComponent,
// 展示LoadingComponent的延时时间
delay: 200,
// 加载的限定时间
timeout: 3000,
}));
过渡和动画
进入/离开过渡
单元素/组件过渡(对v-show
、v-if
和:is
起作用):
【1】CSS 过渡:
<transition name="slide-fade" mode="in-out" :duration="1000">
<component-name v-if="varOrExp" />
</transition>
.slide-fade-enter-active {
transition: all 0.3s ease;
}
.slide-fade-leave-active {
transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-enter,
.slide-fade-leave-to {
transform: translateX(10px);
opacity: 0;
}
【2】动画过渡:
HTML 模板同上。
.slide-fade-enter-active {
animation: /*...*/ ;
}
.slide-fade-leave-active {
animation: /*...*/ ;
}
【3】钩子过渡:
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@enter-cancelled="enterCancelled"
@before-leave="beforeLeave"
@leave="leave"
@after-leave="afterLeave"
@leave-cancelled="leaveCancelled"
>
<!-- ... -->
</transition>
const options = {
mtehods: {
beforeEneter(el) {
el.style.opacity = 0;
},
enter(el, done) {
done();
},
},
};
多元素/组件过渡(对v-for
中的v-show
、v-if
和:is
起作用):
<transition-group name="list" tag="p">
<span v-for="item in items" :key="item.id"> {{item}} </span>
</transition-group>
过渡方式与单元素/组件过渡的相同,额外的是,可指定元素移动时的过渡:
.list-move {
transition: transform 1s;
}
状态过渡
指基于响应式数据,平滑过渡颜色、数值等的变化。
原理
响应式绑定
cn.vuejs.org/v2/guide/re…
虚拟 dom
每个元素都是一个节点。每段文字也是一个节点。甚至注释也都是节点。一个节点就是页面的一个部分。
就像家谱树一样,每个节点都可以有孩子节点 (也就是说每个部分可以包含其它的一些部分)。
Vue 通过建立一个虚拟 DOM 来追踪自己要如何改变真实 DOM。
生态系统
插件
使用插件(Vue 会自动阻止多次注册相同插件):
import MyPlugin from 'my-plugin';
Vue.use(MyPlugin, options);
编写插件:
MyPlugin.install = function (Vue, options) {
// 通过一系列全局注册或混入...
Vue.directive();
Vue.mixin();
Vue.$method = function () {};
Vue.prototype.$method = function () {};
};
Vue 的核心插件有:
- VueRouter:路由管理。
- Vuex:状态管理。
- Vue SSR:服务端渲染。
工具
Vue 的官方工具有:
- Devtools。
- Vue Cli。
- Vue Loader。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!