欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

组合式 API(Composition API)

程序员文章站 2022-03-13 12:51:00
...

认识组合式 API(Composition API)

  1. <template>
  2. <div class="home">
  3. {{data.count}}<hr>
  4. <button @click="data.count++">++</button><hr>
  5. <button @click="add()">++</button><hr>
  6. {{data.pow}}
  7. </div>
  8. </template>
  9. <script>
  10. import { reactive,computed} from "vue";
  11. export default {
  12. name: 'Home',
  13. // data(){
  14. //
  15. // },
  16. // components:{
  17. //
  18. // },
  19. //vue3 新增setup 但是可以与原来的共生,但命名不要冲突
  20. setup(){
  21. const data= reactive({
  22. count:10,
  23. pow:computed(()=>data.count*data.count)
  24. })
  25. const add=()=>{
  26. data.count++;
  27. }
  28. return{
  29. data,
  30. add
  31. }
  32. }
  33. }
  34. </script>

组合式 API(Composition API)

setup()方法应用

  1. <template>
  2. <div>
  3. <h1>这是子组件</h1>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: "SubComp",
  9. data(){
  10. return{
  11. num:1
  12. }
  13. },
  14. beforeCreate() {
  15. console.log('beforeCreate')
  16. },
  17. created() {
  18. console.log('created');
  19. console.log(this.num);
  20. },
  21. beforeMount() {
  22. console.log('beforeMount')
  23. },
  24. setup(){
  25. console.log('setup');//组件创建之前调用 setup() 没this
  26. }
  27. }
  28. </script>
  29. <style scoped>
  30. </style>

组合式 API(Composition API)

setup()的参数

  1. <template>
  2. <div class="about">
  3. <h1>父组件:关于setup()</h1>
  4. <sub-comp @myadd="add" one="this one" :two="10" three="hello" four="world">
  5. <h2>SLOT</h2>
  6. </sub-comp>
  7. </div>
  8. </template>
  9. <script>
  10. import SubComp from "../components/SubComp";
  11. export default {
  12. name:'About',
  13. components:{
  14. SubComp
  15. },
  16. methods: {
  17. add(str){
  18. console.log(str);
  19. }
  20. }
  21. }
  22. </script>
  23. <template>
  24. <div>
  25. <h1>这是子组件</h1>
  26. one={{one}}<hr>
  27. two={{two}}<hr>
  28. <button @click="add()">++</button>
  29. <slot>111</slot>
  30. </div>
  31. </template>
  32. <script>
  33. export default {
  34. name: "SubComp",
  35. props:{
  36. one:{
  37. type:String
  38. },
  39. two: {
  40. type:Number
  41. }
  42. },
  43. setup(props,{attrs, slots, emit}){
  44. console.log(attrs.three);
  45. console.log(slots.default());
  46. console.log(attrs.desc);
  47. emit('myadd', '向父组件传数据')
  48. const add =()=>{
  49. console.log(props.two); //10
  50. }
  51. return{
  52. add
  53. }
  54. }
  55. // setup(props, context) {
  56. // context.attrs // 没有在props中声明的其他传组子组件的属性
  57. // context.slots
  58. // context.parent
  59. // context.root
  60. // context.emit
  61. // context.refs
  62. // }
  63. // setup(props,context){
  64. // console.log(context);
  65. // console.log(context.attrs);
  66. // console.log(context.attrs.three);
  67. // console.log(context.slots.default());
  68. // const add =()=>{
  69. // console.log(this) // undefined
  70. // console.log(props.two); //10
  71. // props.two++;// target is readonly
  72. // }
  73. // return{
  74. // add
  75. // }
  76. // }
  77. // data(){
  78. // return{
  79. // num:1
  80. // }
  81. // },
  82. // beforeCreate() {
  83. // console.log('beforeCreate')
  84. // },
  85. // created() {
  86. // console.log('created');
  87. // console.log(this.num);
  88. // },
  89. // beforeMount() {
  90. // console.log('beforeMount')
  91. // },
  92. // setup(){
  93. // console.log('setup');//组件创建之前调用 setup() 没this
  94. // }
  95. }
  96. </script>
  97. <style scoped>
  98. </style>

