
持续更新中 ······
Computed && Methods && Watch
1.computed
监听响应式的数据,非响应数据不可用
2.methods
方法:无论是否响应,都作为函数处理
3.watch
监听:可以在监听中调用别的函数,处理异步操作(包括节流防抖!!)
Vue filter
引用官方案例~~~~
定义:
当全局过滤器和局部过滤器重名时,会采用局部过滤器。
在当前的script中定义一个局部的filter
filters: { //filters有s
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
全局定义!!!!!但必须在实例化Vue之前定义!!!!
Vue.filter('capitalize', function (value) { // filter没有s
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
new Vue({
// ...
})
{{ message | filterA | filterB }} // 1
{{ message | filterA('arg1', arg2) }} // 2
- 1.可接受多个参数filterA 被定义为接收单个参数的过滤器函数,表达式 message 的值将作为参数传入到函数中。然后继续调用同样被定义为接收单个参数的过滤器函数 filterB,将 filterA 的结果传递到 filterB 中。
- 2.过滤器是js函数,filterA 被定义为接收三个参数的过滤器函数。其中 message 的值作为第一个参数,普通字符串 'arg1' 作为第二个参数,表达式 arg2 的值作为第三个参数。
用法
index.vue中html结构处使用
<!-- 在双花括号中 -->
{{ message | capitalize }}
<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>
弊端(无法在script中使用)(作为工具类中的函数定义)
{{ message }}
import filterName from 'xxxxx'
<script>
computed:{
message(){
return filterName(args)
}
}
</script>
TS中使用vue过滤器
使用vue-property-decorator时可以使用以下方式进行过滤器的引用
<!-- 在双花括号中 -->
{{ message | filterName }}
@Component({
filters:{
filterName
}
})
Transition动画
1.Vue 提供了 transition 的封装组件,可以给任何元素和组件添加进入/离开过渡**
- 条件渲染 (使用 v-if)
- 条件展示 (使用 v-show)
- 动态组件
- 组件根节点
<transition name="fade">
<p v-if="show">hello</p>
</transition>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
动画运行的过程:
-
当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理:
-
检测目标组件是否应用了 CSS 过渡(transtion)或动画(animation),如果是,则添加/删除 CSS 类名。
-
如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。
-
如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同)
2.使用css3动画
<transition name="bounce">
<p v-if="show">Lorem ipsum dolor sit amet, consectetur adipiscing elit. </p>
</transition>
.bounce-enter-active {
transform-origin:left center; //解决放大缩小可能遇到的问题
animation: bounce-in .5s;
}
.bounce-leave-active {
transform-origin:left center; //解决放大缩小可能遇到的问题
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
3.自定义过渡的类名
<transition name="bounce" enter-active-class='active' leave-active-class='leave'>
<p v-if="show">Lorem ipsum dolor sit amet, consectetur adipiscing elit. </p>
</transition>
.active {
transform-origin:left center; //解决放大缩小可能遇到的问题
animation: bounce-in .5s;
}
.leave {
transform-origin:left center; //解决放大缩小可能遇到的问题
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
4.使用animate.css 库动画
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" type="text/css">
<transition
name="custom-classes-transition" //类名随意
enter-active-class="animated tada" //animated必须写,否则无法进行动画
leave-active-class="animated bounceOutRight"
>
<p v-if="show">hello</p>
</transition>
4.同时使用过渡和动画
初始化渲染页面的动画
可以通过 appear 特性设置节点在初始渲染的过渡
css类名为swing
<transition
appear //必须写,声明初始化渲染
appear-class="swing" //可不写
appear-to-class="swing" (2.1.8+)//版本需求
appear-active-class="swing"
>
<!-- ... -->
</transition>
5.动画的过渡时间
在这种情况下你可以用 <transition> 组件上的 duration 属性定制一个显性的过渡持续时间 (以毫秒计):
<transition :duration="1000">...</transition>
你也可以定制进入和移出的持续时间:
<transition :duration="{ enter: 500, leave: 800 }">...</transition>
6.Javascript钩子(可配合Velocity.js)
<transition
:before-enter="beforeEnter"
:enter="enter"
:after-enter="afterEnter"
:enter-cancelled="enterCancelled"
:before-leave="beforeLeave"
:leave="leave"
:after-leave="afterLeave"
:leave-cancelled="leaveCancelled"
>
<!-- ... -->
</transition>
// ...
当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。
否则,它们将被同步调用,过渡会立即完成。methods: {
// --------
// 进入中
// --------
beforeEnter: function (el) {
// ...
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
enter: function (el, done) {
// ...
done()
},
afterEnter: function (el) {
// ...
},
enterCancelled: function (el) {
// ...
},
// --------
// 离开时
// --------
beforeLeave: function (el) {
// ...
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
leave: function (el, done) {
// ...
done()
},
afterLeave: function (el) {
// ...
},
// leaveCancelled 只用于 v-show 中
leaveCancelled: function (el) {
// ...
}
}
7.多元素或组件过渡
当有相同标签名的元素切换时,Vue 为了效率只会替换相同标签内部的内容,需要通过 key 特性设置唯一的值来标记以让 Vue 区分
给在 <transition> 组件中的多个元素设置 key 是一个更好的实践。
<transition mode='in-out'> //in-out先进入后移除 out-in 先移除后进入
<div v-if='show' key='hello'>hello</div>
<div v-else key='bye'>bye</div>
</transition>
组件过渡动画可以使用is的特性来完成,不需要使用key来进行区分
8.列表过渡
<transition-group>
<transition-group name="list" tag="p">
<span v-for="item in items" :key="item">
{{ item }}
</span>
</transition-group>
相当于
<transition>
<span>
{{ item }}
</span>
<span>
{{ item }}
</span>
<span>
{{ item }}
</span>
</transition>
解析 DOM 模板时的注意事项
有些 HTML 元素,诸如<ul>、<ol>、<table>和<select>,对于哪些元素可以出现在其内部是有严格限制的。 而有些元素,诸如 <li>、<tr>和<option>,只能出现在其它某些特定的元素内部。 这会导致我们使用这些有约束条件的元素时遇到一些问题。
例如:
<table>
<blog-post-row></blog-post-row>
</table>
这个自定义组件 <blog-post-row> 会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is 特性给了我们一个变通的办法:
<table>
<tr is="blog-post-row"></tr>
</table>
需要注意的是如果我们从以下来源使用模板的话,这条限制是不存在的:
- 字符串 (例如:template: '...')
- 单文件组件 (.vue)
<script type="text/x-template">
参数校验
我们可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这在开发一个会被别人用到的组件时尤其有帮助。
为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。例如:
Vue.component('my-component', {
props: {
// 基础的类型检查 (`null` 匹配任何类型)
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
}
}
}
})
循环引用
1.递归组件
组件在自己的模板中调用自身的。需要通过 name 选项来做这件事:
- 局部注册
name: 'unique-name-of-my-component'
- 全局注册
当你使用
Vue.component全局注册一个组件时,这个全局的 ID 会自动设置为该组件的name选项。
Vue.component('unique-name-of-my-component', {
// ...
})
注意点:递归调用需要有一个边界值来终止(比如使用v-if来处理),否则会导致无限循环
name: 'stack-overflow',
template: '<div><stack-overflow></stack-overflow></div>'
上述组件将会导致“max stack size exceeded”
组件之间的循环引用
假设你需要构建一个文件目录树,像finder或资源管理器那样的。你可能有一个 <tree-folder> 组件:
<p>
<span>{{ folder.name }}</span>
<tree-folder-contents :children="folder.children"/>
</p>
还有一个 <tree-folder-contents> 组件:
<ul>
<li v-for="child in children">
<tree-folder v-if="child.children" :folder="child"/>
<span v-else>{{ child.name }}</span>
</li>
</ul>
你会发现这些组件在渲染树中互为对方的后代和祖先——一个悖论!当通过 Vue.component 全局注册组件的时候,这种问题不存在
然而,如果你使用一个模块系统依赖/导入组件,例如通过 webpack 或 Browserify,你会遇到一个错误:
Failed to mount component: template or render function not defined.
解释:
我们先把两个组件称为 A 和 B。模块系统发现它需要 A,但是首先 A 依赖 B,但是 B 又依赖 A,但是 A 又依赖 B,如此往复。这变成了一个循环,不知道如何不经过其中一个组件而完全解析出另一个组件。为了解决这个问题,我们需要给模块系统一个点,在那里“A 反正是需要 B 的,但是我们不需要先解析 B。”
在我们的例子中,把 <tree-folder> 组件设为了那个点。我们知道那个产生悖论的子组件是 <tree-folder-contents> 组件,所以我们会等到生命周期钩子 beforeCreate 时去注册它:
beforeCreate: function () {
this.$options.components.TreeFolderContents = require('./tree-folder-contents.vue').default
}
或者,在本地注册组件的时候,你可以使用 webpack 的异步 import:(个人推荐)
components: {
TreeFolderContents: () => import('./tree-folder-contents.vue')
}
混入
用处:
分发Vue组件中的可复用功能
使用
定义mixin
var mixin = {
created:function(){
this.hello()
},
methods:{
hello:function(){
console.log('hello mixin')
}
}
}
在组件中使用mixin
import mixin from xxxxxxx
var Component = Vue.extend({
mixins:[mixin]
})
var comp = new Component() // 输出:hello mixin
注意点:
- 数据对象:当组件使用混入对象时,混入的对象选项都会进入该组件本身的选项中,如果有同名的属性和方法,以组件内部的对象为主,否则合并数据对象
- 钩子函数:同名的钩子函数将合并为一个数组,并且混入对象的钩子将在组件钩子之前被调用
- 全局混入:全局混入将影响每一个之后创建的Vue实例,不建议使用,如果需要,可以作为插件发布使用
自定义选项合并策略
自定义选项将使用默认策略,即简单地覆盖已有值。如果想让自定义选项以自定义逻辑合并,可以通过 Vue.config.optionMergeStrategies 进行处理
有需要的直接传送门
自定义指令
官方传送门(个人觉得很详细了)