初识vue3-setup语法糖,ref和reactive语法,computde计算属性,watch开启监听

发布时间 2023-03-25 17:51:47作者: 帅气丶汪星人

vue3和vue2的区别

1,vue3首次渲染更快(Vue3在编译和渲染性能上有了很大的提升,主要是因为使用了Proxy代理和优化算法,使得组件可以更快的渲染)

2,diff算法更快

3,内存占用体积变得更小

4,打包体积变得更小

5,更好的ts支持(这里不是因为vue3是ts写的,所以更加支持ts,是因为Vue3对TS的支持更加完善了,包括更好的类型推断和类型定义)

6,Composition  API(vue3中引入了Composition API,他是一种新的组合式API,可以帮助我们更好的组织和复用逻辑代码,而不是像Vue2那样只能使用Options API)

vite和传统的webpack的区别

1,构建速度(vite的构建速度比webpack快很多,因为Vite使用了ES Modules来实现快速的热更新,也就是支持热加载。webpack则需要每次修改代码之后重新打包整个应用。这样每次保存看效果很麻烦)

2,开发体验(vite提供了一种更加流畅的开发体验,因为它可以在浏览器中直接运行代码,而不需要重新打包整个应用,开发很舒服)

3,配置(vite配置非常简单,因为它使用了约定优于配置的原则。相比之下webpack的配置比较复杂,需要花费一定时间学习配置)

4,插件生态(webpack插件生态比vite更加丰富,因为webpack存在时间,非常的长了。但是vite发展非常壮大)

webpack先打包然后启动服务器

vit会提供一个服务器,立即启动,然后打包,支持热更新,打包使用Rollup

使用vite创建vue3的项目

$ npm create vite@latest
$ yarn create vite
$ pnpm create vite

Project name: ... vite-dome1,项目名称

Select a framework: » Vue 创建名称

Select a variant: » JavaScript 使用语言

cd vite-dome1 //进入项目
npm i //装包
npm run dev //启动项目

type='module'绑定es6的代码和模板

 学习vue3语法

创建完成项目之后开始学习vue3的语法

setup函数

setup是vue3特有的选项,作为API的起点

从组件的生命周期来看,他在beforCreate之前执行,函数this不是组件实例,是undefined,如果数据或者函数在模板中使用,需要使用setup进行返回

<script>
import { ref } from 'vue'
export default {
  name: 'App',
  /**
   * 这里是组合式APi入口,比beforeCreate执行更早
   * vue3中没有this组件实例,所以在这里可以直接使用ref
   */
  setup() {
    const show = ref(true)
    const toggie = () => {
      show.value = !show.value
    }
    return { show, toggie }
  },
  beforeCreate() {
    console.log(`beforeCreate`)
  }
}
</script>
<template> <div> <button @click="toggie">点击显示或者隐藏图片</button> <hr> <img src="" alt="暂无图片" v-show="show"> </div> </template> <style scoped> </style>

setup语法糖

setup函数每次会有一个返回值,每次还要创建一个函数,太麻烦了,所以vue3提供了setup语法糖。

<script setup>
import { ref } from 'vue'
    const show = ref(true)
    const toggie = () => {
      show.value = !show.value
    }
</script>

<template>
  <div>
    <button @click="toggie">点击显示或者隐藏图片</button>
    <hr>
    <img src="" alt="暂无图片" v-show="show">
  </div>
</template>

<style scoped>

</style>

这样我们不需要定义setup函数,不需要返回值,不需要export default

ref函数--简单数据类型响应式

在setup函数中,使用ref函数,传入普通数据(简单or复杂)返回一个响应式数据

<script setup>
import { ref } from 'vue'
const num = ref(0)
const add = () => {
  num.value++
}
const obj = ref({
  name: 'zhangsan',
  age: 18
})
const change = () => {
  obj.value.name = 'lisi'
}
</script>

<template>
  <div>
    <h1>{{ num }}</h1>
    <button @click="add">add</button>
    <h1>{{ obj.name }}</h1>
    <button @click="change">change</button>
  </div>
</template>

<style scoped>

</style>

注意点:使用ref创建数据,js中的.value,template可以省略

reactive函数--复杂数据类型响应式

通常使用它定义对象类型的响应式数据

vue2中data函数中返回的对象数据是一个响应式数据,现在setup中返回的对象数据是响应式数据吗?

不是的,需要使用reactive进行转换

在setup函数中,使用reactive函数,传入一个普通对象,返回一个响应式数据对象,最后在setup函数中返回一个对象。

reactive函数通常定义:复杂数据类型,可以转换普通数据类型吗?不能

