当前位置: 首页 > article >正文

vue3入门知识(一)

vue3简介

性能的提升

  • 打包大小减少41%
  • 初次渲染快55%,更新渲染快133%
  • 内存减少54%

源码的升级

  • 使用Proxy代替defineProperty实现响应式
  • 重写虚拟DOM的实现和Tree-Shaking

新的特性

1. Composition API(组合API)

  • setup
  • ref与reactive
  • computed与watch

2. 新的内置组件

  • Fragment
  • Teleport
  • Suspense

3. 其他改变

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

创建vue3项目

基于vue-cli创建(基于webpack)

// 安装或升级@vue.cli
npm install -g @vue/cli
// 执行创建命令
vue create project_name

基于vite创建

vite是新一代前端构建工具,官网地址:Vite中文网

vite的优势:

  • 轻量快速的热重载(HMR),能实现极速的服务启动
  • 对TypeScript、JSX、CSS等支持开箱即用
  • 真正的按需编译,不再等待整个应用编译完成
  • webpack构建与vite构建对比图如下:

webpack构建:

vite构建: 

创建项目的命令 

npm create vue@latest

Tips:

  • 确保 Node.js 版本支持 Vue 3:推荐使用 Node.js 14 及以上版本

尝试使用node版本 14.21.3,创建项目时有报错,升级node版本为 16.20.2 之后就可以了

创建项目时的一些配置项设置,仅供参考

安装好的项目文件目录:

这个文件里面有报错,执行一下 npm install 就好了

并且这个文件里面的内容不能删除,他的作用是告诉 TypeScript 引入 Vite 的类型定义

可能还会有上图中这样的报错提示,在确保已经执行npm install之后,重新打开编辑器,报错提示就会消失了

选项式API的弊端

vue2(选项式API)数据、方法、计算属性等,是分散在:data、methods、computed中的,若想新增或者修改一个需求,就需要分别修改data、methods、computed,不便于维护和复用

组合式API的优势

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

setup

setup中的this是undefined,vue3中已经弱化this了

setup的执行顺序在beforeCreate之前

setup的返回值可以是一个渲染函数,返回内容直接渲染在页面上

return () => '直接在页面上展示的内容'
<template>
    <div class="person">
        <h2>姓名:{{ name }}</h2>
        <h2>年龄:{{ age }}</h2>
        <button @click="changeName">修改姓名</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="showTel">查看联系方式</button>
    </div>
</template>

<script lang="ts">
export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name: 'Person',
    setup() {
        // 这样写的name age tel不是响应式的 vue2中是写在data中的
        let name = '张三';
        let age = 18;
        const tel = '13800138000';

        function changeName() {
            name = '李四'; // 这样修改之后页面不会更新 值确实改了但不是响应式的 因此页面未更新
        };

        function changeAge() {
            age += 1;
        };

        function showTel() {
            alert(tel);
        };

        // 将数据、方法交出去,模板中才可以使用
        return {
            name,
            age,
            tel,
            changeName,
            changeAge,
            showTel,
        };
    },
};
</script>

<style scoped lang="less">
.person {
    button {
        display: block;
        margin: 10px 0;
    }
}
</style>

data、methods可以和setup同时存在

data中可以读取setup中的数据,通过this.xxx来获取,但是setup中是无法读取data中的数据的,因为setup是在data之前执行的

setup语法糖

<template>
    <div class="person">
        <h2>姓名:{{ name }}</h2>
        <h2>年龄:{{ age }}</h2>
        <button @click="changeName">修改姓名</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="showTel">查看联系方式</button>
    </div>
</template>

<script lang="ts">
export default {
    // eslint-disable-next-line vue/multi-word-component-names
    name: 'Person',
};
</script>

<script setup lang="ts">
// 这样写的name age tel不是响应式的 vue2中是写在data中的
let name = '张三';
let age = 18;
const tel = '13800138000';

function changeName() {
    name = '李四'; // 这样修改之后页面不会更新 值确实改了但不是响应式的 因此页面未更新
};
function changeAge() {
    age += 1;
};
function showTel() {
    alert(tel);
};
</script>

