@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)
????????????????????????}
????????????????}
????????})
????????
????????
????????????????? ? ? ? ? ??
????????
????????
? ? ? ??
????????
????????
????????
? ? ? ??