Vue3基础使用

目录

一、创建Vue3工程

(一)、cli

(二)、vite

二、常用Composition API

(一)、setup函数

(二)、ref函数

(三)、reactive函数

(四)、setup注意事项

(五)、计算属性

(六)、watch

(七)、watchEffect函数

(八)、生命周期

1、以配置项的形式使用生命周期钩子

2、组合式api(在setup中使用)

(九)、自定义hook

(十)、toRef、toRefs

三、其他Composition API

(一)、shallowReactive、shallowRef

(二)、readonly 与 shallowReadonly

(三)、toRaw 与 markRaw

(四)、自定义ref(customRef)

(五)、provide、inject

(六)、响应式数据的判断

五、新的组件

(一)、Fragment

(二)、Teleport

(三)、Suspense

六、Vue3的其他改变

(一)、全局API的转移

(二)、data

(三)、过度类名更改

(四)、keyCode

(五)、移除v-on.native

(六)、移除过滤器


一、创建Vue3工程

(一)、cli

创建一个项目 | Vue CLI🛠️ Vue.js 开发的标准工具icon-default.png?t=N7T8https://cli.vuejs.org/zh/guide/creating-a-project.html#vue-create

##查看@vue/c1i版本,确保@vue/c1i版本在4.5.8以上
vue --version
#安装或者升级你的@vue/cli
npm install -g @vue/cli

##创建
vue create 项目名
##启动
cd 项目名
npm run serve

(二)、vite

快速上手 | Vue.jsVue.js - 渐进式的 JavaScript 框架icon-default.png?t=N7T8https://v3.cn.vuejs.org/guide/installation.html#viteVite中文网下一代前端开发与构建工具icon-default.png?t=N7T8https://vitejs.cn

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

二、常用Composition API

(一)、setup函数

简单演示,下面的写法不对,丢失了响应式。 

<template>
  <h2>我的名字是{{ name }},年龄是{{ age }}</h2>
</template>

<script>
export default {
  name: "HelloWorld",
  setup() {
    let name = "jack";
    let age = 18;

    function sayHello() {
      console.log("hello");
    }
    return {
      name,
      age,
      sayHello,
    };
  },
};
</script>

(二)、ref函数

// 示例,执行changeInfo函数修改信息,响应式数据
import {ref} from 'vue'
export default {
	name: 'App',
  	setup(){
    	let name = ref('LHD')
    	let age = ref(19)
    	let job = ref({
    	  type:'前端工程师',
    	  salary:'15k'
    	})
    	function changeInfo(){
    	  name.value = 'DHL',
    	  age.value = '20',
    	  job.value.type = '搬砖工程师',
    	  job.value.salary = '10k'
    	}
    	return{
    	  name,
    	  age,
    	  job,
    	  changeInfo
    	}
	}
}

(三)、reactive函数

// 先引入reactive
import {reactive} from 'vue'
// 2的示例,setup函数中改成这样
let person = reactive({
	name:'LHD',
  	age:'19',
  	job:{
    	type:'工程师',
    	salary:'20k'
  	},
  	hobby:['Study','Video Game']
})
function changeInfo(){
	person.name = 'DHL',
  	person.age = '20',
  	person.job.type = '搬砖工程师',
  	person.job.salary = '10k',
  	person.hobby[1] = 'fly'
}
return{
	person,
  	changeInfo
}

(四)、setup注意事项

(五)、计算属性

(六)、watch

//情况一:监视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配置有效

(七)、watchEffect函数

//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
watchEffect(()=>{
    const x1 = sum.value
    const x2 = person.age
    console.log('watchEffect配置的回调执行了')
})

(八)、生命周期

1、以配置项的形式使用生命周期钩子

与setup平级

2、组合式api(在setup中使用)

(九)、自定义hook

src/hooks/usePoint.js

///得到鼠标点的api

import { reactive, onMounted, onBeforeUnmount } from "vue";