组合式 API(Composition API)

常用API

  • ref()函数用来给定的值创建一个响应式的数据对象,ref()的返回值是一个对象,这个对象上只包含一个.value属性.
  • reactive是用来创建一个响应式对象
  • 将ref响应式数据挂载到reactive中,当把ref()创建出来值直接挂载到reactive()中时,会自动把响应式数据对象的展开为原始的值,不需要通过.value就可以直接访问到
  • 双向绑定
  • toRefs()解构响应式对象
  • readonly将响应式数据变回原使数据
  1. <template>
  2. <div>
  3. <h1>常用api</h1>
  4. <div>{{num}}</div>
  5. <button @click="num++">++</button>
  6. <hr>
  7. <div>{{num2}}</div>
  8. <button @click="num2++">++</button>
  9. <button @click="add2()">++ add2</button>
  10. <hr>
  11. <div>{{one}}</div>
  12. <hr>
  13. <div>{{two}}</div>
  14. <hr>
  15. <div v-for="(item,i) in two" :key="i">{{item}}</div>
  16. </div>
  17. </template>
  18. <script>
  19. import {ref,reactive,toRefs,readonly,isRef} from 'vue'
  20. export default {
  21. name: "SetApi",
  22. setup(){
  23. let num=10
  24. let num2=ref(0)
  25. const data=reactive({
  26. one:100,
  27. two:['1111','2222']
  28. })
  29. const add2=()=>{
  30. console.log(num2.value)
  31. num2.value++
  32. data.one++
  33. }
  34. let num8= isRef(num2) ? num2.value :num2
  35. let num3 =readonly(num2)
  36. return{
  37. num,
  38. num2,
  39. add2,
  40. // data,
  41. //...data 展开可以直接调用one和two 展开之后不再是响应式
  42. ...toRefs(data) //保持响应式
  43. }
  44. }
  45. }
  46. </script>
  47. <style scoped>
  48. </style>

组合式 API(Composition API)

计算属性API(computed)

  • computed()用来创建计算属性,返回值是一个ref的实例
  • 创建可读可写的计算属性。在使用computed函数期间,传入一个包含get和set函数的对象,可以额得到一个可读可写的计算属性
  1. <template>
  2. <div>
  3. <h1>computed()</h1>
  4. <div>num={{num}}</div>
  5. <hr>
  6. <button @click="num++">{{num}}++</button>
  7. {{all}}
  8. <hr>
  9. <input type="text" v-model="user.first">
  10. <input type="text" v-model="user.end">
  11. </div>
  12. </template>
  13. <script>
  14. import {ref,reactive,computed} from "vue";
  15. export default {
  16. name: "Comp",
  17. setup(){
  18. let num= ref(0)
  19. const user = reactive({
  20. first:'php',
  21. end:'cn'
  22. })
  23. const all = computed(() =>{
  24. return user.first + '.' +user.end
  25. })
  26. return{
  27. num,
  28. user,
  29. all
  30. }
  31. }
  32. }
  33. </script>
  34. <style scoped>
  35. </style>

组合式 API(Composition API)

侦听器watch

监听数字变化

  1. <template>
  2. <div>
  3. <h1>Watch</h1>
  4. <h2>a={{a}}, b={{b}}</h2>
  5. <button @click="a++">a++</button>
  6. <button @click="b++">b++</button>
  7. </div>
  8. </template>
  9. <script>
  10. import {ref,reactive,watch,watchEffect,toRef} from 'vue';
  11. export default {
  12. name: "Watch",
  13. setup(){
  14. let a= ref(0)
  15. let b=ref(2)
  16. // watchEffect 它与 watch 的区别主要有以下几点:
  17. //懒执行副作用;
  18. //更明确哪些状态的改变会触发侦听器重新运行副作用;
  19. //访问侦听状态变化前后的值。
  20. // watch(a,(newa,olda)=>{
  21. // console.log('a的值:'+a.value+'############# a的新值:'+ newa+',a的原值:'+olda)
  22. // },{immediate:true})
  23. // {immediate:true} 默认执行一次
  24. watch([a,b],([newa,newb],[olda,oldb])=>{
  25. console.log('a的值:'+a.value+'############# a的新值:'+ newa+',a的原值:'+olda)
  26. console.log('b的值:'+b.value+'############# b的新值:'+ newb+',b的原值:'+oldb)
  27. },{immediate:true})
  28. // watch(()=>{
  29. // console.log(a.value+'++++++++++++++'+b.value)
  30. // })
  31. // watchEffect(()=>{
  32. // console.log(a.value+'++++++++++++++'+b.value)
  33. // })
  34. return{
  35. a,
  36. b
  37. }
  38. }
  39. }
  40. </script>
  41. <style scoped>
  42. </style>

