Vue3学习第一天 | 青训营笔记

21 阅读2分钟

这是我参与「第五届青训营 」笔记创作活动的第6天

  • ref 系列
    • ref 和 reactive 的区别
      • ref 支持所有类型,reactive 只支持引用类型,如 Array Object Map Set 等等
      • ref 取值赋值都需要在变量名后面加上 .value , reactive 不需要
      • reactive 是 proxy 包装的,不可以直接赋值,否则会破坏响应型对象的
        • 解决方案:数组可以通过push
          let list = reactive<string[]>([])
          let res = ['a','b','c']
          list.push(...res)
          
        • 解决方案:也可以直接将 list 包装成 Object
  • to 系列
    • toRef ---> 这样一来的话,修改 like 的时候,就会同步修改 age
      const man = reactive({name: 'abc', age: 23})
      const like = toRef(man, 'age')
      
      • 应用场景:比如说你拿到一个对象,但是只用其中某个属性,就可以这样直接提出来
    • toRefs
      • 应用场景:解构赋值
    • toRaw ---> 将响应式代理对象还原成普通对象
  • 特殊情况
    • computed 的
  • watch
    • watch 可以监听响应式数据
      watch(msg, (newVal, oldVal) => {
          //......
      })
      watch([msg1, msg2], (newVal, oldVal) => {
          //......这里的 newVal 和 oldVal 是数组
      })
      
    • 监听对象的某一个属性,需要调用回调函数,比如 () => msg.content
      watch(() => msg.content, (newVal, oldVal) => {
          //......
      })
      
    • 相关配置
      • 深度监听 deep
        watch(msg, (newVal, oldVal) => {
            //......
        }, {deep: true})
        
        • 对于 ref 开启深度监听 newVal 和 oldVal 长得一样
        • 对于 reactive 不需要开启深度监听
      • 立即执行 immediate ——立即执行一次
      • flush
        • flush = 'pre'
        • flush = 'sync'
        • flush = 'post'
  • 父子组件通信
    • 子组件接受父组件
      • 父向子传输
        <template>
            <A :title='name' :arr='list'></A>
        </template>
        
        <script setup lang='ts'>
            import A from './components/A.vue'
            let name = 'vychod';
            let list = [1,2,3];
        </script>
        
      • setup 中声明
        // typescript vue3
        // ts 特有定义默认设置值 withDefaults(a,b) 把 a 的默认值设置为 b
        withDefaults(defineProps<{
            // 设置数据类型
            title: String,
            arr: number[]
        }>(), {
            // 设置默认值
            title: () => 'blog',
            arr: () => [666]
        })
        

        ↑ 这个地方该怎么在ts中访问到这个 titlearr 呢,是不是可以直接使用呀 → 不可以。也必须要使用 props.title,同下面 ↓

        // javascript vue2
        const props = defineProps({
            title: {
                type: String,
                default: '默认值'
            },
            arr: {
                type: Array,
                default: []
            },
        });
        console.log(props.title); 
        // 在 template 中使用的时候可以直接用 title,但是在 setup 中使用的时候需要使用 props.title
        
      • template 直接通过 title arr 这样子的命名使用即可
    • 子组件向父组件通信
      • 向父组件直接发送信号
      // 子组件中
      <template>
          <button @click='send'>给父组件传值</button>
      </template>
      <script setup lang='ts'>
          const emit = defineEmits(['on-click'])
          // ts 的另一种写法
          // const emit = defineEmits<{
          //      (e: "on-click", name: String, age: Number):void,
          //      (e: "on-click2", name: String, ):void,
          //      (e: "on-click3", name: String, ):void
          // }>()
          const send = () => {
              emit('on-click', 'vychod', 24)
          }
      </script>
      
      // 父组件中
      <template>
          <A @on-click='getInfo'></A>
      </template>
      <script setup lang='ts'>
          import A from './components/A.vue'
          const getInfo = (name:String, age:Number) => {
              console.log(name, age);
          }
      </script>
      
      • 向父组件暴露属性
      // 父组件中
      <template>
        <A ref="Aref"></A>
      </template>
      <script setup lang='ts'>
        import { ref, reactive, onMounted } from 'vue' 
        import A from './components/A.vue'
      
        const Aref = ref<InstanceType<typeof A>>()
        onMounted(()=>{
          console.log(Aref.value?.name)
        })
      </script>
      
      // 子组件中
      <template>
        这是A组件
      </template>
      <script setup lang='ts'>
        defineExpose({
          name: 'vychod',
          open: () => {
            console.log(123)
          }
        })
      </script>
      

      感觉就像是 前者是主动的,我想要让父组件知道,后者是被动的,我把属性广播出来了,你爱看不看