博客列表 >组合式 API(Composition API)

组合式 API(Composition API)

初见
初见原创
2021年11月06日 17:16:241180浏览

认识组合式 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

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>

setup

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

  • 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(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>

计算

侦听器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>

监听数字

监听对象

  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>

监听对象

生命周期

  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>

祖孙传值

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>

Vuex

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议