| vue3使用Composition API,相比于vue2的Options API而言,我们可以按需引入需要使用到的api,而不必引入所有api,从而提高了项目打包构建的速度,减少了项目打包后的体积 1. setupsetup函数是composotion api的入口函数,我们的变量,方法,函数等都是在该函数里定义的 <template>
  <div id="app">
      <p>{{count}}</p>
      <button @click="add">+</button>
  </div>
</template>
<script>
import {ref} from 'vue'    //  引入ref函数
export default {
  name: 'App',
  setup() {
      let count = ref(0)    //  用ref包装一个响应式变量
      const add = () => {
          count.value ++    //  被ref包装的变量取值使用.value
      }
      return {count, add}   //  将count和add返回出去,供template使用
  }
}
</script>
 2. reactivereactive方法是用来创建一个响应式的数据对象,该api很好的解决了vue2通过defineProperty实现数据响应式的缺陷(无法实现新增属性的响应式,无法实现删除属性的响应式,无法实现懒监听...) <template>
  <div id="app">
    {{ data.count }}
  </div>
</template>
<script>
import {reactive} from 'vue'    //  从vue3中引入reactive 
export default {
  name: 'App',
  setup() {
      const data = reactive({count: 0})    //  创建响应式的数据对象
      return {data}    //  将响应式数据对象return出去,供template使用
  }
}
</script>
 3. ref?ref底层通过reactive包装了一个对象,然后将值传递给该对象的value属性,可以将ref(prop)理解为reactive({value: prop}),所以访问ref所包装的对象时需要加上.value <script>
import {ref, reactive} from 'vue'
export default {
  name: 'App',
  setup() {
      const data = {count: 0}
      const data1 = ref(obj)
      const data2 = reactive(obj)
      let data3 = ref(0)
  }
}
</script>
 当我们的响应式数据是基本类型或者单值对象时可以使用ref,而为引用类型时使用reactive 4. toRef?toRef是将某个对象中的某个值转化为响应式数据,接受两个参数,第一个参数为obj对象,第二个参数为对象的属性名 <script>
import {toRef} from 'vue'
export default {
    setup() {
        const obj = {count: 0}
        const data = toRef(obj, 'count')
        return {data}
    }
}
</script>
 ref跟toRef的区别: 1. ref是对传入数据的拷贝,toRef是对传入数据的引用 2. ref值改变会更新视图,toRef值改变不会更新视图? 5. toRefstoRefs的作用就是将传入对象所有的属性的值都转化为响应式数据对象,该函数只有一个参数,就是obj对象 <script>
import {toRefs} from 'vue'
export default {
    setup() {
        const obj = {
            propA: 'vue3',
            propB: 'toRefs'
        }
        const data = toRefs(obj)
        console.log(data)
        return {...toRefs(obj)}
    }
}
</script>
 6. shallowReactive浅层次的reactive,reactive为深层次的,会为对象的每一层属性都使用proxy添加响应式,而shallowReactive只对对象的第一层属性添加响应式,可以进行性能优化 <script>
import {reactive, shallowReactive} from 'vue'
export default {
    setup() {
        const obj1 = {
            propA: 0,
            propB: {
                propC: 1
            }
        }
        const obj2 = {
            propA: 0,
            propB: {
                propC: 1
            }
        }
        const data1 = reactive(obj1)           // obj1.propB.propC为响应式
        const data2 = shallowReactive(obj2)    // obj2.propB.propC不是响应式
    }
}
</script>
 7. shallowRef浅层次的ref,可以类比shallowReactive,这里不做多解释 8. toRawtoRaw用于获取ref或reactive对象的原始数据 <template>
    <p>{{ data.propA }}</p>
    <p>{{ data.propB }}</p>
    <button @click="change">change</button>
</template>
<script>
import {reactive,toRaw} from 'vue'
export default {
    setup() {
        const obj = {
            propA: 'vue3',
            propB: 0
        }
        const data = reactive(obj)
        const rawData = toRaw(data)
        const change = () => {
            data.propB ++ 
            console.log(obj)     //  打印原始数据obj
            console.log(data)    //  打印 reactive对象
        }
        console.log(obj === rwaData)    //  true
        return {data, change}
    }
}
</script>
 9. markRawmarkRaw可以将原始数据标记为非响应式数据,即便使用ref或者reactive包装后仍然无法实现响应式,接收一个参数,即原始数据,并返回被标记后的数据 <template>
    <p>{{ data.propA }}</p>
    <p>{{ data.propB }}</p>
    <button @click="change">change</button>
</template>
<script>
import {reactive, markRaw} from 'vue'
export default {
    setup() {
        const obj = {
            propA: 'vue3',
            propB: 0
        }
        // 通过markRaw标记原始数据obj, 使其数据更新不再被追踪
        const rawData = markRaw(obj)
        // 试图用reactive包装raw, 使其变成响应式数据
        const data = reactive(rawData ) 
        const change = () => {
            data.propB ++     // 值被修改但视图不会更新
        }
        return {data, change}
    }
}
</script>
 10. provide&inject与vue2中的provide&inject的作用是一样的,在vue3中需要手动引入 provide:向子组件以及子孙组件传递数据,接收两个参数,第一个参数是key,即数据名,第二个参数为value,即数据值 inject:接收父组件或祖先组件传递过来的数据,接收一个参数key,父组件或祖先组件传递的数据名 // C是B的子组件,B是A的子组件