export default function usePoint(){
    //响应式数据
    let point = reactive({
        x: 0,
        y: 0
    });

    //方法
    const savePoint = event => {
        console.log(event.pageX, event.pageY);
        point.x = event.pageX;
        point.y = event.pageY;
    };

    //生命周期
    onMounted(() => {
        window.addEventListener('click', savePoint)
    });

    onBeforeUnmount(() => {
        //在卸载之前取消事件的监听
        window.removeEventListener('click', savePoint);
    });

    return point;
}

 src/components/Demo.vue

<template>
   <h1>当前求和为:{{ sum }}</h1>
   <button @click="sum++">点我加一</button>
   <hr/>
   <h2>当前点击时鼠标的坐标为x:{{ point.x }}, y:{{ point.y }}</h2>
</template>

<script>
import {ref} from 'vue';
import usePoint from "../hooks/usePoint";
export default {
  name: 'Demo',
  setup(){
    let sum = ref(0);

    //复用自定义hooks
    const point = usePoint();

    //返回一个对象
    return {
      sum,
      point
    }
  },
}
</script>

<style>
</style>

(十)、toRef、toRefs

<template>
  <h4>{{ person }}</h4>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <h2>薪资:{{ salary }}K</h2>
  <button @click="name = name + '~'">修改姓名</button>
  <button @click="age++">增长年龄</button>
  <button @click="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
        }
      }
    });

    //ref类型的值在模板里使用是不需要.value来取的
    const name1 = person.name //注意输出字符串,并不是响应式的数据
    console.log('@@@@@', name1);
    const name2 = toRef(person,name); //RefImpl 这里的name2与person.name是完全一模一样的(你改这里的name2与你改person.name是一码事),且数据还是响应式的
    console.log('####', name2);

    const x = toRefs(person);
    console.log(x);


    //返回一个对象(toRef是引用 name就是person.name且为响应式)
    //toRef处理一个,而toRefs处理一群
    //大白话:toRef(s)就是方便我们把响应式数据(ref,reactive)展开丢出去,方便在模版中应用
    return {
      person,
      // name: toRef(person, "name"),
      // age: toRef(person, "age"),
      // salary: toRef(person.job.j1, "salary")
      ...toRefs(person),
      salary: toRef(person.job.j1, 'salary')  //toRef可以与toRefs连用,更加方便
    };


    //注意千万不能这样写
    //一旦这样写就与元数据分离了,改name不会引起person.name的变化(因为ref把name值包装成了一个refImpl对象)
    // return {
    //   person,
    //   name: ref(person.name),
    //   age: ref(person.age),
    //   salary: ref(person.job.j1.salary)
    // };
  }
}
</script>

<style>
</style>

三、其他Composition API

(一)、shallowReactive、shallowRef

(二)、readonly 与 shallowReadonly

(三)、toRaw 与 markRaw

<template>
  <h2>当前求和为:{{ sum }}</h2>
  <button @click="sum++">sum+1</button>
  <hr/>
  <h2>姓名:{{ name }}</h2>
  <h2>年龄:{{ age }}</h2>
  <h2>薪资:{{ job.j1.salary }}K</h2>
  <h3 v-show="person.car">座驾信息:{{ person.car }}</h3>
  <button @click="name = name + '~'">修改姓名</button>
  <button @click="age++">增长年龄</button>
  <button @click="job.j1.salary++">增长薪资</button>
  <button @click="showRawPerson">输出最原始的person</button>
  <button @click="addCar">给人添加一台车</button>
  <button @click="person.car && (person.car.name +='!') ">换车名</button>
  <button @click="changePrice">换价格</button>
</template>

<script>
import {markRaw, reactive, ref, toRaw, toRefs} from 'vue';