组合式 API(Composition API)

监听对象

  1. <template>
  2. <div>
  3. <h1>Watch</h1>
  4. <h2>a={{a}}, b={{b}}</h2>
  5. <button @click="a++">a++</button>
  6. <button @click="b++">b++</button>
  7. <hr>
  8. <input type="text" v-model="nnn"><hr>
  9. <input type="text" v-model="age"><hr>
  10. {{nnn}} --- {{age}}
  11. </div>
  12. </template>
  13. <script>
  14. import {ref,reactive,watch,watchEffect,toRefs} from 'vue';
  15. export default {
  16. name: "Watch",
  17. setup(){
  18. let a= ref(0)
  19. let b=ref(2)
  20. const user = reactive({
  21. age:30,
  22. nnn:'xiaoming'
  23. })
  24. watch([()=>user.age,()=>user.nnn],()=>{
  25. console.log(user.age+'***************')
  26. },{immediate:true})
  27. return{
  28. a,
  29. b,
  30. ...toRefs(user)
  31. }
  32. }
  33. }
  34. </script>
  35. <style scoped>
  36. </style>

组合式 API(Composition API)

生命周期

  1. 选项式 API 的生命周期选项和组合式 API 之间的映射
  2. beforeCreate -> 使用 setup()
  3. created -> 使用 setup()
  4. beforeMount -> onBeforeMount
  5. mounted -> onMounted
  6. beforeUpdate -> onBeforeUpdate
  7. updated -> onUpdated
  8. beforeUnmount -> onBeforeUnmount
  9. unmounted -> onUnmounted
  10. errorCaptured -> onErrorCaptured
  11. renderTracked -> onRenderTracked
  12. renderTriggered -> onRenderTriggered
  13. activated -> onActivated
  14. deactivated -> onDeactivated
  1. <template>
  2. <div>
  3. </div>
  4. </template>
  5. <script>
  6. import {onMounted, onUpdated} from 'vue';
  7. export default {
  8. name: "Time",
  9. beforeCreate() {
  10. console.log('beforeCreate() ---');
  11. },
  12. created() {
  13. console.log('create() .....');
  14. },
  15. mounted() {
  16. console.log('mounted() .....')
  17. },
  18. setup() {
  19. console.log('setup().....');
  20. let one = '11111';
  21. onMounted(()=>{
  22. console.log(one+'onmounted.....')
  23. });
  24. onUpdated(()=>{
  25. console.log('onUpdate....');
  26. })
  27. }
  28. }
  29. </script>
  30. <style scoped>
  31. </style>

在组合API中provide和inject使用

  1. 父子组件:通过props,$emit,【$root,$parent,$children】
  2. 非父子组件:Vuex实现,父子层层传递、$ref
  3. provide/inject 这对选项允许一个祖先组件向其所有子孙后代组件注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
  4. provide就相当于加强版父组件prop,可以跨越中间组件,inject就相当于加强版子组件的props
  5. 使用办法
  6. provide 提供变量:Object | () => Object
  7. inject 注入变量: Array<string> | { [key: string]: string | Object }
  1. <template>
  2. <div>
  3. <h1>父组件</h1>
  4. <two></two>
  5. </div>
  6. </template>
  7. <script>
  8. import Two from "../components/Two";
  9. import {reactive,provide,ref} from "vue";
  10. export default {
  11. name: "One",
  12. components:{
  13. Two
  14. },
  15. //原来的方法
  16. // provide(){
  17. // return{
  18. // count:99
  19. // }
  20. // },
  21. setup() {
  22. const name = ref('lmonkey')
  23. const obj = reactive({
  24. name: 'lmonkey',
  25. age: '3'
  26. })
  27. provide('name', name)
  28. provide('animal', obj)
  29. }
  30. }
  31. </script>
  32. <style scoped>
  33. </style>
  34. <template>
  35. <div>
  36. <h1>孙组件</h1>
  37. <!-- {{count}}-&#45;&#45;<hr>-->
  38. {{name}}--<hr>
  39. {{animal}}---<hr>
  40. <div v-for="(item,i) in animal" :key="i">{{i}}--{{item}}</div>
  41. <hr>
  42. <input type="text" v-model="name"><hr>
  43. </div>
  44. </template>
  45. <script>
  46. import {inject} from "vue";
  47. export default {
  48. name: "Sun",
  49. // inject:['count'],
  50. setup() {
  51. // 用法: inject(key)
  52. const name = inject('name')
  53. const animal = inject('animal')
  54. return {
  55. name,
  56. animal
  57. }
  58. }
  59. }
  60. </script>
  61. <style scoped>
  62. </style>

