一、常用指令及事件:
v-model | 实现双向数据绑定,实时监控数据变化,一般用于表单。常用于输入框 |
v-for | 用于遍历数组、对象等 |
v-on | 用于绑定时间,用法:v-on : 事件 = “函数” |
v-show | 用来显示或隐藏元素,v-show是通过display实现。值为true或false |
1、事件对象:可以通过事件对象取得事件相关信息(事件源、事件类型、偏移量...)
<template>
<div>
<button type="button" @click="print($event)">点击显示按钮的值</button><br/>
<p style="padding:20px; border:2px solid #f00;">{{msg}}</p>
</div>
</template>
<script>
export default {
data () {
return {msg: '目标'}
},
methods: {
print (e) {this.msg = e.target.innerHTML}
}
}
</script>
2、事件冒泡与事件默认行为:@click.stop = "函数名()" @click.prevent = “函数名()”
3、键盘事件:@keydown.13 = “函数名()” @keydown.enter = “函数名()”
.native | 监听组件根元素的原生事件 |
.once | 只触发一次回调 |
4、数据绑定:
双向数据绑定:v-model
单向数据绑定:a、{{}};b、使用指令v-text、v-html。
其中{{}},在需要长时间编译时会在页面中出现{{}}闪烁,可以用v-cloak配合css的display为none解决。
<div v-cloak>{{msg}}</div>
<style scoped> [v-cloak] {display: none;} </style> //css内容
二、过滤器:vue.filter(过滤器id,过滤器函数)
三、vue生命周期:vue实例从创建到销毁的过程,称为生命周期。
共有八个阶段,这八个阶段里分别有一个叫做钩子函数的实例选项。
beforeCreate(){} | 在实例初始化之后,数据观测data observer(props、data、computed ) 和 event/watcher 事件配置之前被调用。 |
created(){} | 实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。 |
beforeMount(){} | 模板编译之前,还没挂载值。在挂载开始之前被调用:相关的 render 函数首次被调用。 |
mounted(){} | 模板编译之后,已经挂载,此时才会渲染页面,才能看到页面上数据的展示。el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。 |
beforeUpdate(){} | 组件更新之前,数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。 你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。 |
updated(){} | 组件更新之后,无论是组件本身的数据变更,还是从父组件接收到的 props 或者从vuex 里面拿到的数据有变更,都会触发虚拟 DOM 重新渲染和打补丁,并在之后调用 updated 。 |
beforeDestroy(){} | 组件实例销毁之前调用。在这一步,实例仍然完全可用。 |
destroyed(){} | 组件实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。 |
created 阶段的ajax 请求 | 页面视图未出现,如果请求信息过多,页面会长时间处于白屏状态 |
mounted 请求 |
<template>
<div>
<div id="first">{{msg}}</div>
</div>
</template>
<script>
export default {
data () {
return {msg: '生命函数'}
},
beforeCreate () {
console.log('beforecreate: ', document.getElementById('first')) // null
console.log('data:', this.text) // undefined
this.sayHello() // error:not a function
},
created () {
console.log('create:', document.getElementById('first')) // null
console.log('data:', this.text) // this.text
this.sayHello() // this.sayHello()
},
beforeMount () {
console.log('beforeMount:', document.getElementById('first')) // null
console.log('data:', this.text) // this.text
this.sayHello() // this.sayHello()
},
mounted () {
console.log('mounted:', document.getElementById('first')) // <p></p>
console.log('data:', this.text) // this.text
this.sayHello() // this.sayHello()
},
methods: {
sayHello () {
this.msg = '又执行啦!'
}
}
}
</script>
生命周期 | 是否获取dom节点 | 是否可以获取data | 是否获取methods |
beforeCreate | 否 | 否 | 否 |
created | 否 | 是 | 是 |
beforeMount | 否 | 是 | 是 |
mounted | 是 | 是 | 是 |
单个组件的生命周期:
- 初始化组件时,仅执行了
beforeCreate/Created/beforeMount/mounted
四个钩子函数 - 当改变data中定义的变量(响应式变量)时,会执行
beforeUpdate/updated
钩子函数 - 当切换组件(当前组件未缓存)时,会执行
beforeDestory/destroyed
钩子函数 - 初始化和销毁时的生命钩子函数均只会执行一次,
beforeUpdate/updated
可多次执行
四、计算属性:
计算属性也是用来存储数据,其中:数据可以进行逻辑处理操作,对计算属性中的数据进行监视。计算属性有get(获取计算属性)和set(设置计算属性)两部分组成,默认只有get,如果需要set,要自己添加。
<template>
<div>
<div>{{num}}----{{addZero}}</div><br/>
<button type="button" @click="change">点击改变num</button>
</div>
</template>
<script>
export default {
data () {
return {num: 8}
},
methods: {
change: function () { this.num++ }
},
computed: { // 点击会有09、010、11
addZero () { return this.num > 10 ? this.num : '0' + this.num } // 这是计算属性的get方法,用于取值
}
}
</script>
计算属性(computed) | VS | 方法(methods) |
基于它的依赖进行实时更新的 | 调用才更新 | |
有缓存的,只要相关依赖没有改变,多次访问计算属性得到的值是之前缓存的计算结果,不会多次执行。操作一个没有依赖项的值也是如此 |
<template>
<div>{{num}}----{{addZero}}<br/>
<button type="button" @click="change(6)">点击改变num</button>
</div>
</template>
<script>
export default {
data () {
return {num: 8}
},
methods: {
change (newNumber) { this.addZero = newNumber }
},
computed: {
addZero: { // 直接显示8----08,点击后变成了6----06
get () { return this.num > 10 ? this.num : '0' + this.num },
set (newNum) { this.num = newNum }
}
}
}
</script>
五、实例属性和方法:
1、属性:
vm.$el | 获取vue实例关联的元素DOM,进而可以对其进行操作 |
vm.$data | 获取数据对象data |
vm.$options | 获取选项,自定义的选项也可以在这里获取 |
vm.$refs | 获取所有添加ref属性的元素dom对象,进而可以对其进行操作 |
2、方法:
vm.$mount() | 手动挂载vue实例 |
vm.$destroy() | 销毁实例所占的内存空间 |
vm.$nextTick(callback) | 在下次DOM更新完成后再执行延迟回调函数,一般在修改数据之后使用该方法,以便获取更新后的DOM。 |
vm.$set(target, key, value) | 通过vue实例的$set方法为对象添加属性,可以实时监视 |
vm.$watch(监听的属性, callback) | 监控vue实例的变化。如果需要监控深度数据变化,则需要在选项中添加{deep: true} |
什么时候需要用Vue.nextTick()
:
- 在
Vue
生命周期的created()钩子函数进行的DOM
操作一定要放在Vue.nextTick()
的回调函数中。因为是在created()
钩子函数执行的时候DOM
其实并未进行任何渲染,而此时进行DOM
操作无异于徒劳,所以此处一定要将DOM
操作的js
代码放进Vue.nextTick()
的回调函数中。与之对应的就是mounted钩子函数,因为该钩子函数执行时所有的DOM
挂载和渲染都已完成,此时在该钩子函数中进行任何DOM
操作都不会有问题 。 - 在数据变化后要执行的某个操作,当你设置
vm.someData = 'new value'
,DOM
并不会马上更新,而是在异步队列被清除,也就是下一个事件循环开始时执行更新时才会进行必要的DOM
更新。如果此时想要根据更新的DOM
状态去做某些事情,就会出现问题。为了在数据变化之后等待Vue
完成更新DOM
,可以在数据变化之后立即使用Vue.nextTick(callback)
。这样回调函数在DOM
更新完成后就会调用。 mounted
不会承诺所有的子组件也都一起被挂载。如果你希望等到整个视图都渲染完毕,可以用vm.$nextTick
替换掉mounted
:
mounted: function () {
this.$nextTick(function () {})
}
<template>
<div>
{{user.name}}<br/>{{user.age}}<br/>
<button type="button" @click="addAge">添加属性</button>
</div>
</template>
<script>
export default {
data () {
return { user: {name: 'zhangsan', gender: 'man'} }
},
methods: { //使用this.user.age = 26就不会显示
addAge () { this.$set(this.user, 'age', 26) }
}
}
</script>
六、自定义指令:
1、自定义全局指令:大多数情况下,我们只需要使用bind与upage钩子函数(钩子函数与两个常用参数el和binding。el是绑定的DOM对象,binding是一个对象,包含若干属性)
<template>
<div>
<p v-hello>这是自定义指令</p>
</div>
</template>
<script>
export default {
directives: {
'hello': {
bind () { alert('1-指令第一次绑定到元素上时调用,只调用一次,可执行初始化操作') },
inserted () { alert('2-被绑定元素插入到DOM中时调用') },
update () { alert('被绑定元素所在模板更新时调用') },
componentUpdated () { alert('被绑定元素所在模板完成一次更新周期时调用') },
unbind () { alert('2-指令与元素解绑时调用,只调用一次') }
}
}
}
</script>
<template>
<div>
<p v-hello:123.bar = "msg">这是自定义指令</p>
</div>
</template>
<script>
export default {
data () {
return {msg: '我是自定义'}
},
directives: {
'hello': function (el, binding) {
el.style.color = 'green'
console.log(binding.name) // hello,属性name是指令的名字(不带v-)
console.log(binding.value) // 我是自定义,属性value是传递给指令的值
console.log(binding.expression) // msg,属性expression是指令值的字符串形势(有点类似变量名)
console.log(binding.arg) // 123,属性arg是传递给指令的参数
console.log(binding.modifiers) // {bar: true},属性modifiers是一个包含修饰符的对象
}
}
}
</script>
2、局部自定义指令:
七、vuex store 是响应式的,当vue组件从store中读取状态(state)时,若store中的状态发生更新时,会及时的响应给其他的组件。
//myStore.vue
<template>
<div>
过滤后的列表:{{list}} <br/>
列表长度: {{listCount}}
</div>
</template>
<script>
import store from './myStore01'
export default {
name: 'MyStore',
computed: {
list () {
return this.$store.getters.filteredList
},
listCount () {
return this.$store.getters.listCount
}
},
store
}
</script>
// myStore01.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
list: [1, 3, 5, 7, 9, 20, 30, 4, 6]
},
getters: {
filteredList: state => {
return state.list.filter(item => item > 5)
},
listCount: (state, getters) => {
return getters.filteredList.length
}
}
})
export default store
八、过度动画:
1、基本用法:使用transition组件,将要执行动画的元素包含在该组件内
<template>
<div>
<button type="button" @click="flag = !flag">点击</button>
<transition name="fade"><p v-show="flag">运动的元素</p></transition>
</div>
</template>
<script>
export default {
data () {
return {flag: false}
}
}
</script>
<style scoped>
button{ display: block; margin: 20px auto;}
p{ width: 120px; height: 120px; background-color: crimson; margin: 0 auto;}
.fade-enter-active, .fade-leave-active{ transition: all 2s ease;} /* 定义整个过渡期间的效果*/
.fade-enter-to{ opacity: 1; width: 120px; height: 120px;} /* 定义过渡进入的最终效果 */
.fade-leave-to{ opacity: 1; width: 50px; height: 50px;} /* 定义过渡离开的最终效果 */
.fade-enter{ opacity: 1; width: 50px; height: 50px;} /* 定义过渡进入的开始效果 */
</style>
2、钩子函数:vue中给过渡的不同时期提供了不同的钩子函数
<template>
<div>
<transition name="fade" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter" @before-leave="beforeLeave" @leave="leave" @after-leave="afterLeave">
<p v-show="flag"></p>
</transition>
<button @click="flag = !flag">点击</button>
</div>
</template>
<script>
export default {
data () {
return {flag: false}
},
methods: {
beforeEnter (el) { alert('1-动画进入之前') },
enter (el) { alert('2-动画进入') },
afterEnter (el) { alert('3-动画进入之后') },
beforeLeave (el) { alert('4-动画离开之前') },
leave (el) { alert('5-动画离开') },
afterLeave (el) { alert('6-动画离开之后') }
}
}
</script>
<style scoped>
p{ width: 50px; height: 50px; background-color: darkmagenta;}
</style>
3、多元素过渡:<transition-group></transition-group>
<template>
<div>
<button type="button" @click="flag = !flag">点击</button>
<transition-group name="fade">
<p v-show="flag" :key="1">矩形一</p>
<p v-show="flag" :key="2">矩形二</p>
</transition-group>
</div>
</template>
<script>
export default {
data () {
return {flag: false}
}
}
</script>
<style scoped>
button{ display: block; margin: 20px auto;}
p{ width: 100px; height: 100px; background-color: crimson; margin: 20px auto;}
.fade-enter-active, .fade-leave-active{ transition: all 2s ease;} /* 定义整个过渡期间的效果*/
.fade-enter-to{ opacity: 1; width: 100px; height: 100px;} /* 定义过渡进入的最终效果 */
.fade-leave-to{ opacity: 1; width: 15px; height: 15px;} /* 定义过渡离开的最终效果 */
.fade-enter{ opacity: 1; width: 15px; height: 15px;} /* 定义过渡进入的开始效果 */
</style>
4、animate.css库一起使用