Vue 2 OptionsAPI

目录

一. 计算属性

1. 特点

2. 写法

1. 函数式写法

2. 对象式写法

 二. 侦听器

1. 特点

2. 写法

1. 函数式写法

2. 对象式写法

3. 对属性的侦听

4. this.$watch

三. 虚拟DOM

1. 作用

四. 组件

1. 全局组件

2. 局部组件

五. 组件间的通信

1. 父传子(自定义属性)

2. 子传父(自定义事件)

六. 动态绑定类名

七. 插槽

1. 默认插槽

2. 具名插槽

3. 动态插槽名

4. v-slot: 可以缩写成 #

 5. 作用域插槽

八. Provide 和 Inject(非父子组件间的通信  祖先组件之间)

九. 事件总线(非父子组件间的通信 任意组件之间)

十. 生命周期

十一. ref 引用

1. 引用元素

2. 引用组件

3. 获取当前组件的父组件 / 根组件

十二. 动态组件

1. 定义动态组件

2. 动态组件传递数据

3. 动态组件的缓存

4. include 和 exclude 的值

5. 缓存的动态组件的生命周期

十三. 异步导入文件, 利于SSR 优化,首屏加载优化

1. 同步导入js 文件

2. 异步导入js 文件

3. 异步导入vue 文件

十四. 组件的 v-model

1. 默认绑定 modelValue

2. 自定义的绑定

附:


一. 计算属性

1. 特点

  1. 名称自定义

  2. 任何包含响应式数据的复杂逻辑,都应该使用计算属性

  3. 计算属性是有缓存的

  4. 计算属性和methods 的区别:

  • 计算属性会基于它的依赖关系进行缓存,是有缓存的

  • 在数据不发生变化时,计算属性是不需要重新计算的

  • 依赖的数据发生变化,计算属性会自动重新进行计算

  • 在多次调用时,methods 会多次执行,计算属性只执行一次

2. 写法

1. 函数式写法

computed: {
    fullname() {
        return this.firstName + " " + this.lastName;
    }
}

2. 对象式写法

computed: {
    fullName: {
        get: function() {
            return this.firstName + " " + this.lastName;
        },
        set: function(value) {
            const names = value.split(" ");
            this.firstName = names[0];
            this.lastName = names[1];
        }
    }
}

 二. 侦听器

1. 特点

名称的定义是所依赖的数据的名称

2. 写法

1. 函数式写法

watch: {
    message(newValue, oldValue) {
        console.log(newValue, oldValue)
        // 如果侦听的是一个对象时,这个对象是通过proxy代理侦听,侦听后拿到的是一个proxy对象
        // 可以通过下面的方法拿到原始对象
        console.log(Vue.toRaw(newValue))
        // console.log({ ...newValue })
    }
}

2. 对象式写法

watch: {
    info: {
        handler(newValue, oldValue) {
            console.log(newValue, oldValue)
        },
        deep: true,
        immediate: true
    }
}

3. 对属性的侦听

watch: {
    'info.name': function(newValue, oldValue) {
        console.log(newValue, oldValue)
    }
}

4. this.$watch

created() {
    this.$watch( "message", 
    (newValue, oldValue) => {
        console.log(newValue, oldValue)
    }, {deep: true, immediate: true})
}

三. 虚拟DOM

1. 作用

多个VNode 节点 -> 虚拟DOM -> 真实DOM

作用一: 跨平台

作用二: diff 算法

四. 组件

1. 全局组件

import Vue from 'vue';
import comCpns from '@/components/comCpns';

Vue.component('com-cpns', comCpns);
Vue.component(comCpns.name, comCpns);

<com-cpns></com-cpns>
<product-item></product-item>
<ProductItem></ProductItem>

app.component("ProductItem",{})

2. 局部组件

<ProductItem></ProductItem>
<product-item></product-item>

components: {
    ProductItem
}

五. 组件间的通信

1. 父传子(自定义属性)

// 父组件
<show-info name="why" :age="18"></show-info>
import ShowInfo from './show-info.vue';
components: {
    ShowInfo
}

// 子组件
// 1. 数组语法
props: ["name", "age"];

// 2. 对象语法 (推荐)
props: {
    name: {
        type: String,
        required: true
    },
    age: {
        type: Number,
        default: 0
    },
    // 对象类型的写法
    friend: {
        type: Object, 
        default: () => {{ name:"kobe" }}    
        //default() {
        //    return { name: "kobe"}
        //}
    },
    // 数组类型的写法
    hobbies: {
        type: Array,
        default: () => ["a", "b", "c"]
    }
}

2. 子传父(自定义事件)

// 父组件
<add-counter @addClick="addBtnClick"></add-counter>

addBtnClick(count) {
    this.counter += count
}


// 子组件
<button @click="btnClick(1)"></button>

// 注册自定义事件
emits: ["addClick"]

btnClick(count) {
    // 发送自定义事件
    // (自定义事件的名称, 传递的参数)
    this.$emit("addClick", count)
}

六. 动态绑定类名

<div v-for="(item, index) in arrs" :key="item">
    <div 
        :class="{ active: index === currentIndex }"
        @click="itemClick(index)"
    >{{ item }}</div>
</div>

data() {
    return {
        currentIndex: 0,
    }
},
methods: {
    itemClick(index) {
        this.currentIndex = index;
    }
}

七. 插槽

1. 默认插槽

// 父组件
<show-message>
    <button>按钮</button>
</show-message>

