事件修饰符
在元素上绑定指定事件触发交互,在事件跟随修饰符可以阻止事件产生的一些我们不想要的行为,并且事件修饰符可以连续绑定,达到不同的阻止效果
- .prevent:阻止默认事件;例如在 a 标签上绑定事件再添加该修饰符可以阻止点击 a 标签默认跳转的行为
- .stop: 阻止事件冒泡
- .once: 事件只触发一次
- .capture: 使用事件的捕获模式
- .self: 只有 event.target 是当前操作的元素才触发事件
- .passive: 事件的默认行为立即执行,无需等待事件回调执行完毕
计算属性:computed
- 定义一个未被定义的属性,该属性由已存在的属性计算得来。
- 定义的计算属性对象存在两个方法:get() 和 set()
- get 用来获取计算返回的结果,set 用于直接修改计算属性对象
- get 的触发时机:1.第一次读取执行一次。2. 当依赖的属性数据变化时再执行
- 计算属性内部存在缓存机制,也就是多次访问时,不会重复计算。会优先读取缓存,效率更高。
- 如果计算属性要被修改,必须写在set 方法去响应修改,且函数体中要引起依赖项的数据变化
- 简写方式:如果计算属性只考虑读取,不考虑修改。则可以使用简写模式
computed: {
自定义属性名: {
get() {
retrun 操作data中定义的数据,也就是操作想要修改的依赖项再返回
},
set(value) {
根据 value 去操作依赖项
}
},
// 如果计算属性只考虑读取,不考虑修改。则可以使用简写模式
'自定义属性名2'() {
retrun 操作data中定义的数据,也就是操作想要修改的依赖项再返回
}
}
监听属性:watch
- 可以监听存在的属性,也就是 data 定义的属性 和 computed 计算的属性
- 当监听的属性变化时,回调函数就会调用
- 当监听的属性是一个对象中的一个属性,则可以直接使用 对象.属性名 再使用引号包裹 的方式定义监听
- 当监听的属性是一个对象, 且对象中的任意一个属性变化都要被监听到,则可以在监听中添加属性
deep: true - immediate 是否初始化就执行一次监听,默认为false
- handler 监听的回调函数
- deep 是否开启深度监听,就是监听多层级结构的变化,默认false
watch: {
要监听的属性名: {
immediate: true, // 默认为 false,是否初始化就监听
handler(newValue, oldValue) {
// 监听可以监听到属性的变化,获取到变化前后的值
// newValue 为监听到变化后的新值
// oldValue 为监听到变化前的旧值
}
},
// 深度监听 对象 中某个属性 通过 对象.属性名 再使用引号包裹
'对象.属性名': {
// 这里面的属性方法和普通监听一致
},
// 当监听的属性是一个对象, 且对象中的任意一个属性变化都要被监听到
监听的对象: {
// 这里面的属性方法和普通监听一致
deep: true // 开启深度监听
},
// 简写方式:不需要其他配置条件时
要监听的属性名(newValue, oldValue) {
}
}
calss绑定与style绑定
- :calss="data中定义的属性",可以通过改变属性的值,来改变元素绑定的 calss 名,且可以跟已绑定的 calss 同时存在:
- 绑定的属性的值可以是:
- 字符串
- 字符串数组
- 对象结构,而属性名为要绑定的calss名,属性值要为布尔值决定该calss名要不要使用
- 绑定的属性的值可以是:
- :style="data中定义的属性",
- 绑定的属性的值可以是:
- 对象结构数据:对象的属性名和属性值与css样式一致,但css中使用‘-’连接的属性要修改成驼峰命名,而对象的属性值可以动态修改的值: {样式名: 样式值, ...}
- 数组包对象的结构数据,将多个对象结构的数据使用数组包裹再使用:[obj1, obj2]
- 绑定的属性的值可以是:
key 的作用
- 它也可以用于强制替换元素/组件而不是重复使用它。
- 简单的理解就是,Vue会通过key对比虚拟DOM,在没有key或者key的值相同时,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。也就是会直接使用之前旧的真实DOM,修改掉不同的节点,相同的节点保留,而不是生成新的。
- 所以有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误。这就是为什么v-for要添加 key 属性
vue的响应式原理
当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。这里需要注意的是不同浏览器在控制台打印数据对象时对 getter/setter 的格式化并不同,所以建议安装 vue-devtools 来获取对检查数据更加友好的用户界面。
每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
注意:
- 由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。尽管如此我们还是有一些办法来回避这些限制并保证它们的响应性。
vue实例中,用于添加响应式数据的方法
- Vue.set() 或 vm.#set()
VUE实例对象重新包装的数组方法
- 数组方法,使用这些重新包装的数组方法可以被Vue实例检测到数组的修改,从而重新渲染页面
- 如果是通过下标方式去修改数组,Vue 不能检测数组的变化。从而页面不会重新渲染,也就是无法响应式
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
v-model的修饰符
- v-model.trim:将收集到的数据清除前后空格
- v-model.number: 将收集到的数据转换成数字类型
- v-model.lazy: 数据将在当前元素失去焦点时候收集
过滤器
- 局部过滤器
- 在单个组件中,创建一个与data同级的 filters 属性,值为对象。对象中可以创建各种过滤器函数方法。
// 过滤器的使用方式 通过 ‘|’ 连接要过滤的数据和过滤器方法
// 过滤器方法可以加(),也可以不加,而过滤器方法的第一个形参,默认都为要过滤的数据
// 调用过滤器方法传入实参,过滤器方法获取到的实参,从第二个形参开始依次对应传入的实参
// 过滤器方法可以连续调用,会将上一个处理的结果传入下一个。
<div>{{value | 过滤器名称}}</div>
<div>{{value | 过滤器名称(传入实参)}}</div>
<div>{{value | 过滤器名称(传入实参) | 过滤器名称2}}</div>
filters: {
过滤器名称(value, 形参2) {
// value 的值由过滤器前的值传递,且是默认传递
// 形参从第二个开始依次对应实参
// 通过对值的操作再返回出去
return newValue
},
// 可以创建多个过滤器
}
- 全局过滤器
- 通过 Vue.felter() 创建全局的过滤器,这样你在项目中任何地方都可以使用,且该方法可以多次调用,注册不同过滤器
- 切记注册全局过滤器一定要在 new 实例之前。
import Vue from 'vue'
// 注册
Vue.filter('my-filter', function (value) {
// 返回处理后的值
})
Vue.filter('my-filter2', function (value) {
// 返回处理后的值
})
自定义指令
- 局部自定义指令
- 在单个组件中,创建一个与data同级的 directives 属性,值为对象。对象中可以创建各种指令函数方法。
- 函数式自定义指令执行的时机:1.指令与元素成功绑定时(注意这里的时机,实际dom元素还为创建)。2.指令所在的模板重新解析时。
- 创建自定义指令可以是绑定函数,也可以是一个对象,vue指定了对象中存在的钩子函数,也就是不同时机触发的函数
- 一般情况下都使用 函数式的自定义指令,也是对象形式的一种简写,但如果有一些情况下需要在元素插入到页面中时再操作就需要使用对象的形式创建自定义指令。例如想要页面一加载完成 input 元素就聚焦,就需要对真实dom进行操作。
- 注意点:
- 自定义指令的名字不支持驼峰命名,一般都使用小写,或者使用‘-’来连接单词,当然使用‘-’来命名时,需要将名字使用引号包裹
- 自定义指令中任何地方访问 this 指向都是 window
//
directives: {
// 创建 函数式自定义指令
自定义指令名称(element, binding) {
// element 是使用自定义指令的当前dom元素
// binding.value 可以获取到传递给自定义指令的值,就是`v-自定义指令名="值"`
// 自定义指令就可以根据需求去操作dom元素,想要给那个元素做操作就给那个元素绑定自定义指令
},
// 创建 绑定对象的 自定义指令,vue指定了对象中存在的钩子函数,
// 函数式的自定义指令其实就是一种简写方式,它也是直接调用了,对象属性中 bind 和 update的钩子函数
//
自定义指令名称2: {
// bind 指令与元素成功绑定时执行
bind: function () {},
// inserted 指令所绑定的元素插入到页面时执行
inserted: function () {},
// update 指令所绑定的元素在模板中重新解析
update: function () {},
},
}
- 全局自定义指令
import Vue from 'vue'
// 注册全局指令 且要在 new 实例之前
Vue.directive('自定义指令名称', '第二个参数可以是函数,也可以是对象。不管哪种形式都与局部自定义指令一样配置')
组件化模块
new Vue() 创建根组件实例
new VueComponent() 创建给根组件使用的子组件实例,VueComponent 这个构造函数是 Vue 自己帮我们调用创建一个组件实例的
Vue中子组件与根组件的重要的关系
VueComponent.prototype.__proto__ === Vue.prototype- 从上面等式可以看出,这是为了让组件实例对象可以访问到Vue 实例原型上的属性以及方法。
混入(mixin)
- 将组件中具有相同处理功能的函数方法提取到一个文件中,通过暴露和引入的方式,去注册混入。达到每个混入的组件都可以实现这个功能。
- 这样就不需要每个组件编写同样的代码,还可以统一管理。
- 混入是通过混入组件中的配置项,相同的配置项会合并。(配置项例如:data,methods,mounted)
- 如果混入的方法或属性与组件内部重复,则会以组件内部为主。
- 混入生命周期配置,而组件内部也有相同的生命周期,则都会执行生命周期里面的代码
- 特别注意混入相同的生命周期,则混入的代码先执行,组件内部的后执行
// 定义混入文件 myMixin.js,通过分别暴露的方式,想要使用哪个混入这引入那个
export const mixin1 = {
methods: {
showName(){
alert(this.name)
}
},
mounted() {
console.log('你好啊!')
},
}
export const mixin2 = {
data() {
return {
name: 'hhh'
}
},
}
// 在组件中 局部混入
import {mixin1, mixin2} from '混入的文件路径'
// 在与 data 同级的配置 mixins 中注册混入
mixins:[mixin1, mixin2]
// 也可以全局混入
// 在项目的入口文件 main.js 中注册
import {mixin1, mixin2} from '混入的文件路径'
Vue.mixin(mixin1)
Vue.mixin(mixin2)
// 这时候,所有的组件包括根组件都混入了定义的配置