vue.js的两个核心是什么
- 数据驱动也叫双向数据绑定
Vue.数据观测管理在技术实现上,利用的是ES5Object.defineProperty和存储器属性:getter和setter,可称为基于依赖收集的观测机制。核心是VM,保证数据和视图的一致性
- 组件系统
1.模板(template):模板声明了数据和最终展现给用户的DOM之间的映射
2.初始数据(data):一个组件的初始数据状态。对于可复用的组件来说,这通常是私有状态
3.接受外部参数(props):组件之间通过参数来进行数据的传递和共享
4.方法(methods):对数据的改动操作一般都在组件的方法内进行
5.生命周期钩子函数(lifecycle hookss):一个组件会触发多个生命周期钩子函数,最新版本对于生命周期函数名称改动很大
6.私有资源(assets): Vue.js当中将用户自定义的指令、过滤器、组件统称为资源,一个组件可以声明自己的私有资源。私有资源只有该组件和它的子组件可以调用
vue几种常用的指令
- v-if: 根据表达式的值的真假条件渲染元素,在切换时元素及它的数据绑定/组件被销毁并重建
- v-show: 根据表达式的真假判断,切换元素的display CSS属性
- v-for: 循环指令,基于一个数组或者对象渲染一个列表,vue2.0以上必须配合Key使用
- v-bind: 动态绑定一个或多个特性,或一个组件prop到表达式
- v-on:用于监听指定元素的DOM事件,比如点击事件和绑定事件监听器
- v-modle:实现表单传输和应用状态之间的双向绑定
- v-pre:跳过这个元素和它的子元素的编译过程,可以用来显示Mustache标签,跳过大量没有指令的节点会加快编译
- v-once: 只渲染元素和组件一次,随后重新渲染,元素/组件及其所有子节点将被视为静态内容并跳过,这可以优化更新性能
v-if和v-show的具体区别
- 共同点:v-if和v-show都能动态显示DOM元素
- 区别:
- 编译过程:v-if是真正的条件渲染,因为它会确保在切换过程中条件块内事件监听器和子组件适当被销毁和重建。v-show的元素始终会被渲染并保留在DOM中,v-show只是简单切换元素的css属性display
- 编译条件:v-if是惰性的,v-show不管在什么条件下,元素总会被渲染,并且只是简单的css切换
- 性能消耗:v-if有更高的切换消耗。v-show有更高的初始渲染消耗
- 应用场景:v-if适合运行时条件很少改变时使用。v-show适合频繁切换
vue常用修饰符
v-on 指令常用修饰符
- .stop 调用event.stopPropagation() 禁止事件冒泡
- .prevent 调用envent.preventDefault() 阻止事件默认行为
- .capture 添加事件侦听器使用capture模式
- .self 当事件是从侦听器绑定的元素本身触发时才触发的回调
- .{keyCode | keyAlias} 只当事件从特定键触发时才触发回调
- .native 监听组件根元素的原生事件
- .once 只触发一次回调
- .left 只当点击鼠标左键触发
- .right 只当点击鼠标右键触发
- .middle 只当点击鼠标中键触发
- .passive 以{passive: true} 模式添加侦听器
v-bind 指令常用修饰符
- .prop 被用于绑定DOM属性
- .camel 将kebab-case特性名转换成camelCase
- .sync 语法糖,会拓展成一个更新父组件绑定值的v-on侦听器
v-model 指令常用修饰符
- .lazy 取代input监听change事件
- .number 输入字符串转为数字
- .trim 输入首尾空格过滤
v-on可以监听多个方法吗
v-on可以监听多个方法
<input type="text" :value="name" @input="onInput" @focus="onFocus" @blur="onBlur" />
但是不能监听同一种事件类型否则就会报错
vue中key值的作用
- 用于管理可复用的元素,因为vue会尽可能高效渲染元素,通常会复用已有元素而不是从头开始渲染,这么做使vue变得非常快,但是这样也不总符合实际要求
- 因为两个模板使用了相同元素将不会清除用户已经输入的内容,添加唯一值Key属性可以让这两个元素完全独立,不要复用它们
vue事件中使用event对象
//html部分
<a href="javascript:void(0);" data-id="12" @click="showEvent($event)">event</a>
//js部分
showEvent(event){
// 获取自定义data-id
console.log(event.target.dataset.id)
//阻止事件冒泡
event.stopPropagation()
//阻止默认
event.preventDefault()
}
$nextTick
- 因为vue异步更新队列,$nextTick用来知道什么时候DOM更新完成
<div id="app">
<div id="div" v-if="showDiv">这是一段文本</div>
<button @click="getText">获取div内容</button>
</div>
<script>
var app = new Vue({
el : "#app",
data:{
showDiv : false
},
methods:{
getText:function(){
this.showDiv = true;
var text = document.getElementById('div').innnerHTML;
console.log(text);
}
}
})
</script>
这段代码在运行之后会在控制台抛出错误,意思就是获取不到div元素,这里就涉及vue一个很重要的概念:异步更新队列
异步更新队列
vue在观察到数据变化时,并不是直接更新DOM,而是开启一个队列,并缓冲在同一个事件循环中发送的所有数据改变,在缓存中会去除重复数据,从而避免不必要的计算和DOM操作,然后,在下一个事件循环tick中,Vue刷新队列并执行实际(已去重的)工作。所以如果你用一个for循环来动态改变数据100次,其实它只会应用最后一次改变,如果没有这种机制,DOM就要重绘100次,这固然是一个很大的开销。
// $nextTick用来知道DOM什么时候更新完成的,上面的代码修改为:
<div id="app">
<div id="div" v-if="showDiv">这是一段文本</div>
<button @click="getText">获取div内容</button>
</div>
<script>
var app = new Vue({
el : "#app",
data:{
showDiv : false
},
methods:{
getText:function(){
this.showDiv = true;
this.$nextTick(function(){
var text = document.getElementById('div').innnerHTML;
console.log(text);
});
}
}
})
</script>
理论上,我们应该不用去主动操作DOM,因为Vue的核心思想就是数据驱动DOM,但在很多业务里,我们避免不了会使用一些第三方库,比如 popper.js、swiper等,这些基于原生javascript的库都有创建和更新及销毁的完整生命周期,与Vue配合使用时,就要利用好$nextTick。
vue 组件中data为什么必须是函数
- 因为一个组件是可以共享的,但是它们的data是私有的,所以每个组件都要return一个新的data对象,返回一个唯一对象,不要和其他组件共用一个对象
var MyComponent = function() {
this.data = this.data()
}
MyComponent.prototype.data = function() {
return {
a: 1,
b: 2,
}
}
这样每一个实例的data属性都是独立的,不会相互影响了,vue组件的data必须是函数,因为js本身的特性带来的,跟vue本身设计无关
v-for与v-if的优先级
- 当它们处于同一节点,v-for的优先级比v-if更高,这意味着v-if将分别重复运行于每个v-for循环中,当你想为仅有的一些项渲染节点时,这种优先机制十分有用
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
上面的代码只传递了未完成的todos
而如果你的目的是有条件跳过循环的执行,那么可以将v-if置于外层元素
<ul v-if="todos.length">
<li v-for="todo in todos">
{{ todo }}
</li>
</ul>
<p v-else>No todos left!</p>
vue中子组件调用父组件的方法
通过v-on监听和$emit触发来实现
- 在父组件中通过v-on监听当前实例上的自定义事件
- 在子组件中通过$emit触发当前实例上的自定义事件
// 父组件
<template>
<div class="fatherPageWrap">
<h1>这是父组件</h1>
<!-- 引入子组件,v-on监听自定义事件 -->
<emitChild v-on:emitMethods="fatherMethod"></emitChild>
</div>
</template>
<script type="text/javascript">
import emitChild from '@/page/children/emitChild.vue'
export default{
data () {
return {}
},
components: {
emitChild
},
methods: {
fatherMethod(params){
alert(JSON.stringify(params));
}
}
}
</script>
// 子组件
<template>
<div class="childPageWrap">
<h1>这是子组件</h1>
</div>
</template>
<script type="text/javascript">
export default{
data() {
return {}
},
mounted () {
//通过 emit 触发
this.$emit('emitMethods',{"name" : 123});
}
}
</script>
vue中keep-alive组件的作用
- keep-alive 主要用于保留组件状态或避免重新渲染
- 属性:
include: 字符串或正则表达式。只会匹配的组件会被缓存
exclude: 字符串或正则表达式。任何匹配的组件都不会被缓存 - 用法:
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition>相似,<keep-alive>是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中