Vue3学习笔记(待更)

Vue

  • 创建Vue工程:
    • 基于Vite创建

      • npm create vue
        
    • 打开env.d.ts文件,如果提示错误,就要安装依赖,打开终端

      • npm i
        
  • Vite项目中,index.html是项目的入口文件,在项目的最外层

  • 加载index.html后,Vite解析>指向的JavaScript

  • Vue3是通过createApp函数创建的一个实例应用

  • 语法
    • Vue2的API是Option(配置)风格

      • Options API的弊端:

        Options类型,数据,方法,计算属性是分散在data,methods,computed中的,若想修改或新增需求,就需要分别修改data,methods,computed,不便于维护和复印

    • Vue3的API是Composition(组合)风格

      • Composition API的优势:

        可以用函数的方式,更加优雅的组织代码,让相关功能的代码更加有序的组织在一起

    • setup
      • setup是Vue3中的一个新配置项,组件中所用到的数据,方法,计算属性,监视均配置在setup中

      • setup(){
              console.log(this) //setup中的this是undefined,Vue3在弱化this了
              // 数据,原来是写在data中的,此时的name、age、tel都不是响应式的数据
              let name = '张三'
              let age = 18
              let tel = '13888888888'
              
              // 方法
              function changeName() {
                name = 'zhang-san' //注意:这样修改name,页面是没有变化的
                console.log(name) //name确实改了,但name不是响应式的
              }
              function changeAge() {
                age += 1 //注意:这样修改age,页面是没有变化的
                console.log(age) //age确实改了,但age不是响应式的
              }
              function showTel() {
                alert(tel)
              }
         
              // 将数据、方法交出去,模板中才可以使用
              return {name,age,tel,changeName,changeAge,showTel}
            }
        
      • setup函数返回的对象中的内容,可直接在模板中使用

      • setup中访问this是undefined

      • setup函数会在beforeCreate之前调用,它是领先所有钩子执行

      • setup的返回值:

        • 若返回一个对象:则对象中的:属性,方法等,在模板中均可以直接使用,如

          setup(){
          	return {name,age,changname,showid}
          }
          
        • 若返回一个函数:则可以自定义渲染内容,如

          setup(){
          	return ()=>"世间你好"
          }
          
      • setup语法糖;

        <template>
          <div class="person">
            <h2>姓名:{{name}}</h2>
            <h2>年龄:{{age}}</h2>
            <button @click="changName">修改名字</button>
            <button @click="changAge">年龄+1</button>
            <button @click="showTel">点我查看联系方式</button>
          </div>
        </template>
         
        <script lang="ts">
          export default {
            name:'Person',
          }
        </script>
         
        <!-- 下面的写法是setup语法糖 -->
        <script setup lang="ts">
          console.log(this) //undefined
          
          // 数据(注意:此时的name、age、tel都不是响应式数据)
          let name = '张三'
          let age = 18
          let tel = '13888888888'
         
          // 方法
          function changName(){
            name = '李四'//注意:此时这么修改name页面是不变化的
          }
          function changAge(){
            console.log(age)
            age += 1 //注意:此时这么修改age页面是不变化的
          }
          function showTel(){
            alert(tel)
          }
        </script>
        
        • 指定组件名字的script标签也可以不写,借助vite的插件简化

          • 在终端中`npm i vite-plugin-vue-setup-extend -D

          • 打开vite.config.ts文件,改为

            • import { defineConfig } from 'vite'
              import VueSetupExtend from 'vite-plugin-vue-setup-extend'
               
              export default defineConfig({
                plugins: [ VueSetupExtend() ]
              })
              
          • 以后就只用写一个script

            <script setup lang="ts" name="xxxx"></script>
            
      • ref 创建:基本类型的响应式数据

        • <template>
            <div class="person">
              <h2>姓名:{{name}}</h2>
              <h2>年龄:{{age}}</h2>
              <button @click="changeName">修改名字</button>
              <button @click="changeAge">年龄+1</button>
              <button @click="showTel">点我查看联系方式</button>
            </div>
          </template>
           
          <script setup lang="ts" name="Person">
            import {ref} from 'vue'
             // name和age是一个RefImpl的实例对象,简称ref对象,它们的value属性是响应式的。
            let name = ref('张三')
            let age = ref(18)
            // tel就是一个普通的字符串,不是响应式的
            let tel = '13888888888'
           
            function changeName(){
              // JS中操作ref对象时候需要.value
              name.value = '李四'
              console.log(name.value)
           
              // 注意:name不是响应式的,name.value是响应式的,所以如下代码并不会引起页面的更新。
              // name = ref('zhang-san')
            }
            function changeAge(){
              // JS中操作ref对象时候需要.value
              age.value += 1 
              console.log(age.value)
            }
            function showTel(){
              alert(tel)
            }
          </script>
          
      • reactive 创建对象类型的响应式数据
        • <template>
            <div class="person">
              <h2>汽车信息:一台{{ car.brand }}汽车,价值{{ car.price }}万</h2>
              <h2>游戏列表:</h2>
              <ul>
                <li v-for="g in games" :key="g.id">{{ g.name }}</li>
              </ul>
              <h2>测试:{{obj.a.b.c.d}}</h2>
              <button @click="changeCarPrice">修改汽车价格</button>
              <button @click="changeFirstGame">修改第一游戏</button>
              <button @click="test">测试</button>
            </div>
          </template>
           
          <script lang="ts" setup name="Person">
          import { reactive } from 'vue'
           
          // 数据
          let car = reactive({ brand: '奔驰', price: 100 })
          let games = reactive([
            { id: 'ahsgdyfa01', name: '英雄联盟' },
            { id: 'ahsgdyfa02', name: '王者荣耀' },
            { id: 'ahsgdyfa03', name: '原神' }
          ])
          let obj = reactive({
            a:{
              b:{
                c:{
                  d:666
                }
              }
            }
          })
           
          function changeCarPrice() {
            car.price += 10
          }
          function changeFirstGame() {
            games[0].name = '流星蝴蝶剑'
          }
          function test(){
            obj.a.b.c.d = 999
          }
          </script>
          
      • ref 对比reactive
        • ref用来定义:基本类型数据,对象类型数据
        • reactive用来定义:基本对象类型数据
        • ref创建的变量必须使用.value(可以用volar插件)
        • reactive重新分配一个新对象,会失去响应式(可以用Object.assign整体替代)
      • toRefs和toRef
        • <template>
            <div class="person">
              <h2>姓名:{{person.name}}</h2>
              <h2>年龄:{{person.age}}</h2>
              <h2>性别:{{person.gender}}</h2>
              <button @click="changeName">修改名字</button>
              <button @click="changeAge">修改年龄</button>
              <button @click="changeGender">修改性别</button>
            </div>
          </template>
           
          <script lang="ts" setup name="Person">
            import {ref,reactive,toRefs,toRef} from 'vue'
           
            // 数据
            let person = reactive({name:'张三', age:18, gender:'男'})
          	
            // 通过toRefs将person对象中的n个属性批量取出,且依然保持响应式的能力
            let {name,gender} =  toRefs(person)
          	
            // 通过toRef将person对象中的gender属性取出,且依然保持响应式的能力
            let age = toRef(person,'age')
           
            // 方法
            function changeName(){
              name.value += '~'
            }
            function changeAge(){
              age.value += 1
            }
            function changeGender(){
              gender.value = '女'
            }
          </script>
          
      • computer计算属性:
        • 根据已有数据计算出新数据

        • 底层借助了object.defineproperty方法提供的getter和setter方法

        • <template>
            <div class="person">
              姓:<input type="text" v-model="firstName"> <br>
              名:<input type="text" v-model="lastName"> <br>
              全名:<span>{{fullName}}</span> <br>
              <button @click="changeFullName">全名改为:li-si</button>
            </div>
          </template>
           
          <script setup lang="ts" name="App">
            import {ref,computed} from 'vue'
           
            let firstName = ref('zhang')
            let lastName = ref('san')
           
            // 计算属性——只读取,不修改
            /* let fullName = computed(()=>{
              return firstName.value + '-' + lastName.value
            }) */
           
           
            // 计算属性——既读取又修改
            let fullName = computed({
              // 读取
              get(){
                return firstName.value + '-' + lastName.value
              },
              // 修改
              set(val){
                console.log('有人修改了fullName',val)
                firstName.value = val.split('-')[0]
                lastName.value = val.split('-')[1]
              }
            })
           
            function changeFullName(){
              fullName.value = 'li-si'
            } 
          </script>
          
      • watch监听:
        • 监听:监视数据的变化

        • 情况一:
          • <template>
              <div class="person">
                <h1>情况一:监视【ref】定义的【基本类型】数据</h1>
                <h2>当前求和为:{{sum}}</h2>
                <button @click="changeSum">点我sum+1</button>
              </div>
            </template>
             
            <script lang="ts" setup name="Person">
              import {ref,watch} from 'vue'
              // 数据
              let sum = ref(0)
              // 方法
              function changeSum(){
                sum.value += 1
              }
              // 监视,情况一:监视【ref】定义的【基本类型】数据
              const stopWatch = watch(sum,(newValue,oldValue)=>{  //不写sum.value,因为sum才是ref定义的数据。而不是sum.value
                console.log('sum变化了',newValue,oldValue)
                if(newValue >= 10){
                  stopWatch()  //回调一个停止监视的函数,此处是当newValue>10时,停止监视。
                }
              })
            </script>
            
        • 情况二:
          • <template>
              <div class="person">
                <h1>情况二:监视【ref】定义的【对象类型】数据</h1>
                <h2>姓名:{{ person.name }}</h2>
                <h2>年龄:{{ person.age }}</h2>
                <button @click="changeName">修改名字</button>
                <button @click="changeAge">修改年龄</button>
                <button @click="changePerson">修改整个人</button>
              </div>
            </template>
             
            <script lang="ts" setup name="Person">
              import {ref,watch} from 'vue'
              // 数据
              let person = ref({
                name:'张三',
                age:18
              })
              // 方法
              function changeName(){
                person.value.name += '~'
              }
              function changeAge(){
                person.value.age += 1
              }
              function changePerson(){
                person.value = {name:'李四',age:90}
              }
              /* 
                监视,情况一:监视【ref】定义的【对象类型】数据,监视的是对象的地址值,只有整个对象被改变的时候才会被监视到。
                若想监视对象内部属性的变化,需要手动开启深度监视
                watch的第一个参数是:被监视的数据
                watch的第二个参数是:监视的回调
                watch的第三个参数是:配置对象(deep、immediate等等.....) 
              */
              watch(person,(newValue,oldValue)=>{
                console.log('person变化了',newValue,oldValue)
              },{deep:true})
              
            </script>
            
        • 情况三:
          • <template>
              <div class="person">
                <h1>情况三:监视【reactive】定义的【对象类型】数据</h1>
                <h2>姓名:{{ person.name }}</h2>
                <h2>年龄:{{ person.age }}</h2>
                <button @click="changeName">修改名字</button>
                <button @click="changeAge">修改年龄</button>
                <button @click="changePerson">修改整个人</button>
                <hr>
                <h2>测试:{{obj.a.b.c}}</h2>
                <button @click="test">修改obj.a.b.c</button>
              </div>
            </template>
             
            <script lang="ts" setup name="Person">
              import {reactive,watch} from 'vue'
              // 数据
              let person = reactive({
                name:'张三',
                age:18
              })
              let obj = reactive({
                a:{
                  b:{
                    c:666
                  }
                }
              })
              // 方法
              function changeName(){
                person.name += '~'
              }
              function changeAge(){
                person.age += 1
              }
              function changePerson(){
                Object.assign(person,{name:'李四',age:80})
              }
              function test(){
                obj.a.b.c = 888
              }
             
              // 监视,情况三:监视【reactive】定义的【对象类型】数据,且默认是开启深度监视的
              watch(person,(newValue,oldValue)=>{
                console.log('person变化了',newValue,oldValue)
              })
              watch(obj,(newValue,oldValue)=>{
                console.log('Obj变化了',newValue,oldValue)
              })
              
            </script>
            
        • 情况四:
          • <template>
              <div class="person">
                <h1>情况四:监视【ref】或【reactive】定义的【对象类型】数据中的某个属性</h1>
                <h2>姓名:{{ person.name }}</h2>
                <h2>年龄:{{ person.age }}</h2>
                <h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>
                <button @click="changeName">修改名字</button>
                <button @click="changeAge">修改年龄</button>
                <button @click="changeC1">修改第一台车</button>
                <button @click="changeC2">修改第二台车</button>
                <button @click="changeCar">修改整个车</button>
              </div>
            </template>
             
            <script lang="ts" setup name="Person">
              import {reactive,watch} from 'vue'
             
              // 数据
              let person = reactive({
                name:'张三',
                age:18,
                car:{
                  c1:'奔驰',
                  c2:'宝马'
                }
              })
              // 方法
              function changeName(){
                person.name += '~'
              }
              function changeAge(){
                person.age += 1
              }
              function changeC1(){
                person.car.c1 = '奥迪'
              }
              function changeC2(){
                person.car.c2 = '大众'
              }
              function changeCar(){
                person.car = {c1:'雅迪',c2:'爱玛'}
              }
             
              // 监视,情况四:监视响应式对象中的某个属性,且该属性是基本类型的,要写成函数式
              /* watch(()=> person.name,(newValue,oldValue)=>{
                console.log('person.name变化了',newValue,oldValue)
              }) */
             
              // 监视,情况四:监视响应式对象中的某个属性,且该属性是对象类型的,可以直接写,也能写函数,更推荐写函数
              watch(()=>person.car,(newValue,oldValue)=>{
                console.log('person.car变化了',newValue,oldValue)
              },{deep:true})
             
            </script>
            
        • 情况五:
          • 
              <div class="person">
                <h1>情况五:监视上述的多个数据</h1>
                <h2>姓名:{{ person.name }}</h2>
                <h2>年龄:{{ person.age }}</h2>
                <h2>汽车:{{ person.car.c1 }}、{{ person.car.c2 }}</h2>
                <button @click="changeName">修改名字</button>
                <button @click="changeAge">修改年龄</button>
                <button @click="changeC1">修改第一台车</button>
                <button @click="changeC2">修改第二台车</button>
                <button @click="changeCar">修改整个车</button>
              </div>
            </template>
             
            <script lang="ts" setup name="Person">
              import {reactive,watch} from 'vue'
             
              // 数据
              let person = reactive({
                name:'张三',
                age:18,
                car:{
                  c1:'奔驰',
                  c2:'宝马'
                }
              })
              // 方法
              function changeName(){
                person.name += '~'
              }
              function changeAge(){
                person.age += 1
              }
              function changeC1(){
                person.car.c1 = '奥迪'
              }
              function changeC2(){
                person.car.c2 = '大众'
              }
              function changeCar(){
                person.car = {c1:'雅迪',c2:'爱玛'}
              }
             
              // 监视,情况五:监视上述的多个数据
              watch([()=>person.name,person.car],(newValue,oldValue)=>{
                console.log('person.car变化了',newValue,oldValue)
              },{deep:true})
             
            </script>
            
  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值