export default {
  name: 'Demo',
  setup(){

    let sum = ref(0);

    let person = reactive({
      name: '张三',
      age: 18,
      job:{
        j1:{
          salary: 20
        }
      }
    });

    //ref reactive(响应式)

    const showRawPerson = () => {
       const  p = toRaw(person);
       // console.log(person); //proxy代理对象 Proxy {....}
       p.age++; //注意此时页面不会再发生变化了,普普通通的对象不是响应式
       console.log(p); //原始对象数据  {....}

      // const sum  = toRaw(sum);
      // console.log(sum); //undefined //这条路走不通,toRaw只处理reactive对象
    }

    const addCar = () => {
      person.car = markRaw({
         name: 'benz',
         price: 40
       }); //在响应式的对象身上添加任何属性都是响应式的,经过markRaw一包装就变成最原始的数据就不会再做响应
    }


    const changePrice = () => {
      person.car?.price && person.car.price++;
      console.log(person?.car?.price);
    }

    return {
      sum,
      person,
      ...toRefs(person),
      showRawPerson,
      addCar,
      changePrice
    };

  }
}
</script>

<style>
</style>

(四)、自定义ref(customRef)

需求

<template>
	<input type="text" v-model="keyword">
	<h3>{{keyword}}</h3>
</template>

<script>
	import {ref,customRef} from 'vue'
	export default {
		name:'Demo',
		setup(){
			// let keyword = ref('hello') //使用Vue准备好的内置ref
			//自定义一个myRef
			function myRef(value,delay){
				let timer
				//通过customRef去实现自定义
				return customRef((track,trigger)=>{
					return{
						get(){
							track() //告诉Vue这个value值是需要被“追踪”的
							return value
						},
						set(newValue){
							clearTimeout(timer)
							timer = setTimeout(()=>{
								value = newValue
								trigger() //告诉Vue去更新界面
							},delay)
						}
					}
				})
			}
			let keyword = myRef('hello',500) //使用程序员自定义的ref
			return {
				keyword
			}
		}
	}
</script>

(五)、provide、inject

(六)、响应式数据的判断

  1. isRef: 检查一个值是否为一个 ref 对象
  2. isReactive: 检查一个对象是否是由 reactive 创建的响应式代理
  3. isReadonly: 检查一个对象是否是由 readonly 创建的只读代理
  4. isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理

五、新的组件

(一)、Fragment

  • 在Vue2中: 组件必须有一个根标签
  • 在Vue3中: 组件可以没有根标签, 内部会将多个标签包含在一个Fragment虚拟元素中
  • 好处: 减少标签层级, 减小内存占用

(二)、Teleport

什么是Teleport?—— Teleport 是一种能够将我们的组件html结构移动到指定位置的技术。

(三)、Suspense

六、Vue3的其他改变

(一)、全局API的转移

Vue 2.x 有许多全局 API 和配置。

  • 例如:注册全局组件、注册全局指令等

//注册全局组件
Vue.component('MyButton', {
  data: () => ({
    count: 0
  }),
  template: '<button @click="count++">Clicked {{ count }} times.</button>'
})