<style scoped lang="less">
.person {
    button {
        display: block;
        margin: 10px 0;
    }
}
</style>

由于这样需要写两块script标签 ,第一块的主要作用是自定义组件名称,可以借助插件,省略第一块script标签

npm i vite-plugin-vue-setup-extend -D

安装之后在 vite.config.ts 中进行引入配置

<template>
    <div class="person">
        <h2>姓名:{{ name }}</h2>
        <h2>年龄:{{ age }}</h2>
        <button @click="changeName">修改姓名</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="showTel">查看联系方式</button>
    </div>
</template>

<script setup lang="ts" name="Person"> 
// 这样写的name age tel不是响应式的 vue2中是写在data中的
let name = '张三';
let age = 18;
const tel = '13800138000';

function changeName() {
    name = '李四'; // 这样修改之后页面不会更新 值确实改了但不是响应式的 因此页面未更新
};
function changeAge() {
    age += 1;
};
function showTel() {
    alert(tel);
};
</script>

<style scoped lang="less">
.person {
    button {
        display: block;
        margin: 10px 0;
    }
}
</style>

ref

用于(可以)定义基本类型的响应式数据,也可以定义对象类型的响应式数据,想让哪个数据是响应式的 就用ref包一下,在js代码中使用响应式数据需要用 .value 在模板中不需要

<template>
    <div class="person">
        <h2>姓名:{{ name }}</h2>
        <h2>年龄:{{ age }}</h2>
        <h2>地址:{{ address }}</h2>
        <button @click="changeName">修改姓名</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="showTel">查看联系方式</button>
    </div>
</template>

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

let name = ref('张三');
let age = ref(18);
const tel = '13800138000';
const address = '北京';

function changeName() {
    name.value = '李四';
};
function changeAge() {
    age.value += 1;
};
function showTel() {
    alert(tel);
};
</script>

<style scoped lang="less">
.person {
    button {
        display: block;
        margin: 10px 0;
    }
}
</style>

 定义对象类型的响应式数据,表面使用的是ref,其实底层用的还是reactive

<template>
    <div class="person">
        <h2>汽车信息: 一辆{{ car.brand }}车,价值{{ car.price }}</h2>
        <button @click="changePrice">修改汽车的价格</button>
        <br>
        <h2>游戏列表: </h2>
        <ul>
            <li v-for="game in games" :key="game.id">
                {{ game.name }}
            </li>
        </ul>
        <button @click="changeFirstGameName">修改第一个游戏的名字</button>
    </div>
</template>

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

let car = ref({
    brand: 'BMW',
    price: 100,
});
let games = ref([
    { name: 'LOL', id: 1 },
    { name: 'CSGO', id: 2 },
    { name: 'DOTA', id: 3 },
]);

function changePrice() {
    car.value.price += 10;
};
function changeFirstGameName() {
    games.value[0].name = '王者荣耀';
};
</script>

reactive

用于(只能)定义对象类型的响应式数据

<template>
    <div class="person">
        <h2>汽车信息: 一辆{{ car.brand }}车,价值{{ car.price }}</h2>
        <button @click="changePrice">修改汽车的价格</button>
        <br>
        <h2>游戏列表: </h2>
        <ul>
            <li v-for="game in games" :key="game.id">
                {{ game.name }}
            </li>
        </ul>
        <button @click="changeFirstGameName">修改第一个游戏的名字</button>
        <br>
        <h2>{{ obj.a.b.c }}</h2>
        <button @click="changeObj">修改obj</button>
    </div>
</template>

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

let car = reactive({
    brand: 'BMW',
    price: 100,
});
let games = reactive([
    { name: 'LOL', id: 1 },
    { name: 'CSGO', id: 2 },
    { name: 'DOTA', id: 3 },
]);
let obj = reactive({
    a: {
        b: {
            c: 666,
        }
    }
})

function changePrice() {
    car.price += 10;
};
function changeFirstGameName() {
    games[0].name = '王者荣耀';
};
function changeObj() {
    // reactive的响应式是深层次的
    obj.a.b.c = 1000;
};
</script>

