Vue3 基础记录

Vue3

创建

基于vue-cli

bash 复制代码
## 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue --version

## 安装或者升级你的@vue/cli 
npm install -g @vue/cli

## 执行创建命令
vue create vue_test

##  随后选择3.x
##  Choose a version of Vue.js that you want to start the project with (Use arrow keys)
##  > 3.x
##    2.x

## 启动
cd vue_test
npm run serve

基于Vite

bash 复制代码
## 1.创建命令
npm create vue@latest

## 2.具体配置
## 配置项目名称
√ Project name: vue3_test
## 是否添加TypeScript支持
√ Add TypeScript?  Yes
## 是否添加JSX支持
√ Add JSX Support?  No
## 是否添加路由环境
√ Add Vue Router for Single Page Application development?  No
## 是否添加pinia环境
√ Add Pinia for state management?  No
## 是否添加单元测试
√ Add Vitest for Unit Testing?  No
## 是否添加端到端测试方案
√ Add an End-to-End Testing Solution? >> No
## 是否添加ESLint语法检查
√ Add ESLint for code quality?  Yes
## 是否添加Prettiert代码格式化
√ Add Prettier for code formatting?  No

文件结构

main.js

bash 复制代码
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

createApp(App) 返回的变量就是轻量的vm,并且很多方法不带$

vue3中template中,不用再写根div了

setup

bash 复制代码
<template>
  <div>
    <h2>hhh</h2>
    <button @click="sayHello">点击</button>
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {
  },
  setup() {
    let name = 'jjking';

    function sayHello() {
      alert('Hello' + name);
    }

    return {  
      name,sayHello
    }
  }
}
</script>

<style></style>

setup函数返回的对象中的内容,可以在模版中直接使用

setup中this访问是undefined

setup函数会在beforeCreate之前调用

setup返回值,如果是一个渲染函数,则可以自定义渲染内容

这个东西,就是vue2中的main.js中的那个渲染函数

bash 复制代码
<template>
  <div>
    <h2>hhh</h2>
    <button @click="sayHello">点击</button>
  </div>
</template>

<script>
import { h } from 'vue';


export default {
  name: 'App',
  components: {
  },
  setup() {
    let name = 'jjking';

    function sayHello() {
      alert('Hello' + name);
    }

    // return {  
    //   name,sayHello
    // }

    return () => h('h1','jjking'); 
  }
}
</script>

<style></style>

不管你写什么,都会渲染成h1

  • setup的参数
    • props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。
    • context:上下文对象
      • attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性, 相当于 this.$attrs。
      • slots: 收到的插槽内容, 相当于 this.$slots。
      • emit: 分发自定义事件的函数, 相当于 this.$emit。

ref

基本数据类型

使用ref包裹的返回的对象

是一个响应式的对象,如果要修改ref中的对象,需要修改value,而不是直接改

并且,看这个对象,是在原型对象中有get,set方法,有点类似于vue2的_data里边的数据

模版字符串{{}}里边不用.value的原因是,模版字符串会自动加上.value

bash 复制代码
<template>
  <div>
    <h2>{{name}}</h2>
    <button @click="change">点击change</button>
  </div>
</template>
<script>
import { ref } from 'vue';

export default {
  name: 'App',
  components: {
  },
  setup() {
    let name = ref('jjking');
    function change() {
      console.log(name);
      name.value = '改变后';
    }
    return {  
      name,change
    }
  }
}
</script>

对象数据类型

bash 复制代码
  setup() {
    let job = ref({
      type:'前端工程师',
      salary: 30
    })

    function changeSalary() {
      console.log(job);
      job.value.salary = 40;
    }

    return {  
      name,job,changeSalary
    }
  }

我们打印可以看到他实际上是Proxy对象,他的响应式是借助了Vue3中的 新函数,reactive函数

我们更改的话,就如上代码

reactive

一般用于对象和数组,基本类型用ref,不然报错

返回值是Proxy对象,且reactive定义的是深层次的响应式对象

注意,如果reavtive重新分配一个新对象,会失去响应式,必须用Object.assign来做整体的替换

bash 复制代码
<template>
  <div class="person">
    <h2>汽车信息:一辆{{car.brand}}车,价值{{car.price}}万</h2>
    <button @click="changeBrand">修改汽车的品牌</button>
    <button @click="changePrice">修改汽车的价格</button>
    <button @click="changeCar">修改汽车</button>
    <hr>
    <h2>当前求和为:{{sum}}</h2>
    <button @click="changeSum">点我sum+1</button>
  </div>
</template>

<script lang="ts" setup name="Person">
  import {ref,reactive} from 'vue'

  // 数据
  let car = reactive({brand:'奔驰',price:100})
  let sum = ref(0)

  // 方法
  function changeBrand(){
    car.brand = '宝马'
  }
  function changePrice(){
    car.price += 10
  }
  function changeCar(){
    // car = {brand:'奥拓',price:1} //这么写页面不更新的
    // car = reactive({brand:'奥拓',price:1}) //这么写页面不更新的

    // 下面这个写法页面可以更新
    Object.assign(car,{brand:'奥拓',price:1})
  }
  function changeSum(){
    // sum = ref(9) //这么写页面不更新的
    sum.value += 1
  }
