vueJavaScript前端

快速入门vue3

2022-05-11  本文已影响0人  e只咸鱼

一.简介

image.png

2020年9月18日,Vue.js发布3.0版本,代号:One Piece(海贼王)

和vue2相比它的变化有哪些

1.性能的提升
2.源码的升级
3.拥抱TypeScript
4.新的特性

二、创建一个Vue项目

1. 使用 vue-cli 创建
## 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue --version
## 安装或者升级你的@vue/cli
npm install -g @vue/cli
## 创建Vue项目,选择Vue3
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/

## 创建工程
npm init vite-app vue3_test_vite
## 进入工程目录
cd vue3_test_vite
## 安装依赖
npm install
## 运行
npm run dev

三、分析文件目录

1.main

Vue2项目的main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

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

Vue3项目的main.js

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

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

注意: 可以明显的看到vue3引入的不在是vue构造函数了,引入的是一个名为createApp的工厂函数
将代码处理一下把在看看

//vue2
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

const vm = new Vue({
  render: h => h(App),
})
console.log(vm)
// 挂载
vm.$mount('#app')
//vue3
import { createApp } from 'vue'
import App from './App.vue'

// 创建应用实例对象--app(类似于之前Vue2中的vm,但app比vm更‘轻’)
const app = createApp(App)
console.log(app)
// 挂载
app.mount('#app')
vue3和vue2的一个小区别

分别打印vm 和 app 进行对比 可以很明显看到vue3的属性比vue2少很多


image.png
image.png

2.App.vue

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

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

接下来我们来正式学习Vue3的内容~

四、Composition API(组合式api)

官方文档: https://v3.cn.vuejs.org/guide/composition-api-introduction.html

1.拉开序幕的setup

  1. 理解:Vue3.0中一个新的配置项,值为一个函数。
  2. setup是所有 Composition API(组合API) “ 表演的舞台 ” 。
  3. 组件中所用到的:数据、方法等等,均要配置在setup中。
  4. setup函数的两种返回值:
    1. 若返回一个对象,则对象中的属性、方法, 在模板中均可以直接使用。(重点关注!)
    2. 若返回一个渲染函数:则可以自定义渲染内容。(了解)
  5. 注意点:
    1. 尽量不要与Vue2.x配置混用
      • Vue2.x配置(data、methos、computed...)中可以访问到setup中的属性、方法。
      • 但在setup中不能访问到Vue2.x配置(data、methos、computed...)。
      • 如果有重名, setup优先。
    2. setup不能是一个async函数,因为返回值不再是return的对象, 而是promise, 模板看不到return对象中的属性。(后期也可以返回一个Promise实例,但需要Suspense和异步组件的配合)

案例

<template>
  <h1>个人信息</h1>
  <h2>姓名:{{name}}</h2>
  <h2>年龄:{{age}}</h2>
  <h2>性别:{{gender}}</h2>
  <button @click="sayInfo">显示信息</button>
</template>

<script>
// import {h} from 'vue'
export default {
  name: "App",
  //此处只是测试一下setup,暂时不考虑响应式的问题。
  setup(){
    // 数据
    let name = "EvenShun"
    let age = 22
    let gender = "男"

    // 方法
    function sayInfo(){
      alert(`我是${name},年龄${age },性别${gender}`)
    }
    return {
      name,
      age, 
      gender,
      sayInfo
    }
    // return ()=> h('h1','EvenShun')
  }
};
</script>

2.ref函数

案例

<template>
    <h1>一个人的信息</h1>
    <h2>姓名:{{name}}</h2>
    <h2>年龄:{{age}}</h2>
    <h3>工作种类:{{job.type}}</h3>
    <h3>工作薪水:{{job.salary}}</h3>
    <button @click="changeInfo">修改人的信息</button>
</template>

<script>
    import {ref} from 'vue'
    export default {
        name: 'App',
        setup(){
            //数据
            let name = ref('张三')
            let age = ref(18)
            let job = ref({
                type:'前端工程师',
                salary:'30K'
            })

            //方法
            function changeInfo(){
                // name.value = '李四'
                // age.value = 48
                console.log(job.value)
                // job.value.type = 'UI设计师'
                // job.value.salary = '60K'
                // console.log(name,age)
            }

            //返回一个对象(常用)
            return {
                name,
                age,
                job,
                changeInfo
            }
        }
    }
</script>

3.reactive函数

案例

<template>
    <h1>一个人的信息</h1>
    <h2>姓名:{{person.name}}</h2>
    <h2>年龄:{{person.age}}</h2>
    <h3>工作种类:{{person.job.type}}</h3>
    <h3>工作薪水:{{person.job.salary}}</h3>
    <h3>爱好:{{person.hobby}}</h3>
    <h3>测试的数据c:{{person.job.a.b.c}}</h3>
    <button @click="changeInfo">修改人的信息</button>
</template>