<script setup>
import {  reactive } from 'vue'
const state = reactive({
  name: `王路飞`,
  age: 18
})
const changeName = () => {
  state.name = `路飞`
}
// const name = reactive(`王路飞`) // reactive不能将基本类型转换为响应式数据
// const age = reactive(18)
// let changeName = () => {
//   name = `路飞` // 会报错,因为name是只读的
// }
</script>

<template>
<div>
  <h1>{{ state.name }}</h1>
  <h1>{{ state.age }}</h1>
  <button @click="changeName">改名</button>
</div>
</template>

<style scoped>

</style>

注意点:reactive不能转换普通数据类型为响应式数据

reactive和ref的选择

reactive可以转换对象成为响应式数据对象,但是不支持简单数据类型

ref可以转换简单数据类型为响应式数据对象,也可以支持复杂数据类型,但是操作的时候需要使用到.value

如果确定数据类型是对象,且字段和名称也确定,可以使用reactive转换成响应式数据,其他都使用ref,这样就没有心里负担

computed函数--计算属性

在setup函数中,使用computrd函数,传入一个函数,函数返回计算好的数据

最后setup函数返回一个对象,包含该计算属性数据即可,然后模板内使用

<script setup>
import { ref,computed } from 'vue'
const list = ref([1,2,3,4,5])
// 数据筛选出偶数
const even = computed(() => list.value.filter(n => n % 2 === 0))
// 当数据发生变化的时候
setTimeout(() => {
  list.value.push(6,9)
}, 2000)
</script>

<template>
<div>
  <h1>Vue3 Review</h1>
  <ul>
    <li v-for="item in list" :key="item">{{item}}</li>
  </ul>
  <ul>
    <li v-for="item in even" :key="item">{{item}}</li>
  </ul>
</div>
</template>

<style scoped>

</style>

watch函数--属性侦听器

watch属性侦听器监听数据的变化,使用watch监听一个响应式数据,使用watch监听多个响应式数据,使用watch监听响应式对象数据中一个属性(见到那数据类型),使用watch监听响应式对象数据中一个属性(复杂数据类型)配置深度监听,使用watch监听配置默认执行

使用watch监听一个响应式数据

<script setup>
import { ref,watch,reactive } from 'vue'
const count = ref(0)
// watch监听一个响应式
watch(count,(newVal,oldVal)=>{
  console.log(newVal,oldVal)
})
</script>

<template>
<div>
计数器:{{count}}
<button @click="count++">+</button>
</div>
</template>

<style scoped>

</style>

使用watch监听多个响应式数据

<script setup>
import { ref,watch,reactive } from 'vue'
// watch监听多个响应式
const user = reactive({
  name:`jack`,
  info:{
    age:18,
    gender:`男`
  }
})
// watch监听多个响应式
watch([user],()=>{
  console.log('改变')
  console.log(user.name)
})
</script>

<template>
<div>
名字:{{user.name}}
年龄:{{user.info.age}}
  <button @click="user.name = '路飞'">修改名称</button>
</div>
</template>

<style scoped>

</style>

使用watch监听对象的一个属性,简单数据类型

<script setup>
import { ref,watch,reactive } from 'vue'
const count = ref(0)
const user = reactive({
  name:`jack`,
  info:{
    age:18,
    gender:`男`
  }
})
// 监听对象一个属性,简单类型
watch(()=>user.name,()=>{
  console.log(user.name)
  console.log('user.name改变了')
})
</script>

<template>
<div>
名字:{{user.name}}
  <button @click="user.name = '黑胡子'">修改名称</button>
</div>
</template>

<style scoped>

</style>

使用watch监听对象一个属性,复杂数据类型

<script setup>
import { ref,watch,reactive } from 'vue'
const count = ref(0)
const user = reactive({
  name:`jack`,
  info:{
    age:18,
    gender:`男`
  }
})
// 监听对象一个属性,复杂类型
watch(()=>user.info.age,()=>{
  console.log(user.info.age)
  console.log('user.info.age改变了')
},{
  // 开启深度监听
  deep:true
})
</script>

<template>
<div>
  <button @click="user.info.age = 50">点击修改年龄</button>
</div>
</template>

<style scoped>

</style>

开启默认监听

<script setup>
import { ref,watch,reactive } from 'vue'
const count = ref(0)
const user = reactive({
  name:`jack`,
  info:{
    age:18,
    gender:`男`
  }
})
// 默认执行
watch (count,()=>{
  console.log('默认执行')
},{
  immediate:true
});
</script>

<template>
<div>
  计数器:{{count}}
<button @click="count++">+</button>
  <br>
名字:{{user.name}}
年龄:{{user.info.age}}
  <button @click="user.name = '路飞'">修改名称</button>
  <button @click="user.name = '黑胡子'">修改名称</button>
  <br>
  <button @click="user.info.age = 50">点击修改年龄</button>
</div>
</template>

<style scoped>

</style>

每次数据发生变动都会进行数据的劫持