vue3

1,154 阅读3分钟

Vue3

options API 和 composition API的组合框架

setup

vue2的computed,watch等配置选项在vue3中封装成hook,需要使用就调用hook一般配置在setup配置项,setup是一个新的配置项(一个函数) 调用时机 等同于beaforcreat setup里this undifend

使用 setup 函数时,它将接收两个参数:

  1. props
  2. context 一,setup 函数中的第一个参数是 props。正如在一个标准组件中所期望的那样,setup 函数中的 props 是响应式的,当传入新的 prop 时,它将被更新。 WARNING

但是,因为 props 是响应式的,你不能使用 ES6 解构*,它会消除 prop 的响应性。

二,传递给 setup 函数的第二个参数是 contextcontext 是一个普通的 JavaScript 对象,它暴露组件的三个 property:

// MyBook.vue

export default {
  setup(props, context) {
    // Attribute (非响应式对象)
    console.log(context.attrs)

    // 插槽 (非响应式对象)
    console.log(context.slots)

    // 触发事件 (方法)
    console.log(context.emit)
  }
}

context 是一个普通的 JavaScript 对象,也就是说,它不是响应式的,这意味着你可以安全地对 context 使用 ES6 解构。

// MyBook.vue
export default {
  setup(props, { attrs, slots, emit }) {
    ...
  }
}

attrs 和 slots 是有状态的对象,它们总是会随组件本身的更新而更新。这意味着你应该避免对它们进行解构,并始终以 attrs.x 或 slots.x 的方式引用 property。请注意,与 props 不同,attrs 和 slots 是响应式的。如果你打算根据 attrs 或 slots 更改应用副作用,那么应该在 onUpdated 生命周期钩子中执行此操作。

reactivity API

reactive 返回对象的响应式副本(proxy代理)
ref 返回ref对象 ( Object.definePropety()) 值需要.value

简单数据类型用ref 引用类型用reactive 如果let obj = ref({uname:'zs'})传入了引用类型,obj.value也会包装成proxy代理对象

isRef

判断是不是ref对象

unref

语法糖hook let obj2 = unref(obj) 如果是ref对象返回对象.value 否则返回原对象

toRef

可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接

const state = reactive({
 foo: 1,
 bar: 2
})

const fooRef = toRef(state, 'foo')

fooRef.value++
console.log(state.foo) // 2

state.foo++
console.log(fooRef.value) // 3

toRefs

将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref。 reactive对象使用toRefs处理返回一个普通对象,对象每一个属性就是reactive对象属性,值是ref对象 在setup返回对象中解构 在模板中可以直接写属性不需写返回对象.属性

reactive响应式对象在setup返回对象中解构会失去响应式

<script>
import { ref, reactive } from "vue";
export default {
  name: "HelloWorld",
  props: ["msg"], //声明接收
  emits: ["zevent"],
  setup(props, context) {
    console.log(props); //Proxy {msg: "nihao"}
    console.log(context); //对象
    let uname = ref("zs");
    let obj = reactive({
      id: 1,
      value: "dnm",
    });
    console.log(uname);//RefImpl {_shallow: false, __v_isRef: true, _rawValue: "zs", _value: "zs"}
    console.log(obj); //Proxy {id: 1, value: "dnm"}
    function change() {
      uname.value = "ww";
      obj.value = "wsnd";
    }
    function emitEvent() {
      context.emit("zevent", 666);
    }
    return {
      uname,
      obj,
      change,
      emitEvent,
    };
  },
};
</script>

computed

接受一个 getter 函数,并根据 getter 的返回值返回一个不可变的响应式 ref 对象。

const count = ref(1)
const plusOne = computed(() => count.value + 1)

console.log(plusOne.value) // 2

plusOne.value++ // 错误

或者,接受一个具有 get 和 set 函数的对象,用来创建可写的 ref 对象。

const count = ref(1)
const plusOne = computed({
  get: () => count.value + 1,
  set: val => {
    count.value = val - 1
  }
})

plusOne.value = 1
console.log(count.value) // 0

readonly

接受一个对象 (响应式或纯对象) 或 ref 并返回原始对象的只读代理。只读代理是深层的:任何被访问的嵌套 property 也是只读的。

toRaw

返回 reactive 或 readonly 代理的原始对象。这是一个“逃生舱”,可用于临时读取数据而无需承担代理访问/跟踪的开销,也可用于写入数据而避免触发更改。建议保留对原始对象的持久引用。请谨慎使用。// 将一个响应式对象处理成普通对象,适用场景不多,但是返回的对象===响应式对象

const foo = {}
const reactiveFoo = reactive(foo)
console.log(toRaw(reactiveFoo) === foo) // true

。。。