vue3学习笔记

*与vue2的区别

        vue2配置项的风格

        vue3组合式的风格

*通过createApp创建实例

*setup早于beforecreate

1.创建vue3方式

        1。vue-cli创建(基于webpack)

        2。vite创建(官方推荐,安装node才可支持npm  安装后重启电脑)

        

2.ref和reactive

import { ref, reactive } from 'vue';

区别:

1.ref创建的变量必须使用.value (可以使用 volar 插件自动添加. value )。
2. reactive 重新分配一个新对象,会失去响应式(可以使用 Object . assign 去整体替换)。

 let game=reactive([
      {id:'1',name:'game1'},
      {id:'2',name:'game2'},
      {id:'3',name:'game3'}
 ]) 

  function changeGame(){
      
      Object.assign(game,reactive([
           {id:'1',name:'game5'},
           {id:'2',name:'game6'},
           {id:'3',name:'game7'}
      ]))
   }

使用原则:
1.   若需要一个基本类型的响应式数据必须使用 ref 。
2.若需要一个响应式对象,层级不深, ref 、 reactive 都可以。ref定义对象本质是借助reactive实现响应式的。

3.若需要一个响应式对象,且层级较深,推荐使用 reactive 。

 3.toRef和toRefs
  • toRef: 复制 reactive 里的单个属性并转成 ref
  • toRefs: 复制 reactive 里的所有属性并转成 ref
 let info = reactive({
      name: 'Tony',
      greet: 'Hello'
    })
// 复制 info 里的 greet 属性
  let rGreet = toRef(info, 'greet')


 rGreet.value = 'world!'

 rGreet 改变 则  info里面的greet改变

 let info = reactive({
      name: 'Tony',
      greet: 'Hello'
    })
	// 复制整个 info
    let rInfo = toRefs(info)
    // 更改 rInfo.greet
    const onChangeGreet = () => {
      rInfo.greet.value = 'world!'
    }

4.computed  计算属性-有缓存,所计算结果发生变化才再次执行

方法用几次叫用几次,没有缓存

<template>
  <div>
    计算属性
    <div><span>姓:</span> <input type="text" v-model="xing"></div>
    <div><span>名:</span> <input type="text" v-model="ming"></div>
    <div><span>全名:{{ funllname }}</span> </div>
    <div><span>全名:{{ funllname }}</span> </div>
    <div><span>全名:{{ funllname }}</span> </div>
    <button @click="changename">改变姓名为li-si</button>
  </div>
</template>

<script lang="ts" setup>
  import { ref,computed } from 'vue';
  let xing=ref("zhang")
  let ming=ref("san")
  // computed有缓存   多次调用没有改变的话只执行一次
  // 这么定义的funllname是只读的
  // let funllname=computed(()=>{
  //   return xing.value+"-"+ming.value
  // })


  // 这么定义才是funllname可读写的
  let funllname=computed({   //funllname是个ref定义的响应式数据
    get()  {
      return xing.value+"-"+ming.value
    },
    set(name){
      console.log(name)
      let [str1,str2]=name.split("-")
      xing.value=str1
      ming.value=str2
      
    }
    
  })

  function changename(){
    //funllname是个ref定义的响应式数据
    funllname.value="li-si"
  }
</script>
5.watch监听

 情况一:监视ref定义的基本类型

<template>
  <div>
    情况一:监视ref定义的基本类型
    sumde:{{ sum }}
    <button @click="addsum">sum1+1</button>
  </div>
</template>

<script lang="ts">
 export default {
    name:'watch'
 }

</script>
<script lang="ts" setup >
    import { ref,watch } from "vue";
    let sum=ref(1)
    function addsum(){
      sum.value =sum.value+1
    }
    // 情况一:监视ref定义的基本类型
    let stopWatch=watch(sum,(newvalue,oldvalue)=>{
      console.log(newvalue,oldvalue)
      if(newvalue>=10){
        stopWatch()//结束监视
      }
    })
