vue_record

vue3

1.组合式API,在单文件组件中(spa) single page application , 通常会与搭配使用,这个setup attribute 是一个标识,告诉vue在编译时进行一些处理,让我们更简洁的使用组合式API

<script setup >
    import {ref,onMounted} from 'vue'

2.组合式API的核心思想是直接在函数作用域内定义响应式状态变量,并将从多个函数中得到的状态组合起来处理复杂问题.

创建一个vite+vue3的脚手架项目

1.npm init vue@latest

2.cd 到项目 npm i 安装依赖

3.启动项目 npm run dev

应用配置 app.config.errorHandler

应用实例会暴露一个.config对象,允许我们配置一些应用级的选项.

声明响应式状态 reactive

import { reactive } from "vue"
export default {
    setup(){ //setup是一个专门用于组合式API的特殊钩子函数
        const state = reactive({count:0})
        
        function increment(){ //方法 也需要return 暴露
          state.count++  
        }
        
        return { //暴露响应式对象到模板中
            state,
            increment
        }
    }
}

响应式对象其实是JavaScript Proxy ,代理,他可以自由的定义变量是否是响应式.vue会跟踪响应式对象的属性的访问和更改操作

<script setup>

setup钩子函数使用很频繁,可以使用构建工具来简化代码

<script setup>
	import { reactive } from "vue"	
	const state = reactive({count:1})
    function increment(){
        state.count++
    }
</script>
<template>
 	<button @click='increment'>{{state.count}}</button>   
 </template>	

reactive响应式对象和普通对象

如果一个响应式对象再次被reactive 所代理,则该对象会失去响应式连接

let state = reactive({count:0})
state = reactive({count:1})    //该响应式对象会失去响应式连接,并且在脚手架环境下会报错

const obj = reactive({})
const obj1 = {}
obj === obj1    ?     //  false
    
const obj = {}
const obj1 = reactive({})
obj1.name = obj

obj1.name === obj ?   //false

ref 和reactive

1.reactive 仅对对象类型的有效,对简单数据类型无效

2.对一个变量多次是用reactive替换响应式,会使该响应式是去连接.

3.ref 适用于所有的类型的响应式,但是读取值的时候会多一个value,例如:

const num = ref(3)
console.log(num) // {value:3}
console.log(num.value) // 3

计算属性computed 和methods

1.计算属性的值会基于其响应式依赖被缓存,只有当响应式依赖发生了改变才会重新计算,而方法不用,例如

const now = computed(()=>Date.now())    //永远不会更新,以为Date.now并不是一个响应式依赖

2.不要再计算属性中做异步请求和更新dom,他的义务和职责仅为计算和返回该值

3.计算属性的返回值应该被视为只读的,并且永远不应该被更改,应该更新它所依赖的源(响应式依赖)来触发新的计算

vue能够侦听响应式数组的变更方法,变更方法包括

push()
unshift()
pop()
reverse()
sort()
splice()
shift()

watch 侦听器(参考链接:https://blog.csdn.net/weixin_42776027/article/details/125759685)

const obj = reactive({
    name:"前端",
    nickName:"hulk",
    soulmate:{
        name:"薛之谦",
        nickName:"世界和平"
    }
})
const num = ref(1)

1.侦听整个对象,对象中任意一个值发生改变都会触发,无论是子属性还是孙属性

watch(obj,(newValue,oldValue)=>{
	console.log(newValue,oldValue)
})

2.监听对象中某个值的变化,仅当obj中的name发生改变才触发

watch(()=>>obj.name,(newV,oldV)=>{
    console.log(newV,oldV)
})

3.监听对象的子属性发生变化时触发,孙属性发生变化不会触发

watch(()=>({...obj}),(newV,oldV)=>{
	console.log(newV,oldV)
})

4.组合式监听,同时监听两个

watch([()=>obj.name,num],([newV1,oldV1],[newV2,oldV2])=>{
	
})

watchEffect

watchEffect会在同步执行中立即执行一次回调函数,并且会自动追踪响应式的依赖源,如果响应式的依赖源再次发生改变,回调函数会再次触发.

const str = ref('')

watchEffect(async()=>{
	const res = await axios('http:...')
	str.value = await res.data.json()
}) //在使用异步回调时,只有在第一个await正常工作前访问到的属性才会被跟踪

监听器回调触发的时机 和 停止监听器

1.默认用户创建的监听器都是在vue组件更新前触发的,如果想要在回调中访问vue更新后的dom,需要指明flush:“post”

watch(source,callback,{flush:"post"})
warchEffect(callback,{flush:"post"})

2.停止侦听器

setTimeout(()=>{
    watchEffect(()=>{})
},100) //无法停止

const unWatch = watchEffect(()=>{})
unWatch() //正常停止

模板引用

<button ref='cusButton'></button>

<script setup>
    import { ref,onMounted } from "vue"
	const cusButton = ref(null) //声明一个跟ref同名的,ref响应式变量,来存放该元素的引用
    onMounted(()=>{
        console.log(cusButton.value) //在页面挂载后访问该元素
    })
</script>

vue2 和 vue3 生命周期的区别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pfjZBCAC-1661324098046)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20220823092939647.png)]