//注册全局指令
Vue.directive('focus', {
  inserted: el => el.focus()
}

Vue3.0中对这些API做出了调整:

  • 将全局的API,即:Vue.xxx调整到应用实例(app)上

(二)、data

data选项应始终被声明为一个函数。

(三)、过度类名更改

Vue2.x写法

.v-enter,
.v-leave-to {
  opacity: 0;
}
.v-leave,
.v-enter-to {
  opacity: 1;
}

Vue3.x写法

.v-enter-from,
.v-leave-to {
  opacity: 0;
}

.v-leave-from,
.v-enter-to {
  opacity: 1;
}

(四)、keyCode

移除 keyCode作为 v-on 的修饰符,同时也不再支持config.keyCodes

(五)、移除v-on.native

移除 v-on.native修饰符

父组件中绑定事件

<my-component
  v-on:close="handleComponentEvent"
  v-on:click="handleNativeClickEvent"
/>

子组件中声明自定义事件

<script>
  export default {
    emits: ['close']
  }
</script>

(六)、移除过滤器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/743816.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

功能测试【测试用例模板、Bug模板、手机App测试★】

功能测试 Day01 web项目环境与测试流程、业务流程测试一、【了解】web项目环境说明1.1 环境的定义&#xff1a;项目运行所需要的所有的软件和硬件组合1.2 环境(服务器)的组成&#xff1a;操作系统数据库web应用程序项目代码1.3 面试题&#xff1a;你们公司有几套环境&#xff1…

昇思25天学习打卡营第2天|快速入门

快速入门 操作步骤1.引入依赖包2.下载Mnist数据集3.划分训练集和测试集4.数据预处理5.网络构建6.模型训练7.保存模型8.加载模型9.模型预测 今天通过昇思大模型平台AI实验室提供的在线Jupyter工具&#xff0c;快速入门MindSpore。 目标&#xff1a;通过MindSpore的API快速实现一…

互联网应用主流框架整合之Spring Boot运维体系

先准备个简单的系统&#xff0c;配置和代码如下 # 服务器配置 server:# 服务器端口port: 8001# Spring Boot 配置 spring:# MVC 配置mvc:# Servlet 配置servlet:# Servlet 的访问路径path: /sbd# 应用程序配置application:# 应用程序名称name: SpringBootDeployment# 配置数据…

PointCloudLib NDT3D算法实现点云配准 C++版本

0.实现效果 效果不咋好 ,参数不好调整 1.算法原理 3D NDT(Normal Distributions Transform)算法是一种用于同时定位和地图生成(SLAM)的机器人导航算法,特别适用于三维点云数据的配准。以下是关于3D NDT算法的详细解释: 算法原理 点云划分与分布计算:3D NDT算法首先将…

ElementPlus组件与图标按需自动引入

按需自动引入组件 1. 安装ElementPlus和自动导入ElementPlus组件的插件 pnpm install element-plus pnpm install -D unplugin-vue-components unplugin-auto-import 2. vite.config.ts进行修改 import { defineConfig } from vite import vue from vitejs/plugin-vue // …

MySQL索引优化解决方案--索引失效(3)

索引失效情况 最佳左前缀法则&#xff1a;如果索引了多列&#xff0c;要遵循最左前缀法则&#xff0c;指的是查询从索引的最左前列开始并且不跳过索引中的列。不在索引列上做任何计算、函数操作&#xff0c;会导致索引失效而转向全表扫描存储引擎不能使用索引中范围条件右边的…

Windows 根据github上的环境需求,安装一个虚拟环境,安装cuda和torch

比如我们在github上看到一个关于运行环境的需求 Installation xxx系统Python 3.xxx CUDA 9.2PyTorch 1.9.0xxxxxx 最主要的就是cuda和torch&#xff0c;这两个会卡很多环境的安装。 我们重新走一遍环境安装。 首先创建一个虚拟环境 conda create -n 环境名字 python3.xxx…

Tomcat 下载部署到 idea

一、下载Tomcat Tomcat 是Apache 软件基金会&#xff08;Apache Software Foundation&#xff09;下的一个核心项目&#xff0c;免费开源、并支持Servlet 和JSP 规范。属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发…

【Text2SQL 论文】MAGIC:为 Text2SQL 任务自动生成 self-correction guideline

论文&#xff1a;MAGIC: Generating Self-Correction Guideline for In-Context Text-to-SQL ⭐⭐⭐ 莱顿大学 & Microsoft, arXiv:2406.12692 一、论文速读 DIN-SQL 模型中使用了一个 self-correction 模块&#xff0c;他把 LLM 直接生成的 SQL 带上一些 guidelines 的 p…

计算机组成原理课程设计报告

有关计算机组成原理课程设计报告如下题材&#xff0c;其包含报告和代码 16位ALU设计 动态LED动态显示屏设计 海明码编码设计编码流水传输 单周期MIPS控制器设计 阵列乘法器设计 Cache映射机制与逻辑实现 我们以6x6位阵列乘法器设计的报告为例为大家讲述一下我们这次的课程设计 …

网络爬虫Xpath开发工具的使用

开发人员在编写网络爬虫程序时若遇到解析网页数据的问题&#xff0c;则需要花费大量的时间编 写与测试路径表达式&#xff0c;以确认是否可以解析出所需要的数据。为帮助开发人员在网页上直接 测试路径表达式是否正确&#xff0c;我们在这里推荐一款比较好用的 XPath 开发工…

关于关闭防火墙后docker启动不了容器

做项目的时候遇到个怪事&#xff0c;在Java客户端没办法操作redis集群。反复检查了是否运行&#xff0c;端口等一系列细节的操作&#xff0c;结果都不行。 根据提示可能是Linux的防火墙原因。于是去linux关闭了防火墙。 关闭后果不其然 可以操作reids了&#xff0c;可是没想到另…

浏览器断点调试(用图说话)

浏览器断点调试&#xff08;用图说话&#xff09; 1、开发者工具2、添加断点3、查看变量值 浏览器断点调试 有时候我们需要在浏览器中查看 html页面的js中的变量值。1、开发者工具 打开浏览器的开发者工具 按F12 &#xff0c;没反应的话按FnF12 2、添加断点 3、查看变量值

高考填报志愿攻略,5个步骤选专业和院校

在高考完毕出成绩的时候&#xff0c;很多人会陷入迷茫中&#xff0c;好像努力了这么多年&#xff0c;却不知道怎么规划好未来。怎么填报志愿合适&#xff1f;在填报志愿方面有几个内容需要弄清楚&#xff0c;按部就班就能找到方向&#xff0c;一起来了解一下正确的步骤吧。 第…

【C语言】解决C语言报错:Dangling Pointer

文章目录 简介什么是Dangling PointerDangling Pointer的常见原因如何检测和调试Dangling Pointer解决Dangling Pointer的最佳实践详细实例解析示例1&#xff1a;释放内存后未将指针置为NULL示例2&#xff1a;返回指向局部变量的指针示例3&#xff1a;指针悬空后继续使用示例4&…

37岁,被裁员,失业三个月,被面试官嫌弃“太水”:就这也叫10年以上工作经验?

今年部门要招两个自动化测试&#xff0c;这几个月我面试了几十位候选人。发现一个很奇怪的现象&#xff0c;面试中一问到元素定位、框架api、脚本编写之类的&#xff0c;很多候选人都对答如流。但是一问到实际项目&#xff0c;比如“项目中UI自动化和接口自动化如何搭配使用&am…

【研究】国内外大模型公司进展

2022年11月&#xff0c;OpenAI推出基于GPT-3.5的ChatGPT后&#xff0c;引发全球AI大模型技术开发与投资热潮。AI大模型性能持续快速提升。以衡量LLM的常用评测标准MMLU为例&#xff0c;2021年底全球最先进大模型的MMLU 5-shot得分刚达到60%&#xff0c;2022年底超过70%&#xf…

JAVA小知识29:IO流(上)

IO流是指在计算机中进行输入和输出操作的一种方式&#xff0c;用于读取和写入数据。IO流主要用于处理数据传输&#xff0c;可以将数据从一个地方传送到另一个地方&#xff0c;例如从内存到硬盘&#xff0c;从网络到内存等。IO流在编程中非常常见&#xff0c;特别是在文件操作和…

正版软件 | Copywhiz 6:革新您的文件复制、备份与管理体验

在数字化时代&#xff0c;文件管理的效率直接影响到我们的生产力。Copywhiz 6 最新版本&#xff0c;带来了前所未有的文件处理能力&#xff0c;让复制、备份和组织文件变得轻而易举。 智能选择&#xff0c;只复制更新内容 Copywhiz 6 的智能选择功能&#xff0c;让您只需几次点…

10--7层负载均衡集群

前言&#xff1a;动静分离&#xff0c;资源分离都是在7层负载均衡完成的&#xff0c;此处常被与四层负载均衡比较&#xff0c;本章这里使用haproxy与nginx进行负载均衡总结演示。 1、基础概念详解 1.1、负载均衡 4层负载均衡和7层负载均衡是两种常见的负载均衡技术&#xff…