# 基础语法
虚拟dom,就是用普通的js对象去模拟 真实的dom
指令:凡是 v- 开头的行内属性 我们都称为vue指令
- v-model:主要应用于表单元素 value属性和input事件的一个合体
- v-text:解决小胡子语法的显示问题
- v-html:等同于原生innerHTML
- v-cloak:解决小胡子语法的显示问题
- v-pre:优化性指令(告诉vue 该指令下的所有元素不需要编译)
- v-if、v-else-if、v-else、v-show
- v-if 有比较大的初始加载开销(整体结构不加载)
- v-show 有比较大的切换开销 (display:none)
- v-for 循环 数组、对象、字符串和数字
- v-bind:变量名 => :变量名、:key=> 提升渲染性能
- 事件修饰符:
- .stop 阻止时间冒泡
- .prevent 组织默认事件
- .capture 在捕获阶段执行
- .self 只在点击当前元素的时候才会执行,冒泡传播不执行
- .once 只会执行一次
- .passive 优先执行默认行为还是绑定事件
- 按键修饰符
- .enter
- .tab
- .delete
- .esc
- .space
- .up
- .down
- .left
- .right
- v-model
- .lazy
- .number
- .trim
- 事件修饰符:
- :class='{active: true, normal: false}'
- v-on:事件名(v-on:click)
definProperty 实现 数据双向绑定,vue3 采用Proxy
function definep(obj, key, value) { Object.defineProperty(obj, key, { get: function proxyGetter(){ return value }, set(val){ value = val; } }) } var obj2 = new Proxy(obj, { get(target, key){ return target[key] }, set(target, key, val){ target[key] = val; } })
:class => 接收 [string/array/object]
:style => 接收 [string/array/object]
# JSX
export default {
data(){
return {
name: 'aa'
}
},
render(h){
return h('h1', {
class: 'box',
attrs: {id: 'app'}
}, [
h('input', {
domProps: {
value: this.name
},
on: {
input: function(e){
this.name = e.target.value;
}
}
}),
this.name,
h('i', this.name)
])
}
}
当使用组件编写时代码冗余,则可尝试使用jsx编写
# 生命周期
new Vue 对应的执行过程
- 初始化时间和生命周期
- beforeCreate
- 初始化依赖注入
- created:可以使用vue数据
- 检测 el 容器是否存在
# router
// history 模式 => 访问不存在页面的时候,直接重定向到index.html
const routes = [
{
path: '/about',
name: 'About',
recirect: '/about/a', // 打开about 直接重定向到a页面
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'),
children: [
path: '/about/a',
component: () => import(/* webpackChunkName: "a" */ '../views/About/a.vue'),
]
},
{
path: '/404',
component: () => import(/* webpackChunkName: "404" */ '../views/404.vue'),
},
{
path: '/',
recirect: '/404'
}
]
const router = new Router({
mode: 'history',
bae: process.env.BASE_URL,
routes
})
export default router;
- 路由钩子函数
let Vue = null;
function install(_vue){
Vue = _vue;
Vue.mixin({
beforeCreate(){
if (this.$options.router) {
this.$router = this.$options.router;
} else if (this.$parent) {
this.$router = this.$parent.router;
}
Vue.component('router-link', link);
Vue.component('router-view', {
render(h){
return h(this.$router.routerMap[this.$router._route]);
}
})
}
})
}
class VueRouter {
constructor(options){
let { routes } = options;
this.routerMap = {}
routes.forEach((item) => {
this.routerMap[item.path] = item.component;
})
Vue.util.defineReactive(this, "_route", "/");
this._route = location.hash.slice(1);
window.onhashchange = ()=>{
this._route = location.hash.slice(1);
}
}
}
VueRouter.install = install;
export default VueRouter;
watch $route 只要路径或者参数发生改变就会触发watch方法
# vuex
let obj= {
created(){
console.log('aa');
}
}
Vue.mixin(obj); // 全局混入obj
// 混入时 若钩子函数重复了,则混入的钩子函数先执行,组件自己的钩子后执行(以组件内部数据和钩子函数优先原则)
// 局部混入
export default {
mixins: [mixins]
}
let Vue = null;
function install(_Vue){
Vue = _Vue;
Vue.mixin({
beforeCreate(){
if (this.$options.store) {
// 根实例
this.$store = this.$options.store;
} else if (this.$parent) {
// 后代组件
this.$store = this.$parent.$store;
}
}
})
}
class Store {
constructor(options){
let vm = new Vue({
data(){
return state: options.state
}
})
this.state = vm.state;
}
commit(mutations, option){
}
}
export default {
install,
Store
}