<script>
    import {reactive} from 'vue'
    export default {
        name: 'App',
        setup(){
            //数据
            let person = reactive({
                name:'张三',
                age:18,
                job:{
                    type:'前端工程师',
                    salary:'30K',
                    a:{
                        b:{
                            c:666
                        }
                    }
                },
                hobby:['抽烟','喝酒','烫头']
            })

            //方法
            function changeInfo(){
                person.name = '李四'
                person.age = 48
                person.job.type = 'UI设计师'
                person.job.salary = '60K'
                person.job.a.b.c = 999
                person.hobby[0] = '学习'
            }

            //返回一个对象(常用)
            return {
                person,
                changeInfo
            }
        }
    }
</script>


4.Vue3.0中的响应式原理

vue2.x的响应式

//源数据
let person = {
    name:'张三',
    age:18
}
//模拟Vue2中实现响应式
let p = {}
Object.defineProperty(p,'name',{
    configurable:true,
    get(){ //有人读取name时调用
        return person.name
    },
    set(value){ //有人修改name时调用
        console.log('有人修改了name属性,我发现了,我要去更新界面!')
        person.name = value
    }
})
Object.defineProperty(p,'age',{
    get(){ //有人读取age时调用
        return person.age
    },
    set(value){ //有人修改age时调用
        console.log('有人修改了age属性,我发现了,我要去更新界面!')
        person.age = value
    }
})

Vue3.0的响应式

5.reactive对比ref

6.setup的两个注意点

7.计算属性与监视

1.computed函数

2.watch函数

            //数据
            let sum = ref(0)
            let msg = ref('你好啊')
            let person = ref({
                name:'张三',
                age:18,
                job:{
                    j1:{
                        salary:20
                    }
                }
            })

            console.log(person)

            watch(sum,(newValue,oldValue)=>{
                console.log('sum的值变化了',newValue,oldValue)
            })

            watch(person,(newValue,oldValue)=>{
                console.log('person的值变化了',newValue,oldValue)
            },{deep:true})

3.watchEffect函数

8.生命周期

    import {ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted} from 'vue'
    export default {
        name: 'Demo',
        
        setup(){
            console.log('---setup---')
            //数据
            let sum = ref(0)

            //通过组合式API的形式去使用生命周期钩子
            onBeforeMount(()=>{
                console.log('---onBeforeMount---')
            })
            onMounted(()=>{
                console.log('---onMounted---')
            })
            onBeforeUpdate(()=>{
                console.log('---onBeforeUpdate---')
            })
            onUpdated(()=>{
                console.log('---onUpdated---')
            })
            onBeforeUnmount(()=>{
                console.log('---onBeforeUnmount---')
            })
            onUnmounted(()=>{
                console.log('---onUnmounted---')
            })

            //返回一个对象(常用)
            return {sum}
        },
     }

9.自定义hook函数

import { reactive, onMounted, onBeforeUnmount } from "vue";
export default function() {
  //实现鼠标“打点”相关的数据
  let point = reactive({
    x: 0,
    y: 0,
  });

  //实现鼠标“打点”相关的方法
  function savePoint(event) {
    point.x = event.pageX;
    point.y = event.pageY;
    console.log(event.pageX, event.pageY);
  }

  //实现鼠标“打点”相关的生命周期钩子
  onMounted(() => {
    window.addEventListener("click", savePoint);
  });

  onBeforeUnmount(() => {
    window.removeEventListener("click", savePoint);
  });

  return point;
}

在组件里使用

<template>
    <h2>我是HelloWorld组件</h2>
    <h2>当前点击时鼠标的坐标为:x:{{point.x}},y:{{point.y}}</h2>
</template>

<script>
    import usePoint from '../hooks/usePoint'
    export default {
        name:'HelloWorld',
        setup(){
            const point = usePoint()
            return {point}
        }
    }
</script>

10.toRef

<template>
    <h4>{{person}}</h4>
    <h2>姓名:{{name}}</h2>
    <h2>年龄:{{age}}</h2>
    <h2>薪资:{{job.j1.salary}}K</h2>
    <button @click="name+='~'">修改姓名</button>
    <button @click="age++">增长年龄</button>
    <button @click="job.j1.salary++">涨薪</button>
</template>

<script>
    import {ref,reactive,toRef,toRefs} from 'vue'
    export default {
        name: 'Demo',
        setup(){
            //数据
            let person = reactive({
                name:'张三',
                age:18,
                job:{
                    j1:{
                        salary:20
                    }
                }
            })

            // const name1 = person.name
            // console.log('%%%',name1)

            // const name2 = toRef(person,'name')
            // console.log('####',name2)

            const x = toRefs(person)
            console.log('******',x)

            return {
                person,
                // name:toRef(person,'name'),
                // age:toRef(person,'age'),
                // salary:toRef(person.job.j1,'salary'),
                ...toRefs(person)
            }
        }
    }
</script>

三、其它 Composition API

1.shallowReactive 与 shallowRef

2.readonly 与 shallowReadonly

3.toRaw 与 markRaw

4.customRef

5.provide 与 inject

image.png

6.响应式数据的判断

四、Composition API 的优势

1.Options API 存在的问题

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


image.png

2.Composition API 的优势

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

image.png

五、新的组件

1.Fragment

2.Teleport

3.Suspense

六、其他

1.全局API的转移

2.其他改变

上一篇 下一篇

猜你喜欢

热点阅读