vue3

一 Vue3的变化

1.性能的提升

  • 打包大小减少41%

  • 初次渲染快55%, 更新渲染快133%

  • 内存减少54%

2、源码的升级

  • 使用Proxy代替defineProperty实现响应式

  • 重写虚拟DOM的实现和Tree-Shaking

3.拥抱TypeScript

Vue3可以更好的支持TypeScript

4.新的特性

1.Composition API(组合API)

  • setup配置
  • ref与reactive
  • watch与watchEffect
  • provide与inject

2.新的内置组件

  • Fragment
  • Teleport
  • Suspense

3.其他改变

  • 新的生命周期钩子
  • data 选项应始终被声明为一个函数
  • 移除keyCode支持作为 v-on 的修饰符

5 组合式API和配置项API

5.1 Options API 存在的问题

使用传统OptionsAPI中,新增或者修改一个需求,就需要分别在data,methods,computed里修改 。

5.2 Composition API 的优势

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

6 项目分析

分析文件目录

main.js

Vue2项目的main.js
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

看看vm是什么

const vm = new Vue({
  render: h => h(App),
})

console.log(vm)

vm.$mount('#app')

我们再来看看Vue3项目中的main.js

import { createApp } from 'vue'
import App from './App.vue'

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

我们来分析一下吧

// 引入的不再是Vue构造函数了,引入的是一个名为createApp的工厂函数
import { createApp } from 'vue'
import App from './App.vue'
// 创建应用实例对象——app(类似于之前Vue2中的vm,但app比vm更“轻”)
const app = createApp(App)
console.log(app)
// 挂载
app.mount('#app')

这里的app到底是啥,我们输出到控制台看看
image

App.vue

我们再来看看组件

在template标签里可以没有根标签了

<template>
	<!-- Vue3组件中的模板结构可以没有根标签 -->
	<img alt="Vue logo" src="./assets/logo.png">
	<HelloWorld msg="Welcome to Your Vue.js App"/>
</template>

二 创建Vue3.0工程

1.使用 vue-cli 创建

官方文档:https://cli.vuejs.org/zh/guide/creating-a-project.html#vue-create

## 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue --version
## 安装或者升级你的@vue/cli
npm install -g @vue/cli
## 创建
vue create vue_test
## 启动
cd vue_test
npm run serve

2.使用 vite 创建

官方文档:https://v3.cn.vuejs.org/guide/installation.html#vite

vite官网:https://vitejs.cn

介绍:https://cn.vitejs.dev/guide/why.html#the-problems

什么是vite?—— 新一代前端构建工具。

优势如下:

  • 开发环境中,无需打包操作,可快速的冷启动。
  • 轻量快速的热重载(HMR)。
  • 真正的按需编译,不再等待整个应用编译完成。

传统构建 与 vite构建对比图

image

创建步骤

image

工具链,构建工具

	-之前咱们再html中写,可能js可以引入
    -可能写了一些 es高版本的语法----》转成低版本
    -可能写  xx.vue,浏览器识别不了,浏览器只能识别:html,css,js
    -咱们需要 有个东西可以一次性把 es高版本转成低版本,把xx.vue 转成xx.js的方式
    -工具链:
    	webpack
        vite

三、setup

setup是个函数,以后vue的代码,都写在这里面
1 里面可以定义变了
2 可以定义函数,可以定义匿名函数
3 如果想在templage中使用,必须return
4 如果要对变量加入响应式,需要使用ref包裹变量
5 data,methods都可以用,但是是setup函数先执行,才走其它
6 template中使用函数,变量,都优先用setup中的
7 setup最先执行,是再生命周期的beforeCreate前执行的,内部没有this,也不能用this了

  1. setup为Vue3.0中一个新的配置项,值为一个函数

  2. setup是所有Composition API(组合API)编写的位置

  3. 组件中所用到的:数据、方法等等,均要配置在setup中

  4. setup函数的返回值:返回一个对象,对象中的属性、方法, 在模板中均可以直接使用

注意:

尽量不要与Vue2.x配置混用

  • Vue2.x配置(data、methos、computed...)中可以访问到setup中的属性、方法。
  • 但在setup中不能访问到Vue2.x配置(data、methos、computed...)。
  • 如果有重名, setup优先。
<template>
  {{name}}--{{age}}--{{xx}}
</template>

<script>

export default {
  name: 'App',
  data(){
    return {
      xx:this.name
    }
  },
  setup(){
    let name='lqz'
    let age =19
    return {
      name,age
    }
  },
}
</script>

四、 ref函数

image

包裹变量,实现响应式

let name = ref('lqz')

<template>
  <div class="home">
    名字是:{{ name }},年龄是:{{ age }},爱好:{{ hobby }}
    <br>
    <button @click="handleAdd">点我涨年龄</button>
    <br>
    <button @click="handleChange">点击变名字</button>
  </div>
</template>

<script>
// 导入ref函数
import {ref} from 'vue'

