@1 ref既可以定义基本数据类型,也可以定义对象数据类型。ref在使用watch的时候没有默认deep
为true,react定义的对象类型数据在使用watch的时候默认是开启的deep为true的。
@2 ref为对象重新赋值的时候不会失去响应式的,而reactive重新分配一个对象不是响应式的,如果想要响应式的需要使用 object.assign(源对象,要覆盖的对象)。
@3 可以定义一个计算属性为可读可写的
const a = ref(10)
const count = computed({
get () { return a.value },
set(value){ a.value= value}
})
@4 watch也有返回值
const stopWatch = watch(a,(value)=>{
if(a>20){
stopWatch() // 如果符合条件,监听器不再监听a的变化
}
})
@5 watchEffect // 监视数据 依赖到哪个数据 就直接监听到哪个数据了
watchEffer(()=>{
if(a>20) {
.. 向服务器发送请求
}
})
@6 definedExport({...接受需要对外暴露的数据})父组件如果通过ref获取子组件的数据和方法的
时候,因为子组件的数据是受保护的私有的,需要向外暴露。不需要引入。
@7 关于ts的使用,定义一个接口
interface PersonInter { //定义了一个对象类型的接口
name:string,
age:number,
sex?:string
}
定义一个数组对象类型的接口
type Persons = Array<PersonInter> // 也能写为 PersonInter[ ]
在组件中使用:
import {type PersonInter} from '../.'
let personList = reactive<Persons> = [ {name:'zs',age:12},{...},{...}]
@8 接收父组件传递的数据 并限制类型 加上默认值
只接收
defineProps(['list'])
限制类型
defineProps<{list:Persons}>()
限制类型 指定默认值
withDefault(defineProps<{list?:Persons}>(), {list:()=>[{name:'zs',age:12}] } )
拥有返回值在setup中可以访问
let x = defineProps['list']
@9 Hook组件 就是把相同的数据和操作数据的方法封装在同一个ts文件中,并向外导出数据和方法,在组件中引入并使用就可以了。
import {ref} from 'Vue'
import axios from 'axios'
export default function () {
const a = ref(10)
const addA = ()=>{
a.value += 1
}
return {a,addA}
}
组件中导入 import useCount from ‘./...’
const {a,addA} = useCount()
组件中再使用就可以了
@10 pinia的使用
第一步 安装 pinia
第二步 main.ts文件中导入 import {createPinia} from 'pinia'
第三步 创建pinia const pinia = createPinia()
第四步 挂载 app.use(pinia)
第五步 创建store文件夹 使用独立的模块管理
import {defineStore} from 'pinia'
export const useCountstore = defineStore('count',{ // count是store容器的名字
state() { // 存储数据的地方
return {
sun:10
}
},
actions:{
changeSun(value){ // 修改数据 这里面也可以做异步获取数据的方法
this.sun+=value // this代表整个容器
}
}
})
第六步 组件中使用
import {useCounstore} from './store/count'
const countStore = useCountStore()
获取数据
countStore.sun
获取修改数据的方法
countStore.changeSun(10) // 调用方法 传递参数
第七步 使用storeToRefs将结构出来store中的数据变成响应式的
import {storeToRefs} from ‘pinia’
mport {useCounstore} from './store/count'
const countStore = useCountStore()
// $subscibe 监听store数据发生变化 同时将数据存储到本地
countStore.$subscribe((mutate,state)=>{localstoreage.setItem('sun',JSON.stringfy(sun))})
const {sun} = storeToRefs(countStore.sun) // 将数据变为响应式的
在组件中也可以不同cations的方法直接修改store里面的数据
第七步 getters的使用
getters:{
bingSun(state){
return state.sun+10
}
}
@11 组件之间的传递方式
第一种 父->子:
父组件 <children name='zs' age='18' changeFn="()=>{console.log('...')}"></children>
子组件 defiendProps(['name','age','changeFn'])
第二种 子->父:
父组件 <children @changeSun = "getSun"/>
const getSun = (value)=>{console.log(value)}
子组件 <button @click="sendSun">
const emit = defiendEmit(['changeSun'])
sendSun(){ emit('changeSun', 10) }
第三种 emit:
// 创建mitt.ts文件
import mitt from 'mitt'
const emitter = mitt()
export default emiiter
// 组件中使用
import emitter from './..'
发送数据使用 @click=“()=>{emitter.emit('sendSun', 10 )}”
接受数据 @click=()=> {emitter.on('sendSun',(value)=>{console.log(value)})}
第四种 v-model
父组件
<children v-model="count"></children>
<children :modelValue="count" @update:modelvalue="count=$event">
子组件需要接受
defieneProps(['count'])
const emit = defieneEmits(['update:modelvalue'])
<input :value="count"
@input="emit('update:modelvalue'<HtmlInputElement>$event.targer.value)"
/>
第五种:$sttrs
祖->孙
通过祖 父 再到孙
祖组件给父组件传递属性 <children a="10" b="20">
父组件此刻不是有props接受 所有传递的属性都存在$sttrs上面了
父组件 <Sun v-bind="$sttrs"> 传给孙组件
孙组件defineProps([a,b])
第六种 $refs $parents
父组件给通过给子组件绑定ref获取子组件的实例 然后通过$refs就可以获取所有绑定
ref属性的子组件的实例得到的是一个数组。@click=“getChildren($refs)”
$parent主要是用来获取父组件的实例 @click="getparent($parent)"
第七步 project inject
父组件 project(‘名字’,传递的值)
孙组件 const a = inject(‘名字’ , '也可以设置默认值')
@12 自定义的ref customRef
let initval = ''
let time =null
let msg = customRef((track,trigger)=>{
return {
get() {
track() // 持续根据数据发生的变化
return initval
},
set(value){
clearTimeout(timer)
// 这里可是使用定时器 延迟使用 相当于防抖
timer = setTimeout(()=>{
initval = value
trigger() // 通知vue数据msg发生了变化
},1000)
}
}
})