VUE3记录

使用 setup

setup 选项应该是一个接受 props 和 context 的函数。
此外,我们从 setup 返回的所有内容都将暴露给组件的其余部分 (计算属性、方法、生命周期钩子等等) 以及组件的模板。
setup 选项应该为一个函数
setup 选项函数接受两个参数: props 和 context
setup 选项函数需要返回要暴露给组件的内容

props:
(props 是响应式的,你不能使用 ES6 解构 如果不用toRefs将失去响应式 即子组件不能更新数据)
import { toRefs } from 'vue'

setup(props) {
    const { title } = toRefs(props)

    console.log(title.value)
}

context:
context 上下文是一个普通的 JavaScript 对象,它暴露三个组件的 property:
(它不是响应式的,这意味着你可以安全地对 context 使用 ES6 解构)
export default {
  setup(props, context) {
    // Attribute (非响应式对象)
    console.log(context.attrs)

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

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

setup 函数的返回值
1. setup 函数的返回值 —— 对象
如果 setup 返回一个对象,则可以在组件的模板中像传递给 setup 的 props property 一样访问该对象的 property:
<template>
  <!-- 模板中使用会被自动解开,所以不需要 .value  -->
  <div>{{ readersNumber }} {{ book.title }}</div>
</template>

<script>
  import { ref, reactive } from 'vue'

  export default {
    setup() {
      const readersNumber = ref(0)
      const book = reactive({ title: 'Vue 3 Guide' })

      // expose to template
      return {
        readersNumber,
        book
      }
    }
  }
</script>
2、setup 函数内部一般不使用 this


响应式系统 API
1. reactive
reactive() 接收一个普通对象然后返回该普通对象的响应式代理。等同于 2.x 的 Vue.observable()
<template>
  <div id="app">{ state.count }</div>
</template>
<script>
import { reactive } from 'vue'
export default {
  setup() {
    // state 现在是一个响应式的状态
    const state = reactive({
      count: 0,
    })
    return {
        state
        //...toRefs(state) 可以直接访问count 
    } 
  }
}
</script>
2. ref
接受一个参数值并返回一个响应式且可改变的 ref 对象,ref 对象拥有一个指向内部值的单一属性 
.value
(对于基本数据类型,ref是自己的实现方式且性能优于reactive,而对于对象类型,ref仍然是通过reactive包装实现的)
<template>
  <div>{{ count }}</div>
</template>

<script>
  export default {
    setup() {
      return {
        count: ref(0),
//如果想用ts的类型判断 得用 let count: Ref<number> = ref(1012)  
//而不是 let count: <number> = ref(1012)
      }
    },
  }
</script>
3. computed
3.1 传入一个 getter 函数,返回一个默认不可手动修改的 ref 对象

const count = ref(1)
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value) // 2
plusOne.value++ // 错误!

3.2 传入一个拥有 get 和 set 函数的对象,创建一个可手动修改的计算状态。
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

4. readonly
传入一个对象(响应式或普通)或 ref,返回一个原始对象的只读代理。一个只读的代理是“深层的”,对象内部任何嵌套的属性也都是只读的。

const original = reactive({ count: 0 })
const copy = readonly(original)
watchEffect(() => {
  // 依赖追踪
  console.log(copy.count)
})
// original 上的修改会触发 copy 上的侦听
original.count++
// 无法修改 copy 并会被警告
copy.count++ // warning!

5. watchEffect
立即执行传入的一个函数,并响应式追踪其依赖,并在其依赖变更时重新运行该函数。
const count = ref(0)

watchEffect(() => console.log(count.value))
// -> 打印出 0

setTimeout(() => {
  count.value++
  // -> 打印出 1
}, 100)
//停止监听
const stop = watchEffect(() => {
  /* ... */
})

// 之后
stop()

6.watch
import { reactive, ref, watch } from "vue";
 
const state = reactive({
  count: 0,
});
 
//侦听时返回值得getter函数
watch(
  () => state.count,
  (count, prevCount) => {
    // 1 0
    console.log(count, prevCount);
  }
);
state.count++;
 
const count = ref(0);
//直接侦听ref
watch(count, (count, prevCount) => {
  // 2 0
  console.log(count, prevCount, "watch");
},{ deep: true });
count.value = 2;
区别:
watchEffect不需要手动传入依赖
每次初始化时watchEffect都会执行一次回调函数来自动获取依赖
watchEffect无法获取到原值,只能得到变化后的值

生命周期钩子
onBeforeMount
onMounted
onBeforeUpdate
onUpdated
onBeforeUnmount
onUnmounted
onErrorCaptured
onRenderTracked
onRenderTriggered

import { onBeforeMount, onMounted } from "vue";
export default {
  setup() {
    console.log("----setup----");
    onBeforeMount(() => {
      // beforeMount代码执行
    });
    onMounted(() => {
      // mounted代码执行
    });
  },
}
举例子
<template>
  <div>{{ state.count }} * 2 = {{ double }}</div>
  <div>{{ num }}</div>
  <div @click="add">Add</div>
</template>
<script>
import { reactive, computed, ref } from "vue";
export default {
  name: "Button",
  setup() {
    const state = reactive({
      count: 1,
    });
    const num = ref(2);
    function add() {
      state.count++;
      num.value += 10;
    }
    const double = computed(() => state.count * 2);
    return {
      state,
      double,
      num,
      add,
    };
  },
};
</script>
应用

export default {
  setup() {
    const { networkState } = useNetworkState();
    const { user } = userDeatil();
    const { list } = tableData();
    return {
      networkState,
      user,
      list,
    };
  },
};
function useNetworkState() {}
function userDeatil() {}
function tableData() {}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值