</script>

Vue3中的响应式原理

Vue2中,如果我们想修改对象或者数组中的数据,Vue是不会监测变化的,换句话说,也就是响应式没用,我们新增属性,删除属性,修改数组中的值

实现原理

通过Proxy代理对象

Proxy和Object.defineProperty很类似,不过他添加了删除属性,和追加属性的方法

追加属性的方法集成到了set方法里边

为什么要用Reflect呢,就是因为Reflect操作对象可以返回布尔值,如果像之前那样修改代码的话,报错是直接抛出的,我们必须用try catch来捕获

computed函数

bash 复制代码
import {computed} from 'vue'

setup(){
    ...
	//计算属性------简写
    let fullName = computed(()=>{
        return person.firstName + '-' + person.lastName
    })
    //计算属性------完整
    let fullName = computed({
        get(){
            return person.firstName + '-' + person.lastName
        },
        set(value){
            const nameArr = value.split('-')
            person.firstName = nameArr[0]
            person.lastName = nameArr[1]
        }
    })
}

watch

bash 复制代码
//情况一:监视ref定义的响应式数据
watch(sum,(newValue,oldValue)=>{
	console.log('sum变化了',newValue,oldValue)
},{immediate:true})

//情况二:监视多个ref定义的响应式数据
watch([sum,msg],(newValue,oldValue)=>{
	console.log('sum或msg变化了',newValue,oldValue)
}) 

/* 情况三:监视reactive定义的响应式数据
			若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue!!
			若watch监视的是reactive定义的响应式数据,则强制开启了深度监视 
*/
watch(person,(newValue,oldValue)=>{
	console.log('person变化了',newValue,oldValue)
},{immediate:true,deep:false}) //此处的deep配置不再奏效

//情况四:监视reactive定义的响应式数据中的某个属性
watch(()=>person.job,(newValue,oldValue)=>{
	console.log('person的job变化了',newValue,oldValue)
},{immediate:true,deep:true}) 

//情况五:监视reactive定义的响应式数据中的某些属性
watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
	console.log('person的job变化了',newValue,oldValue)
},{immediate:true,deep:true})

//特殊情况
watch(()=>person.job,(newValue,oldValue)=>{
    console.log('person的job变化了',newValue,oldValue)
},{deep:true}) //此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效

监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)。

watchEffect

  • watch的套路是:既要指明监视的属性,也要指明监视的回调。

  • watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。

  • watchEffect有点像computed:

    • 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
    • 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。
bash 复制代码
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
watchEffect(()=>{
    const x1 = sum.value
    const x2 = person.age
    console.log('watchEffect配置的回调执行了')
})

生命 周期钩子

  • ue3.0中可以继续使用Vue2.x中的生命周期钩子,但有有两个被更名:
    • beforeDestroy改名为 beforeUnmount
    • destroyed改名为 unmounted
  • Vue3.0也提供了 Composition API 形式的生命周期钩子,与Vue2.x中钩子对应关系如下:
    • beforeCreate===>setup()
    • created=======>setup()
    • beforeMount ===>onBeforeMount
    • mounted=======>onMounted
    • beforeUpdate===>onBeforeUpdate
    • updated =======>onUpdated
    • beforeUnmount ==>onBeforeUnmount

自定义钩子

  • 什么是hook?------ 本质是一个函数,把setup函数中使用的Composition API进行了封装。

  • 类似于vue2.x中的mixin。

  • 自定义hook的优势: 复用代码, 让setup中的逻辑更清楚易懂。

就是封装一个函数,为了复用

toRefs toRef

bash 复制代码
<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>

toRef有点类似于,桥接,他指向的还是源数据,只不过他为了少写点代码

相关推荐
用户461169657285 分钟前
网站 HTTPS 不稳定?证书排查指南
前端
n876517 分钟前
Playwright Java WEB UI 自动化实现框架与逻辑
java·前端·ui
keyipatience19 分钟前
TypeScript学习(1)
前端·javascript·学习·typescript·html·css3
xifangge20251 小时前
基于 JavaScript 实现 CNC 数控切削参数与螺纹公差纯前端核算引擎
开发语言·前端·javascript
wangruofeng1 小时前
2026 Web 技术选型指南,AI 时代如何选择适合项目的技术栈
前端·aigc·ai编程
honkun61 小时前
vue 表格组件 vxe-table 修改滚动条样式,修改滚动条样式,统一宽度、颜色与自动隐藏
前端·javascript·vue.js
爱勇宝2 小时前
研究数字孪生的这半年,做了个 Demo,也有了一些新想法
前端·程序员
不可能片场2 小时前
工程实践 一个缓存把选片从十分钟压到一分钟
前端·electron
前端小万2 小时前
探索副业五个月,最终以放弃告终
前端·后端·面试
FRing032 小时前
JavaScript入门到精通二十四(正则表达式、元字符、修饰符)
开发语言·前端·javascript·正则表达式