// A.vue
<script>
import {provide} from 'vue'
export default {
    setup() {
        const data = {
            prop: 'vue3'
        }
        // 向子组件以及子孙组件传递名为data的数据
        provide('data', data)
    }
}
</script>
// B.vue
<script>
import {inject} from 'vue'
export default {
    setup() {   
        // 接收A.vue传递过来的数据
        inject('data')  // {prop: 'vue3'}
    }
}
</script>
// C.vue
<script>
import {inject} from 'vue'
export default {
    setup() {   
        // 接收A.vue传递过来的数据
        inject('data')  // {prop: 'vue3'}
    }
}
</script>
 11. watch&watchEffect?用来监视某项数据变化从而执行指定的操作 1. watch(source, cb, [options]): source:可以是表达式或函数,用于指定监听的依赖对象 cb:?依赖对象变化后执行的回调函数 options:?可选参数,可以配置的属性有immediate(立即触发回调函数),deep(深度监听) watch方法会返回一个stop方法,如果需要停止监听,可以直接执行stop方法 <script>
import {ref, reactive, watch} from 'vue'
export default {
    setup() {
        // 监听ref  
        const data1 = ref(0)
        watch(data1, (newValue, oldValue) => {
            console.log(`原值为${oldValue}`, `新值为${newValue}`)
            // 1秒后打印结果:原值为0,新值为1
        })
        setTimeout(() => {
            data1.value ++
        }, 1000)
        
        // 监听reactive 
        const data2 = reactive({prop: 0})
        watch(() => data2.prop, (newValue, oldValue) => {
            console.log(`原值为${oldValue}`, `新值为${newValue})
            // 1秒后打印结果:原值为0,新值为1
        })
        setTimeout(() => {
            data2.prop ++
        }, 1000)
        // 监听多个数据
        const data3 = reactive({ propA: 0, propB: 'vue3' })
        watch(
            [() => data3.propA, () => data3.propB], 
            ([newPropA, newPropB], [oldPropA, oldPropB]) => {
                console.log(oldPropA, newPropA, oldPropB, newPropB)
                // 1秒后打印结果:0, 1, vue3, hello vue3
            }
        )
        setTimeout(() => {
          data3.propA ++
          data3.propB = 'hello vue3'
        }, 1000)
    }
}
</script>
 2. watchEffect watchEffect跟watch不同,它不需要手动传入依赖,每次初始化的时候就会执行一次回调函数来自动获取到依赖,无法获取到原始值,只能获取改变后的值 <script>
import {reactive, watchEffect} from 'vue'
export default {
    setup() {   
        const data = reactive({propA: 0, propB: 'vue3'})
        watchEffect(() => {
            console.log(data.propA, data.propB)
            console.log(state.name)
            // 初始化打印:0 vue3
            // 一秒后打印:1 hello vue3
        })
        setTimeout(() => {
          data.propA ++
          data.propB = 'hello vue3'
        }, 1000)
    }
}
</script>
 12. computed<template>
  <div>
    <p><input type="text" v-model="propA"></p>
    <p><input type="text" v-model="propB"></p>
  </div>
</template>
<script>
import { computed, ref } from 'vue'
export default {
  setup() {
    const propA = ref(0)
    const propB = computed(() => {
      return propA.value + 1
    })
    return { 
      propA,
      propB
    }
  }
}
 13. useStorevue3中使用vuex的方式跟vue2不一样,需要使用vuex中的useStore方法 import Vuex from 'vuex'
const store = Vuex.createStore({
    state: {
        propA: 'vue3'
    },
    mutations: {
        ……
    }
})
<script>
import {useStore} from 'vuex'
export default {
    setup() {   
        const store = useStore()
        console.log(store)
    }
}
</script>
 14. useRoutervue3中使用路由的方式跟vue2不一样,需要使用router中的useRouter方法 <script>
import {useRouter} from 'vue-router'
export default {
    setup() {   
        const router = useRouter()
        router.push({
            path: `/`
        })
    }
}
</script>
 15.?getCurrentInstancevue3中获取实例的方式跟vue2不一样,需要使用getCurrentInstance方法 <template>
    <p></p>
</template>
<script>
import {getCurrentInstance} from 'vue'
export default {
    setup() {   
        const instance = getCurrentInstance()
        console.log(instance)
        return {}
    }
}
</script>
 16. 元素ref属性元素ref属性可以获取到标签的元素或组件 <template>
  <div>
    <div ref="el">div元素</div>
  </div>
</template>
<script>
import { ref, onMounted } from 'vue'
export default {
  setup() {
      // 创建一个DOM引用,名称必须与元素的ref属性名相同
      const el = ref(null)
      // 在挂载后才能通过 el 获取到目标元素
      onMounted(() => {
          console.log(el.value)
      })
      return {el}
  }
}
</script>
 |