当前位置:   article > 正文

vue3学习_vue3 computed 异步

vue3 computed 异步

Vue3的心得(为了更好的服务ts)

1.ref和reactive的区别
2.watch和computed,watchEffect
3.获取dom结点
4.子向父传数据,父向子传数据
5.props和emit
6.动态组件
7.阻止冒泡行为
8.插槽
9.provide和inject
10.异步组件
11.组合式函数
12.自定义指令
13.teleport
14.Suspense
vue2得各种写法可以访问vue3

  • 如果引入一个包,只用了其中一部分,那么通过Tree-shaking就可以把没有利用到的都清除掉。
// 创建应用实例对象 类似于Vue2的vm(比vm更加轻)
const app = createApp(App)
  • 1
  • 2
  • setup函数即可以返回一个对象,同时也可以返回一个函数(渲染函数)
// 返回一个对象
    return {
      a,
      age,
      getAge,
    };
    import {h}from 'vue'
    // 返回一个渲染函数
    return () => h("h1", "abc");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 引用setup数据的时候,并不需要用this

setup函数

  • setup的执行时期是在beforeCreate之前,且只执行一次。
  • setup(props,context)可以添加两个参数,props就是可以获得自定义属性,context可以获得emit,slot等操作。emit在向父组件传值得时候,需要通过emits选项来确定传出去的值是什么。
  • 在这里插入图片描述

h函数

1.渲染函数 return () => h("h1", "abc");

ref函数(通过get和set实现响应式)

  • 定义一个响应式的数据
  • 通过引用ref,然后进行.value进行响应式的修改值。
  • 即可以是基本数据类型的数据,也可以是对象类型的数据。
import { ref } from "vue";
	let a = ref(10);
    let age = ref(5);
    function getAge() {
      a.value = 11;
      age.value = 10;
    }`person.fullAge = computed(() => {
      return person.age + person.name;
    });`
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

reactive函数(通过proxy,内部通过reflect来实现响应式)

  1. 是对象类型的数据
  2. 获取数据的时候不再需要.value,直接.键名就可以。
  3. 这里不再需要$set就可以直接修改对象的值或者添加值。

ref和reactive的区别

  1. 首先ref通常对基本数据类型进行响应式(对象也可以,但是不常用),reactive对对象进行响应式。
  2. ref通过的是Object.defineProperty进行响应式,reactive通过的是proxy(代理对象)。

computed和watch

computed函数

这个存在数据缓存以及不要在computed中使用异步函数。
如果你想要返回一个对象的话,那么箭头函数就得这么写(()=>({}))

  1. 我们通过一个元素来获取computed来重新获取的数据,默认下是get()。
//computed中间是一个回调函数
const value = computed(() => {
  // 默认是get
  return x.a.b;
});
  • 1
  • 2
  • 3
  • 4
  • 5

2.如果我们想直接修改computed值的话就要通过set方法。