// 子组件
<div class="content">
    <slot>
        <!-- 没有传入任何内容时,显示插槽的默认内容 -->
        <div>插槽的默认内容</div>
    </slot>
</div>

2. 具名插槽

// 父组件
<show-message>
    <template v-slot:left>
        <button>返回</button>
    </template>

    <template v-slot:center>
        <button>内容</button>
    </template>

    <template v-slot:right>
        <button>我的</button>
    </template>

    <button>默认插槽</button>
</show-message>


// 子组件
<div class="content">
    <div class="left">
        <slot name="left"></slot>
    </div>

    <div class="center">
        <slot name="center"></slot>
    </div>

    <div class="right">
        <slot name="right"></slot>
    </div>

    <div class="other">
        <slot name="default"></slot>
    </div>
</div>

3. 动态插槽名

// 可以通过修改name 的值来实现插槽绑定名字的变化
<template v-slot:[name]>
    <button>按钮</button>
</template>

4. v-slot: 可以缩写成 #

// v-slot:  可以缩写成  #
<template #left>
    <button>返回</button>
</template>

 5. 作用域插槽

// 父组件
<show-message>
    // <template v-slot="slotProps">
    <template v-slot:default="slotProps">
        <button>{{ slotProps.item }}</button>
    </template>
</show-message>

// 子组件
<div class="content">
    <slot :item="item" abc="cba"></slot>
</div>

八. Provide 和 Inject(非父子组件间的通信  祖先组件之间)

  • 将props 沿着组件链逐级传递下去
  • 父组件不需要知道哪些子组件使用它roovide 的property
  • 子组件不需要知道inject 的property 来自哪里

  •  provide 也有对象的写法,但是不能通过this 绑定data 中的数据
  • 函数写法可以通过this 绑定data 中的数据
  • 箭头函数的this 指向provide 的this
  • computed 函数包裹 意思是将this.name 成为响应式数据
  • 即: this.name 发生改变 inject 拿到的name 值也会发生改变
// provide 
export default {
    // provide 也有对象的写法,但是不能通过this 绑定data 中的数据
    // 函数写法可以通过this 绑定data 中的数据
    // 箭头函数的this 指向provide 的this
    // computed 函数包裹 意思是将this.name 成为响应式数据
    // 即: this.name 发生改变 inject 拿到的name 值也会发生改变
    provide() {
        return {
            name: computed(() => {
                return this.name
            }),
            age: 18
        }
    }
}

// inject
<div>
    {{ name.value }} - {{ age }}
</div>
export default {
    inject: ["name", "age"]
}

九. 事件总线(非父子组件间的通信 任意组件之间)

// 发送
eventBus.emit("whyEvent", why, 18);

// 接收
eventBus.on("whyEvent", (name, age) => {
    console.log(name, age);
})

// 移除监听
eventBus.off("whyEvent", this.offWhyEventHandler);

十. 生命周期

beforeCreate 

created -> 1. 发送网络请求  2. 事件监听  3. this.$watch()

    -> template 模板编译

beforeMount 

    -> 挂载到虚拟DOM -> 真实DOM -> 界面元素

mounted -> 元素已挂载、获取DOM、使用DOM

    -> 数据更新

beforeUpdate

    -> 根据最新数据生成新的VNode -> 新的虚拟DOM -> 新的真实DOM

updated

beforeUnmount

    -> 将之前挂载在虚拟DOM 中的VNOde 从虚拟DOM 中移除

unmounted -> 取消事件监听、回收操作

十一. ref 引用

1. 引用元素

<div ref="divEl"></div>

this.$refs.divEl

2. 引用组件

<banner ref="banner"></banner>

// 获取子组件
this.$refs.banner

// 调用子组件的方法
this.$refs.banner.bannerClick();

// 获取子组件的元素
this.$refs.banner.$el (子组件最好只有一个根元素)

3. 获取当前组件的父组件 / 根组件

this.$parent

this.$root

十二. 动态组件

1. 定义动态组件

<component :is="currentTab"></component>

2. 动态组件传递数据

<component  name="why"
            :age="18"
            @homeClick="homeCli"
            :is="currentTab">
</component>

3. 动态组件的缓存

<keep-alive include="home, about"
            exclude="category">
    <component :is="currentTab">></component>
</keep-alive>

4. include 和 exclude 的值

string | RegExp | Array

"home, ablue"   |   正则   |   ['home', ' ablue']

5. 缓存的动态组件的生命周期

activated   ->   活跃状态

deactivated   ->   停用状态

十三. 异步导入文件, 利于SSR 优化,首屏加载优化

1. 同步导入js 文件

import math from './math'

2. 异步导入js 文件

import("./math").then(res => {
    res.sum(20, 30)
})

3. 异步导入vue 文件

import { defineAsyncComponent } from 'vue'

const AsyncCategory = defineAsyncComponent(
    () => import("./category.vue")
)

components: { category: AsyncComponent };

十四. 组件的 v-model

1. 默认绑定 modelValue

// 父组件
<counter v-model="appCounter"></counter>

    // v-model 的本质
    <counter v-bind:modelValue="appCounter"
             v-on:update:modelValue="appCounter=$event">
    </counter>

// 子组件
props: {
    modelValue: {
        type: Number,
        default: 0
    }
},
emits: ["update:modelValue"],

this.$emit("update:modelValue", 10)

2. 自定义的绑定

// counter
<counter v-model:counter="appCounter"></counter>

props: ["counter"],
emits: ["update:counter"]

this.$emit("update:counter", 10)

附:

  • npm init vue @latest    (vite 打包)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值