</script>

情况二.监听ref定义的对象类型数据

·若修改的是 ref 定义的对象中的属性, newValue 和 oldValue 都是新值,因为它们是同一个对象。(person.value.name+="~"


.若修改整个 ref 定义的对象, newValue 是新值, oldValue 是旧值,因为不是同一个对象了。( person.value={name:'张三222',age:118} //地址值发生了变化

<template>
  
    <div>
      情况二:监视ref定义的对象类型
        <p> 姓名:{{ person.name}}</p>
        <p> 年龄:{{person.age}}</p>
        <button @click="changename">改变姓名</button>
        <button @click="changeage">改变年龄</button>
        <button @click="changeperson">改变person</button>
    </div>
    

  </div>
</template> 
<script lang="ts" setup >
// 情况二:监视ref定义的对象类型
 let person=ref({name:'张三',age:18})
function changename(){
  person.value.name+="~"  
}
function changeage(){
  person.value.age+=1
}
function changeperson(){
  // person.value.name+="~"
  // person.value.age+=1
  person.value={name:'张三222',age:118} //地址值发生了变化
}
watch(person,(newvalue,oldvalue)=>{
  // 此时监视的是地址值的变化(changeage(),changename()person无变化),
// 若想监视对象内部属性的变化,要开启深度监视
  console.log("person改变了",newvalue,oldvalue)
})
watch(person,(newvalue,oldvalue)=>{

// 若想监视对象内部属性的变化,要开启深度监视
  console.log("person改变了",newvalue,oldvalue)
},{deep:true})
</script>

情况三:监视reactive定义的对象数据类型  地址值没有发生变化,所以newvalue和oldvalue值一样

 监视reactive定义的对象类型:默认开启深度监视,隐式的创建一个深层的监听,且关不掉

<div>
      情况三:监视reactive定义的对象类型
        <p> 姓名:{{ person.name}}</p>
        <p> 年龄:{{person.age}}</p>
        <button @click="changename">改变姓名</button>
        <button @click="changeage">改变年龄</button>
        <button @click="changeperson">改变person</button>
    </div>

 

// 情况三:监视reactive定义的对象类型
 let person3=reactive({name:'张三',age:18})
function changename3(){
  person3.name+="~"  
}
function changeage3(){
  person3.age+=1
}
function changeperson3(){
 Object.assign(person3,{name:'张三222',age:118})//把相同的属性值赋值给person3

  
}

watch(person3,(newvalue,oldvalue)=>{
//三个方法person3都发生了改变
// 监视reactive定义的对象类型:默认开启深度监视,隐式的创建,且关不掉
  console.log("person改变了",newvalue,oldvalue)
})

*情况四
监视 ref 或 reactive 定义的【对象类型】数据中的某个属性,注意点如下:
1.若该属性值不是【对象类型】(如person4.age)且是基本类型,需要写成函数形式。
2.若该属性值是依然是【对象类型】,可直接写watch(()=>{ person4.car},(newvalue,oldvalue)=>{}(不完美),也可写成函数,不过建议写成函数(不完美)。

结论:监视的要是对象里的属性,最好写函数式,若监视的是地址性的改变,最好手动都开启{deep:true}(ref或者reactive)

let person4=reactive({
  name:"zhangsan",
  age:18,
  car:{
    brand:"奥迪",
    peice:100
  }
})

watch(()=>{return person4.age},(newvalue,oldvalue)=>{
  console.log("person改变了",newvalue,oldvalue)
})

watch(()=>{return person4.car},(newvalue,oldvalue)=>{
  console.log("person改变了",newvalue,oldvalue)
},{deep:true})

*情况五

 监视上述多种数据

let person4=reactive({
  name:"zhangsan",
  age:18,
  car:{
    brand:"奥迪",
    peice:100
  }
})


watch([()=>{return person4.age},()=>{return person4.name}],(newvalue,oldvalue)=>{
  console.log("person改变了",newvalue,oldvalue)
},{deep:true})

6.watchEffect

   watch:要明确指出检测的数据;

   watchEffect:不用明确指出检测的数据;

     

let temp=ref(20)
let hei=ref(30)
watchEffect(()=>{
  if(temp.value>50||hei.value>80){  
    console.log("调用服务器")
  }
})
 7.标签的ref属性+子传父

        用在普通的dom标签上,获取的是dom节点

        用在组件标签上,获取的是组件实例对象

 1.用在普通的dom标签上,获取的是dom节点

<template>
  <div class="greetings">
    <p>1111 </p>
    <p ref="title">2222 </p>
    <button @click="showtitle">出现ref的内容</button>
  </div>
</template>
<script  lang="ts" setup>
import {ref} from "vue"
// 用于存储ref标记的内容,名字和ref里面的名字一致
 let title=ref()
 function showtitle(){
  console.log(title.value)
 }
</script>
<style scoped>
</style>

2.用在组件标签上,获取的是组件实例对象

//父
<script  lang="ts" setup>
import person from './components/person.vue';
import {ref} from 'vue'
let ren=ref()
function showren(){
  console.log(ren.value,ren.value.a,ren.value.b,ren.value.c)
}
</script>

<template>
  <header>
    <div class="wrapper">
      <button @click="showren">showren</button>
      <person ref="ren"/>
    </div>
  </header>
</template>

//子
<template>
  <div class="greetings">
  </div>
</template>
<script lang="ts">
    export default {
      name:'person'
    }
</script>
<script  lang="ts" setup>
import {ref,defineExpose} from "vue"


 let a=ref(1);
 let b=ref(2);
 let c=ref(3);
 defineExpose({a,b,c})
</script>
<style scoped>
</style>

 8.defineProps父传子

<template>
  <header>
    <div class="wrapper">
     <person4  a="哈哈" :listperson="person"/>    
    </div>
  </header>
</template>


<script  lang="ts" setup>
import person4 from './components/person4.vue';
// @ts-ignore
import {person} from '@src/type'
import {ref,reactive} from 'vue'
let person=reactive<person>([])

</script>

<template>
  <div class="greetings">
    <ul>
      <li v-for="item in propsValue.listperson" :key="item.id">
      {{ item.name }}--{{item.age}}
      </li>
    </ul>
  </div>
</template>
<script lang="ts">
    export default {
      name:'person4'
    }
</script>
<script  lang="ts" setup>
import { defineProps ,withDefaults} from 'vue'; 
// @ts-ignore
import { person } from '@src/type'; 
// 接受所有
// let propsValue=defineProps(["a","listperson"])

// 接收listperson  +  限制类型
// let propsValue=defineProps<{listperson:person}>()

// 接收listperson  +  限制类型  +   限制必要性  +   指定默认值
//父级不传listperson,设置默认值
let propsValue=withDefaults(defineProps<{listperson?:person}>(),{
  listperson:()=>[{id:'1',name:"默认",age:0}]
})
</script>

 9.生命周期

vue 2

  • beforeCreate 
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestory(不用的时候销毁  <person v-if="isshow">  isshow为false )
  • destroyed

vue 3

除了这些函数 vue3 还增加了些生命周期,可以直接导入 onXXX 一族的函数来注册生命周期钩子:与 2.x 版本生命周期相对应的组合式 API。

1、beforeCreate -> 使用 setup()

2、created -> 使用 setup()

3、beforeMount -> onBeforeMount

4、mounted -> onMounted

5、beforeUpdate -> onBeforeUpdate

6、updated -> onUpdated

7、beforeDestroy -> onBeforeUnmount(卸载前)

8、destroyed -> onUnmounted

9、errorCaptured -> onErrorCaptured

创建   setup()

挂载  onBeforeMount  onMounted

更新  onBeforeUpdate  onUpdated

卸载 onBeforeUnmount  onUnmounted

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值