export default {
  name: 'HomeView',
  // 这样写支持
  data() {
    return {
      // hobby: '篮球'
      hobby: this.name + '爱打篮球'
    }
  },
  methods: {
    handleAdd() {
      console.log('methods中的handleAdd')
    }
  },

  // 以后我们写成这样,
  setup() {
    // 以后所有vue3的代码,都写在这里面
    //原来写在data中定义变量
    // 如果想在view中使用定义的变量,必须retur出去
    // var:老语法     let:以后定义变量用这个    const :定义常量

    // 1 定义变量,并再页面中渲染
    // const name = 'lqz'
    // const age = 19
    // return {name,age}
    // // return {name:name,age:age}


    // 2 定义变量和函数,再页面中使用---->失去了响应式
    // let name = 'lqz'
    // let age = 19
    // const handleAdd = () => {
    //   // alert('我被点了')
    //   // alert(add(4,5))
    //   age = age + 1
    //   console.log(age)
    //
    // }
    //
    // function add(a, b) {
    //   return a + b
    // }
    //
    //
    // return {name, age, handleAdd}


    // 3 加入响应式
    //   let name = ref('lqz')
    //   let age = ref(19)  // 他就变成了响应式
    //   const handleAdd = () => {
    //     console.log(age)
    //     console.log(typeof age)
    //     // age = age + 1
    //     // 以后需要用那个之,需要 对象.value才能取出来
    //     age.value = age.value + 1
    //     console.log(age)
    //
    //   }
    //
    //   const handleChange = () => {
    //     // name.value = '彭于晏'
    //     name.value = name.value+'nb'
    //     console.log(name)
    //   }
    //
    //   return {name, age, handleAdd, handleChange}

    // 4 研究一下,原来的data,methods还能不能用
    let name = 'lqz'
    let age = 19
    // const handleAdd = () => {
    //   console.log('setup中的handleAdd')
    // }
    console.log('---',this)
    return {name, age,}

  }
}
</script>

五、 reactive函数

### 使用方式
let data = reactive({'name': 'lqz', 'age': 19, 'hobby': '篮球'})
const handelAdd = () => {
      data.age += 1  // 使用reactive包裹的对象,直接当对象用即可
      console.log(data)
    }
 return {data, handelAdd}

从定义数据角度对比:

ref用来定义:基本类型数据
reactive用来定义:对象(或数组)类型数据

从原理角度对比:

ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)。
reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据。

从使用角度对比:

ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value。
reactive定义的数据:操作数据与读取数据:均不需要.value。

六、计算,监听属性

监听属性 就是使用watch,三种方式


	#  1 方式一
    // watch(name, (newValue, oldValue) => {
    //   console.log(oldValue)
    //   console.log(newValue)
    //   console.log('name 真的变了。。。。')
    // })

    # 2 监听属性之监听对象中的某个属性
    let person = reactive({name: 'lqz', age: 19})
    watch(() => person.name, () => {
      console.log('person中的name变了')
    })
    const handleChanel = () => {
      person.name = '刘亦菲'
    }
    #  3 同时监听多个变量
    // const sum = ref(100)
    // const msg = ref('很好')
    // watch([sum, msg], (newValue, oldValue) => {
    //   console.log('sum或msg变化了', newValue, oldValue)
    // })

计算属性 使用computed ,只有取值触发或取值赋值触发函数

1 基本使用

    // let newName = computed(() => {
    //   return name.value + 'nb'
    // })

2 了解:计算属性可以取值用,还可以改值

    let newName = computed({
      get() {
        // 使用计算属性,会触发这里
        return name.value + '=nb'
      },
      set(value) {
        // 只要计算属性发生变化,就会执行这里
        // 只要newName变了,name理应该也变,需要我们写代码变
        let res=value.split('=')
        name.value=res[0]
        console.log('计算属性变了,变成', value)
      }

七、生命周期

vue3不建议使用 配置项api,把所有代码都写在setup函数中

	-以后没有:destory这俩了,换成了unmounted
    -可以写配置项api(练习一下)
        beforeCreate
        created
        beforeMoun
        mounted
        beforeUpdate
        updated 
        beforeUnmount 
        unmounted 
    -但是不建议了(以后写组合式aip)
        beforeCreate===>setup()
        created=======>setup()
        beforeMount ===>onBeforeMount
        mounted=======>onMounted
        beforeUpdate===>onBeforeUpdate
        updated =======>onUpdated
        beforeUnmount ==>onBeforeUnmount
        unmounted =====>onUnmounted

八 toRef

...{对象}---》相当于解压
再setup函数中return时,使用return {...toRefs(data)},以后再templte中直接使用内层的变量即可


  setup() {

    console.log('执行了')
    let a={hobby:'篮球',gender:'男'}

    let b ={...a,name:'lqz'}
    console.log(b)




    var data = reactive({name: 'lqz', age: 19})
    const handleClick = () => {
      alert('美女')
    }
    const  handleAdd=()=>{
      data.age+=1
    }

    // ...toRefs(data)  等同于  {name:data.name,age:data.age}
    // return {name: data.name, age: data.age, handleClick}
    return {...toRefs(data),handleClick,handleAdd}
  }

九 vue3 setup写法

<script setup>
// <script setup> 表示,这个script里的所有东西是setup函数,原来写在setup中的,现在顶格写即可
import {ref, toRefs} from 'vue'
import HelloWorld from '@/components/HelloWorld.vue'

let name = ref('lqz')

const handelClick = () => {
  name.value = '彭于晏'
}
// watch,computed
// 生命周期钩子
// 组件导入,自动注册

// 不需要return


</script>
posted @ 2023-06-12 21:23  岳宗柯  阅读(27)  评论(0编辑  收藏  举报