ref与reactive

1. ref用来定义:基本类型数据、对象类型数据

2. reactive用来定义:对象类型数据

区别:

1. ref创建的变量必须使用 .value (可以使用volar插件自动添加 .value) 

2. reactive重新分配一个新对象,会失去响应式(可以使用Object.assign去整体替换)

<template>
    <div class="person">
        <h2>汽车信息: 一辆{{ car.brand }}车,价值{{ car.price }}</h2>
        <button @click="changeCar">修改汽车</button>
    </div>
</template>

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

let car = reactive({
    brand: 'BMW',
    price: 100,
});

function changeCar() {
    // 这样会失去响应式
    // car = {
    //     brand: '奔驰',
    //     price: 200,
    // };
    
    // 这样不会失去响应式
    Object.assign(car, {
        brand: '奔驰',
        price: 200,
    });
};
</script>

 使用原则:

1. 若需要一个基本类型的响应式数据,必须使用ref

2. 若需要一个响应式对象,层级不深,ref、reactive都可以

3. 若需要一个响应式对象,且层级较深,推荐使用reactive

toRefs

把一个响应式对象中的内容拿出来,依然具备响应式的能力

<template>
    <div class="person">
        <h2>{{ person.name }}</h2>
        <h2>{{ person.age }}</h2>
        <button @click="changeName">修改姓名</button>
        <button @click="changeAge">修改年龄</button>
    </div>
</template>

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

const person = reactive({
    name: '张三',
    age: 18,
});

// 直接从响应式对象中解构出来的变量都不是响应式的 需要toRefs包裹才会变成响应式的
let { name, age } = toRefs(person);

function changeName() {
    // 这里修改之后 name、person.name 都会改变
    name.value += '~';
};
function changeAge() {
    age.value += 1;
};
</script>

<style scoped lang="less">
.person {
    button {
        margin: 10px;
    }
}
</style>

toRef

作用和toRefs一样,但每次只能取一个

<template>
    <div class="person">
        <h2>{{ person.name }}</h2>
        <h2>{{ person.age }}</h2>
        <button @click="changeName">修改姓名</button>
    </div>
</template>

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

const person = reactive({
    name: '张三',
    age: 18,
});

let name = toRef(person, 'name');

function changeName() {
    // 这里修改之后 name、person.name 都会改变
    name.value += '~';
};
</script>


http://www.kler.cn/a/386869.html

相关文章:

  • WordPress HTTPS 配置问题解决方案
  • C++编程:利用环形缓冲区优化 TCP 发送流程,避免 Short Write 问题
  • 新版 idea 编写 idea 插件时,启动出现 ClassNotFound
  • C#发票识别、发票查验接口集成、电子发票(航空运输电子行程单)
  • sql server 查看io资源使用
  • 力扣515:在每个树行中找最大值
  • docker安装低版本的jenkins-2.346.3,在线安装对应版本插件失败的解决方法
  • udp为什么会比tcp 有更低的延迟
  • Linux 下 mysql 9.1 安装设置初始密码 【附脚本】
  • Docker 容器网络模式详解
  • 【猜数字】C语言小游戏
  • 快速开发工具 Vite
  • 实现 Nuxt3 预览PDF文件
  • uniapp分享功能
  • 练习LabVIEW第四十四题
  • 导游职业资格考试真题题库
  • 自定义springCloudLoadbalancer简述
  • CMS垃圾回收流程的理解
  • 在线演示,开箱即用:传知平台让高质量内容与技术完美融合
  • 记一次宝塔centos出现Failed to start crond.service: Unit crond.service not found.解决
  • YOLOv11融合[ECCV2024]自调制特征聚合SMFA模块及相关改进思路|YOLO改进最简教程
  • 使用ookii-dialogs-wpf在WPF选择文件夹时能输入路径
  • 「Mac畅玩鸿蒙与硬件31」UI互动应用篇8 - 自定义评分星级组件
  • Flink on YARN是如何确定TaskManager个数的
  • [spark面试]spark与mapreduce的区别---在DAG方面
  • CI_CD