vue基础学习笔记
1.vue基础
1.1数据绑定
单向数据绑定的数据流向: data --> template
双向数据绑定的数据流向: data <--> template
1.2MVVM简单理解
- M:Model(模型)--对应vue中的data
- V:View(视图)--对应vue中模板页面
- VM:ViewModel(视图模型)--对应vue中的根实例vm
1.3 Object.defineProperty()
直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
Object.defineProperty(obj, prop, descriptor)
// obj 要定义的对象
// prop 要定义或修改的属性名称
// descriptor 要定义或修改的属性描述符
let p = {
firstName: 'A',
lastName: 'B'
}
Object.defineProperty(p, 'fullName', {
/*
当读取属性值时候回调自动调用,将函数的返回值作为属性值
this指向属性所在的对象
*/
get() {
console.log('get()', this);
return this.firstName + '-' + this.lastName
},
/*
当修改了属性值时候回调自动调用,用来监视属性值的变化
this指向属性所在的对象
*/
set(value) { //value是fullName最新的值
console.log('set()', value);
const names = value.split('-')
this.firstName = names[0]
this.lastName = names[1]
}
})
console.log(p.fullName);
p.firstName = 'C'
p.lastName = 'D'
console.log(p.fullName);
p.fullName = 'E-F'//导致对应的set调用
console.log(p.firstName, p.lastName);
/*
get() {return value} 统称getter
set(value) {} 统称setter
*/
注:关于回调函数的三个问题,1.什么时候执行,2.用来做什么,3.this是谁
1.4计算属性和监听器
计算属性computed
- 什么时候执行:1.初始显示执行第一次,2.依赖数据发生变化
- this.指向vue实例vm(vue控制所有回调的指向都是实例vm/组件对象)
- 什么时候用计算属性:要显示的数据要根据现有的数据计算产生
注:cumputed一定要return
监听器watch
watch: {
dataName(newValue, odlValue) {
}
}
计算属性缓存问题
计算属性存在缓存,提高效率,多次读取只执行一次getter计算,内部通过对象的形式存储缓存v-model绑定数据为对象的属性名,计算的结果为属性值。计算属性执行会先看缓存是否存在,不存在则进行计算,计算后存到缓存中
1.5事件修饰符和按键修饰符
事件修饰符
- 阻止事件默认行为 .prevent
- 停止事件冒泡 .stop
按键修饰符
- @keyup.enter="method"或@keyup.13="method"
1.6生命周期函数
- beforeCreate 1.初始化显示 不能通过vm读取data中的数据
- created 1.初始化显示 已经实现了数据代理/data数据的监视(setter)
- beforeMount 1.初始化显示 不能通过ref读取页面标签
- mounted 1.初始化显示 完成了初始化渲染页面,可读取页面标签
- beforeUpdate 2.更新数据 数据已经改变,看到的是老数据的也买你
- updated 2.更新数据 数据已经改变,看到新数据的页面
- beforeDestroy 3.销毁vue实例 vm.$destroy()
- desreoyed 3.销毁vue实例 vm.$destroy()
1.7过滤器
对想要显示的数据进行特定格式化后在显示,并没改变原数据
时间:{{time | dateFormat('YYYY-MM-DD')}}
Vue.filter('dateFormat', (value, formatStr) => {
return moment(value).format(formatStr || 'YYYY-MM-DD HH:mm:ss')
})
1.8自定义指令
/*
el: 当前标签元素
binding: 包含指令相关数据的对象(value)
*/
Vue.directive('focus', {
inserted(el, binding) {
}
})
1.9插件
//注册插件
const myPlugin = {
install(Vue, options) {
// ....添加全局指令等等
Vue.mixin({
})
}
}
// 使用插件
Vue.use(myPlugin)
2.组件
2.1父子组件通信
props
// 父组件通过自定义属性传值
<Header :title="msg" />
// 子组件通过props接收
export default {
props: {
/*
type类型
required 是否为必填
default 默认值--如果是对象或数组的话需要使用工程模式(函数)返回
*/
title: {
type: 'String',//type: ['String', 'Number'...]
required: true,
default: 'hello props'
}
}
}
注:props是单项数据流
2.2自定义事件
// 父组组件绑定自定义事件-如果有参数通过$vent接收
<Header @ok="handlePage($vent)" />
export default {
methods: {
handlePage(msg) {
console.log(msg)
}
}
}
// 子组件中通过this.$emit('ok')来触发父组件事件
methods: {
handle(value) {
this.$emit('ok','子组件传递给父组件的参数')
}
}
2.3兄弟组件数据交互
事件中心
// 1.创建事件中心
const eventHub = new Vue()
// 2.监听事件与销毁事件
eventHub.$on('add-todo', addTodo)
eventHub.$off('add-todo')
// 3.触发事件
eventHub.$emit('add-todo', id)
2.4组件插槽
父组件向子组件传递内容(模板内容)
<!-- 父组件 -->
<alert-box>哈哈哈哈</alert-box>
<!-- 子组件 -->
<template>
<div>
<slot>如果使用子组件中间没传递内容则显示默认内容</slot>
</div>
<template>
2.5具名插槽
<!-- 父组件 -->
<children-component>
<h1 slot="header">具名插槽内容</h1>
<p>非具名插槽内容</p>
<p>非具名插槽内容</p>
</children-component>
<!-- 子组件 -->
<template>
<div>
<header>
<!-- 渲染父组件中具名插槽的内容 -->
<slot name="header"></slot>
<!-- 渲染非具名插槽的所有内容 -->
<slot></slot>
</header>
</div>
<template>
2.6作用域插槽
应用场景:父组件可以对子组件的内容进行加工处理
3.路由
3.1基础路由
<router-link to="/foo">Go to Foo</router-link>
<!-- 默认情况下router-link会被渲染成a标签 -->
3.2动态路由匹配(路由传参)
// 1.设置动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
// 2.传参数
<router-link to="/user/123">Go to Foo</router-link>
// 3.获取参数
this.$route.params.id
3.3编程式导航
// 1.路径对象跳转和传参
this.$router.push({ path: `/home${userId}` })
// 2.命名路由跳转和传参
this.$router.push({ name: 'user', params: { userId: '123' }})
// 3.router.go(n)
router.go(1)//前进1步
router.go(-1)//后退一步
3.4命名路由
// 路由对象中添加
name: 'user',
//routerlin跳转传参
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
3.5重定向和别名
// 访问/根目录跳转至home页
{
path: '/',
redirect: '/home'
}