组合式 API(Composition API)

Composition API结合路由

  1. <template>
  2. <div>
  3. <h1>Router</h1>
  4. </div>
  5. </template>
  6. <script>
  7. import {useRoute,useRouter} from 'vue-router';
  8. export default {
  9. name: "Router",
  10. setup(){
  11. const route=useRoute();
  12. const router=useRouter();
  13. console.log(route);
  14. console.log(route.fullPath);
  15. console.log(route.query);
  16. console.log(route.params.uid) //user/14
  17. console.log(router);
  18. // setTimeout(()=>{
  19. // router.push({path:'/',query:{name:1111,age:2222}})
  20. // },5000)
  21. }
  22. }
  23. </script>
  24. <style scoped>
  25. </style>
  1. import { createStore } from 'vuex'
  2. export default createStore({
  3. state: {
  4. num1:11,
  5. num2:22
  6. },
  7. getters:{
  8. double1(state) {
  9. return state.num1 * 2;
  10. },
  11. double2(state) {
  12. return state.num2 * 2;
  13. }
  14. },
  15. mutations: {
  16. changenum1(state, payload){
  17. state.num1 = payload;
  18. },
  19. changenum2(state, payload){
  20. state.num2 = payload;
  21. }
  22. },
  23. actions: {
  24. timecnum1({commit, state}) {
  25. setTimeout(()=>{
  26. commit('changenum1', 44);
  27. }, 5000)
  28. },
  29. timecnum2({commit, state}) {
  30. setTimeout(()=>{
  31. commit('changenum2', 55);
  32. }, 5000)
  33. }
  34. },
  35. modules: {
  36. }
  37. })
  38. <template>
  39. <h2>Vuex Api useStore</h2>
  40. <h3>num1: {{$store.state.num1}}</h3>
  41. <h3>getter-num1: {{$store.getters.double1}}</h3>
  42. <button @click="cnum1(33)">修改num1:{{$store.state.num1}}</button>
  43. <button @click="canum1">修改anum1:{{$store.state.num1}}</button>
  44. <hr>
  45. <h3>num2: {{num2}}</h3>
  46. <h3>getters-num2: {{double2}}</h3>
  47. <button @click="cnum2(33)">修改num2:{{num2}}</button>
  48. <button @click="canum2">修改anum2:{{num2}}</button>
  49. </template>
  50. <script>
  51. import {useStore} from 'vuex';
  52. import {computed} from 'vue';
  53. export default {
  54. name: "VuexApi",
  55. setup() {
  56. const store = useStore();
  57. return {
  58. num2:computed(()=>store.state.num2),
  59. double2:computed(()=>store.getters.double2),
  60. cnum2:(newnum)=>{
  61. store.commit('changenum2', newnum);
  62. },
  63. canum2:()=>{
  64. store.dispatch('timecnum2');
  65. }
  66. }
  67. },
  68. methods: {
  69. cnum1(newnum) {
  70. this.$store.commit('changenum1', newnum);
  71. },
  72. canum1() {
  73. this.$store.dispatch('timecnum1');
  74. }
  75. }
  76. }
  77. </script>
  78. <style scoped>
  79. </style>

组合式 API(Composition API)