const value = computed({
  //默认情况下
  get() {
    return x.a.b;
  },
  // value = 10时候,调用这个。
  set(value) {
    x.a.b = value + 1;
  },
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

watch函数

普通数据类型 watch(基础数据类型,回调函数,配置对象)
引用数据类型 watch(()=>(return 引用数据里面的值),回调函数,配置对象)

	watch(
  //侦听基础数据类型的时候
  y,
  (newValue, oldValue) => {
    console.log(newValue, oldValue);
  }
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
//侦听对象
watch(
  //如果是对象的话就写成getter函数,否则有问题,同时还可以用watchEffect来进行
  () => x[0].a,
  (a) => {
    console.log(a);
  }
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

watchEffect

可以替换watch侦听引用数据类型
可以根据一个数据发生变化之后里面进行异步操作等
如果你想在一个数据展现为true之后立马访问dom的话,那么配置项对象中配置 flush: 'post'

watchEffect(() => {
	//这个可以实例创建之后直接执行一次。
	//可以代替watch侦听引用数据类型的变化。
      const sum = agE.value;
      console.log("123" + sum);
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
const y = ref(10)
//只要y发生变化那么就会执行一次watchEffect
watchEffect(async () => {
  const data = await a1(y.value);
  console.log(data);
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

dom结点

<input ref='koko'/>
const koko = ref(null);
console.log(koko.value.innerHTML)
  • 1
  • 2
  • 3

props

父向子

//在子组件上面添加这个
defineProps(['title'])
//如果需要添加数据类型的时候
const props = defineProps({
  foo: String
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

子向父

1.第一种写法
//子组件
<button @click='$emit('自定义的事件名')'/>
//父组件
<hoho @自定义的事件名='change'/>
2.第二种写法
//子组件
defineEmits(['enlarge-text'])
//父组件
<hoho @enlarge-text='change'/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

props和emit

defineEmits和defineProps中间的参数都是数组
如果在模块中emit的话可以使用$emit,如果在script中的话那么就定义一个emit来使用。

import {defineEmits,defineProps} from 'vue'
	1.不校验版本
  const emit = defineEmits(['showshow'],1)
  	2.校验版本
  const emit = defineEmits((value)=>{
  	if(value){
  	console.log(123)
  	//必须得有返回值
  	return true
  	}
  	})
  	1.不校验版本
  const prop= defineProps(['value'])
  	2.校验版本
  const emit = defineProps({
  		value:String
  		})
  function addMessage(){
    emit('showshow',{
      name:'li',
      age:10
    })
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

动态组件

<button @click="qwe='xixi'">+</button>
<component :is='value[qwe]'></component>

import help from "@/components/help.vue";
import xixi from '@/components/xixi.vue'
let qwe = ref('help')
let value = {
  help,
  xixi
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

阻止冒泡行为

  1. 我们在组件上添加一个点击事件,组件内部也添加一个点击事件,如果内部点击得话,那么会触发冒泡事件。

此时会触发冒泡行为

//组件上
<component :is='value[qwe]' @click="add"></component>
//组件内部
<button @click="addMessage">add</button>
  • 1
  • 2
  • 3
  • 4

阻止冒泡得行为如下:

<script>
  // 使用普通的 <script> 来声明选项
  export default {
    inheritAttrs: false
  }
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

插槽

1.普通插槽
<component :is='value[qwe]'>
1
</component>
//组件内部就显示1
<slot/>
2.具名插槽
<component :is='value[qwe]'>
		//使用模板
      <template #footer>
      1
      </template>
    </component>
 <slot name='footer'/>
3.带值插槽
<component :is='value[qwe]'>
 <template #footer="obj">
   {{obj.title}}
 </template>
</component>
<slot name='footer' title='天气不错'/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

provide和inject

可以解决祖和孙进行数据的交互
多依赖的话 可以创建一个key.js的文件 然后里面存放我们需要注入的内容

// keys.js
export const myInjectionKey = Symbol()
  • 1
  • 2
// 在供给方组件中
import { provide } from 'vue'
import { myInjectionKey } from './keys.js'

provide(myInjectionKey, { /*
  要提供的数据
*/ });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
// 注入方组件
import { inject } from 'vue'
import { myInjectionKey } from './keys.js'

const injected = inject(myInjectionKey)
  • 1
  • 2
  • 3
  • 4
  • 5
祖组件
provide('location',{
  x:'10',
  y:'20'
})
孙组件
const {x,y} = inject('location')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

异步组件

基于的原理就是promise

import xixi from '@/components/xixi.vue'
const great = defineAsyncComponent(()=>{
   return new Promise((resolve)=>{
    setTimeout(()=>{
      resolve(xixi)
    },2000)
   })
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

组合式函数

把我们需要的内容全部抽离出来重新组装成一个函数

hooks函数

  • 封装一个hooks文件夹,然后通过export default function(){}

在这里插入图片描述

1.event.js
import { onMounted, onUnmounted } from "vue";

export function useEventListener(target,event,callback){
  onMounted(()=>{
    target.addEventListener(event,callback)
  })
  onUnmounted(()=>{
    target.removeEventListener(event)
  })
}
2.mouse.js
import {ref } from "vue"
import {useEventListener} from '@/use/event.js'
export function useMouse(){
  const z = ref(0)
  const y = ref(0)
  useEventListener(window,'mousemove',function(event){
    z.value = event.pageX
    y.value = event.pageY
  })
  return {z,y}
}
3.引入该公用函数
import {useMouse} from '@/use/mouse.js'
const {z,y} = useMouse()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

自定义指令

组合式函数的写法就是:
const vFocus = {
	mounted:(el)=>{
	el.focus();
	}
}
非组合式写法:
directives: {
    // 在模板中启用 v-focus
    focus: {
      /* ... */
    }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

teleport

模态框十分适用

  1. 解决定位不到我们需要的位置的时候,可以使用这个方法,比如我们需要定位到body的身上的时候,可以使用这个标签。
父元素有position,但是模态框并不受这个影响。
<div class="mask1">
1.定位到我们想要的body身上。
    <teleport to='body'>
      <div class="mask" v-if="show">
      <div class="content">
        <button @click="show=false"></button>
      </div>
    </div>
    </teleport>
  </div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

Suspense

  1. 这个是为了服务异步组件时候来使用。
  2. 如果我们异步组件加载失败的话,那么可以通过这个标签来加载备用内容。
<Suspense>
//如果great组件加载失败的话,那么可以一直是loading
<great :value='{z,y}'/>
<template #fallback>
  <h1>loading</h1>
</template>
</Suspense>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

toRef函数

  • 可以获取某对象的某属性的值,同时该属性的值变化的时候,自己的值也会变化。

toRefs函数

  • 可以将一个对象类型的数据,将其属性全部展现为一个又一个的分支。

import {toRefs} from ‘vue’
let person = reactive({
age: 10,
name: “li”,
hobby: [1, 2, 3],
a: {
b: {
c: 10,
},
},
});
return {
…toRefs(person),
};


## shallowReactive函数

 - 就是浅拷贝数据对象。
 - 让自己自增,页面不会显示,但是让别的自增,之前自己的自增就会显现出来。
`让c自增页面不会显示,但是自增age的话c就会在页面显示最新的数据。`
```javascript
let person = shallowReactive({
      age: 10,
      name: "li",
      hobby: [1, 2, 3],
      a: {
        b: {
          c: 10,
        },
      },
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

shallowRef函数

  • 数据不需要修改的时候,可以用这个。(也就是对象数据的时候)

readonly函数

  • 使数据变成可读的,不能进行修改。
person = readonly(person);
  • 1

shallowReadonly函数

  • 也就是数据对象的第一层不能够修改,深层次的可以修改。

toRaw函数

  • 可以把响应式数据reactive,还原成最初始的数据。

markRaw函数

  • 指定添加的数据不具有响应式。

##customRef函数

  • 创建一个自定义的rf,并对其依赖项跟踪和更新触发进行显式控制。
 function myRef(value) {
      // 闭包 返回一个函数,参数是一个函数
      return customRef((track, trigger) => {
        // 返回一个对象
        return {
          // 第一步
          get() {
            // 第四步
            // 通知vue追踪数据的变化
            track();
            return value;
          },
          // 第二步
          set(newValue) {
            value = newValue;
            // 延迟解析模板
            setTimeout(() => {
              // 第三步
              // 通知vue重新解析模板
              trigger();
            }, 2000);
          },
        };
      });
    }
    // 自定义函数的返回参数
    let data = myRef(123);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

provide和inject函数

  • 实现祖孙组件间通信
  • 父组件有一个provide选项来提供数据,子组件有一个inject选项来使用数据。

响应式数据的判断在这里插入图片描述

fragment组件

  • 虚拟元素,也就是可以不需要根标签了。

teleport组件

  • teleport是一种能够将我们的组件html结构移动到指定位置的技术。

Suspense组件

<!-- 异步组件 -->
  <Suspense>
    <!-- 成功得时候 -->
    <template v-slot:default> </template>
    <!-- 失败的时候 -->
    <template v-slot:fallback> </template>
  </Suspense>
  import { defineAsyncComponent } from "vue";
  异步组件
const child = defineAsyncComponent(() => import("./"));
同时这个可以配合promise对象来使用。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

其他得一些修改

// 等同于vue.prototype,往原型链上面添加值。
app.config.globalProperties;

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/845551
推荐阅读
相关标签
  

闽ICP备14008679号