组件上的ref

如果子组件没有使用<script setup,使用的是选项式API,并且被引用的组件实例和子组件的this保持一致,那么父组件可以完全访问子组件中的任意一个属性和方法.但是大多数情况下还是推荐使用标准的props和emit来实现父子间的交互.<script setup中,每个组件的属性和方法默认是私有的,父组件无法访问到子组件的任何东西,除非子组件通过defineExpose宏显示暴露.

<script setup>
	import {ref} from "vue"
	const num  = ref(3)
	defineExpose({
		num
	})
</script>

<script setup 和 setup(){} 父子传值的区别 defineProps 和defineEmits

1.defineProps接收一个对象.对象的格式如下

{
	type:String //接收的数据类型
	default:"你好" //接收的默认值
	required:true //是否必传
}

//例如:
<script setup>
	const allProps = defineProps({
		title:{
			type:String,
			default:"你好"
		},
		numArr:{
			type:Array,
			required:true
		}
	})
</script>

2.defineEmits 接收一个数组,数组里面的内容为触发事件的名称,并非方法名称

<template>
	<button @click='emitFn'></button>    
</template>

<script setup>
	const emit = defineEmits('cusClick')    
	function emitFn(){
        emit('cusClick',1)
    }
</script>

3.在setup(){}函数中的接收pros和emit

<script>
    export default {
        props:{
          msg:{
            type:String,
            default:"nihao"
          }
        },
        emits:['cusText'],
        setup(props,ctx){

          const cusFn = ()=>{
            ctx.emit('cusText',props.msg)
          }

          return {
            cusFn
          }
        }
      }
</script>



单向数据流

所有的props都遵循单向绑定的原则,props因父组件的更新而变化,自然地将新的状态向下流往子组件,而不会逆向传递.另外.每次父组件更新后,所有的子组件中的props都会被更新到最新值,这意味着不应该在子组件中去更改一个prop.若想更改一个prop,通常来源于以下两种场景:

1.prop被用于初始传入值,而子组件想再之后将其作为一个局部数据属性

const props = defineProps({
    title:[String]
})

const subTitle = ref(props.title) //这样做就和后续的props没有任何关系了

2.需要对传入的props进一步处理

const arr= defineProps(["array"])

const computedArr = computed(()=>arr.map(item=>item))

依赖入驻 provide 和 inject ,解决 多层级嵌套的组件传值问题

1.provide 提供数据,可以多次调用,以提供不同的依赖值

<script setup>
	import { provide,ref } from "vue"    
	const num = ref(3)
	provide('key',num)	
	// provide(/*注入名*/'msg',/*注入值*/'你好,世界')
</script>

2.inject 注入接收数据.为防止祖先没有提供注入名而导致的报错,可以在inject时提供默认值

<script setup>
	import { inject } from "vue"    
	const num = inject('key')
    //提供inject 默认值
    const num1 = inject('key',2)
    
</script>

3.尽可能的将对任何响应式属性变更的方法保存在提供方中,不要在接收方直接更改提供方响应书的属性

//接收方
<template>
	<button @click='increment'>{{num}}</button>	
</template>
<script setup>
	import {inject} from "vue"
	const {num,increment} = inject('numAdd')
</script>
    
//提供方
<script setup>
	import {provide,ref} from "vue"
	const num = ref(3)
    function increment(){
        num.value++
    }
    
    provide('numAdd',{
        num,
        increment
    })
</script>

lick=‘increment’>{{num}}

//提供方


### 
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值