全局混入 mixin
全局混入将会影响每一个组件
// main.js
const app = createApp(App);
app.mixin({
data() {
return {
globalMsg: '这是全局混入的消息'
}
}
})
复制代码
extend
- 类似mixins
多个组件之间依赖一个相同的方法 如下:
import CommonComponent from './common/CommonComponent.vue';
export default {
extends: CommonComponent // 之后即可使用CommonComponent组件中的属性(感觉和 mixin 一模一样)
}
复制代码
setup
注意:
- setup里面没有绑定this
- 如果在 CompositionApi(setup) 内定义的属性与 OptionApi 内定义的属性冲突了 优先采用 CompositionApi 内定义的属性 ??(实际操作起作用的是optionApi)
setup(props, ctx) {
// ctx 常用属性
const {
slots, // 插槽
attrs, // 挂载在元素上面的非 props 的 attribute
emit // 事件
} = ctx;
}
复制代码
响应式数据
import { ... } from 'vue';
复制代码
– ref
– reactive
– isProxy
– isRef
判断变量是否由 ref 创建的, boolean
– readonly
判断变量是否是由 reactive | readonly 创建的, boolean
– isReactive
判断变量是否由 reactive 创建的, boolean
(如果该变量是readonly包裹了reactive, 仍然返回true)
– toRaw
返回reactive 或 readonly 代理的原始对象(谨慎使用)
– toRefs(常用)
传入解构的的对象必须是reactive对象
解构了某一响应式数据后, 使得解构出来的数据依然是响应式数据
(将reactive对象的所有属性转成ref, 建立连接)
const {
name,
age
} = toRefs(reactive({name: 'cqc', age: 24}))
// 之后通过 xxx.value = newValue 来跟新值
复制代码
– toRef
和toRefs功能一样, 但是只转换其中的某一个属性
const info = reactive({
age: 25
})
const age = toRef(info, age)
复制代码
– shallowReactive
创建一个响应式代理数据(浅层, 只监听第一层)
– shallowRef
创建一个响应式代理数据(浅层, 只监听第一层), 之后如果在某一次想要刷新界面, 可以使用 triggerRef(),
triggerRef 接受一个ref类型数据 每调用一次可以刷新一次界面
– triggerRef
为 shallowRef 刷新视图, 执行与 shallowRef 关联的所有副作用(依赖)
– shallowReadonly
创建一个响应式代理数据, 他的第一层是只读的(深层依然可读写)
– unref
对ref类型的变量进行解包
获取一个ref引用中的value, 如果参数是一个ref则返回内部值, 否则返回本身
val = isRef(val) ? val.value : val;
复制代码
import {
ref, // 传入基本变量类型
reactive, // 传入引用变量类型
readonly
} from 'vue';
复制代码
ref
获取基本类型的响应式数据
在模板中使用ref, vue会自动进行解包(自动添加ref.value(浅层解包))
// 浅层解包
const counter = ref(100);
const info = {
counter
} // 除非用reactive包裹info, 否则就是浅层解包
复制代码
此时在template内
<!-- 需要完整写下来(不会自动解包) -->
{{info.counter.value}}
复制代码
reactive
获取引用类型的响应式数据
readonly
获取只读类型的响应式数据(在某些地方使用数据但是不希望修改数据)
这是一个new Proxy, 劫持了set方法
customRef
使用场景比较少, 一般用于组件库 , 创建一个自定义的ref(可自由控制 track、trigger)
需要配合工厂函数进行使用,该函数接受两个参数(track, trigger)
track: 追踪依赖 在get时候调用一下track();
trigger: 更新视图 在set的时候调用一下trigger();
- customRef 函数返回一个带有set、get 方法的对象
- example: 这里用一个防抖例子
const useDebounce(value, delay) { let timer = null; return customRef((track, trigger) => { return { get() { track(); // 收集依赖 return value }, set(newValue) { value = newValue; timer && clearTimeout(timer); timer = setTimeout(() => { trigger(); // 更新视图 }, delay) return true; } } }) } setup() { return { text: useDebounce('这里做了延迟500毫秒操作', 500) } } 复制代码
computed
computed函数接收一个参数 该参数可以有两种形式
1.一个带有get、set函数的对象
2.直接一个get函数
example:
const state = ref('cqc');
const computedTest = computed(() => state.value + 'computed');
const computedTest2 = computed({
get() {
return state.value + 'computed'
},
set(newValue) {
state.value = newValue;
return true;
}
})
复制代码
侦听数据
Vue3 提供了两种侦听api
API | 说明 |
---|---|
watch | 侦听数据变化后 执行一些操作 |
watchEffect | 刚开始时候立即执行一次, 收集里面的所有可响应式对象数据, 一旦这些数据发生改变 执行 |
watch实例
const name = ref('cqc');
const state = reactive({
name: 'cqc',
fav: 'play-game',
data: {
io: '/td'
}
})
// watch区分侦听两种响应式数据
// 1. 被侦听的原始值类型是普通类型的
watch(name, (newValue, oldValue) => {
console.log(newValue, oldValue);
})
// 2. 被侦听的原始值类型是引用类型的
watch(() => ({...state}), (newValue, oldValue) => {
// 如果state里还有引用数据属性, 那么newValue, oldValue内的这个属性仍然指向它们本身, 也就是说这些引用数据的newValue和oldValue相等
console.log(newValue, oldValue);
})
//-------------
// 侦听单个属性
watch(() => state.name, (newValue, oldValue) => {
console.log(newValue, oldValue);
})
// 侦听多个数据源
watch(
[name, () => ({ ...state })],
(newValue, oldVAlue) => {
// 此时的newValue, oldValue 也将是一个数组 他们的下标与传入的数据源下标相对应
[newName, newState] = newValue;
[oldName, oldState] = oldValue;
}
)
// watch配置项 第三个参数
watch(
() => ({ ...state }),
(newValue, oldValue) => {},
{
deep: false, // 是否深度监听
immediate: false // 是否立即执行(初始化的时候马上执行一次)
}
)
复制代码
watchEffect实例
和watch区别
无法拿到数据更新前的值, watch 可以
watch 可以配置immediate是否马上执行 watchEffect一定会在初始化的时候就执行一次(采集副作用)
const state = reactive({
name: 'cqc'
})
const watchEffectStop = watchEffect(
// watchEffect 第一个参数
(onInvalidate) => {
// onInvalidate 会在副作用即将执行, 或则侦听器被停止时候执行里面的回调函数
onInvalidate(() => {
// 可以在这里做一些清理的工作
})
// 默认开始watchEffect会执行一次(收集里面的响应式数据, 一旦收集到的数据开始发生变化 执行)
console.log('watchEffect', state.name);
},
// watchEffect 第二个参数
{
flush: 'pre'
/*
flush: 执行作用时机 可选值 pre post sync
- pre: dom更新前执行 默认值
- post dom更新后执行
- sync 强制同步执行(不建议使用)
*/
}
)
if(someFlag) {
// 手动停止watchEffect的侦听
watchEffectStop();
}
复制代码
获取 组件|元素 实例
相当于vue2.x 中 this.$refs.xxx
<Component-A ref="ComponentA" />
复制代码
setup() {
// 在组件被更新后 ComponentA.value 会被vue自动赋值
const ComponentA = ref(null);
return {
ComponentA
}
}
复制代码