https://blog.csdn.net/iku_n/article/details/140136183
在本篇文章中,我们将详细讲解如何使用Vue3,从基本概念到高级技巧,最终通过一个项目实战,让大家全面掌握Vue3开发技能。
Vue基于标准HTML,CSS,JavaScript构建,并提供了一套声明式,组件化的编程模型,帮助你高效地开发用户页面。无论是简单还是复杂页面,Vue都可以胜任
渐进式JavaScript框架,易学易用,性能出色,适用场景丰富的Web前端框架
Vue是目前前端最火的框架之一
Vue是目前企业技术栈中要求的知识点
Vue可以提升开发体验
....
Vue是一个框架,也是一个生态。其功能覆盖了大部分前端开发常见的需求。但web世界是十分多样化的,不同的开发者在web上构建的东西可能在形式和规模上会有很大的不同。考虑到这一点,Vue的设计非常注重灵活性和“可以被逐步集成”这个特点。
1.4 Vue版本
目前,在开发中,Vue有两大版本vue2和vue3,老项目一般都是vue2,但是因为vue2已经停止维护了,新的项目一般都是会选择vue3开发(vue3涵盖了vue2的知识体系,当然vue3也增加了许多新的特性)
Windows 安装
访问官方网站下载: 访问Node.js官方网站 Node.js — Run JavaScript Everywhere ,选择"Downloads"页面,找到适合你系统的安装包(推荐使用LTS版本,即长期支持版,更稳定)。
运行安装程序: 下载完成后,双击安装包开始安装。在安装界面,你可以选择是否加入PATH环境变量(建议勾选),这样安装完成后就可以直接在命令行中使用node和npm命令。
验证安装: 安装完成后,打开命令提示符(cmd)或PowerShell,输入以下命令检查安装是否成功:
node -v
npm -v
分别会显示Node.js和npm(Node包管理器)的版本号。
vite 是新一代前端构建工具
优势
总结:
Vue3项目的目录结构与Vue2有些不同,主要是因为Vue3使用了新的模块化系统和TypeScript语言。
以下是一个Vue3项目的典型目录结构:
代码语言:javascript
复制
├── public
│ ├── index.html
│ └── favicon.ico
├── src
│ ├── assets
│ ├── components
│ ├── router
│ ├── store
│ ├── utils
│ ├── views
│ ├── App.vue
│ └── main.ts
├── tests
├── node_modules
├── package.json
├── tsconfig.json
└── README.md
public
:存放静态资源文件,如HTML文件、图片、图标等。 src
:存放源代码文件。 assets
:存放静态资源文件,如CSS、图片、字体等。 components
:存放Vue组件文件。 router
:存放Vue Router路由文件。 store
:存放Vuex状态管理文件。 utils
:存放工具函数文件。 views
:存放页面组件文件。 App.vue
:根组件文件。 main.ts
:入口文件,包括Vue实例的创建和挂载等。 tests
:存放测试文件。 node_modules
:存放项目依赖的第三方库。 package.json
:存放项目的配置信息和依赖库信息。 tsconfig.json
:存放TypeScript编译器的配置信息。
// 引入createApp用于创建应用
import { createApp } from "vue";
// 引入App根组件
import App from "./App.vue";
createApp(App).mount("#app");
<template>
<!-- html -->
</template>
<script lang="ts">
// JS 或 TS
</script>
<style>
/* css样式 */
</style>
<template>
<div class="text">
<h3>模版语法</h3>
<p>{{ msg }}</p>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const msg = ref('神奇的语法')
</script>
<style scoped>
.text{
background-color: #f10808;
box-shadow: 0 0 10px;
border-radius: 10px;
padding: 20px;
}
</style>
每个绑定仅支持单一表达式,也就是一段能够被求值的JavaScript代码。一个简单的判断方法是是否合法地写在 return 后面
<template>
<div class="text">
<h3>模版语法</h3>
<p>{{ count+1 }}</p>
<p>{{ ok? 'YES':'NO' }}</p>
</div>
</template>
<script setup lang="ts">
import { ref,onMounted } from 'vue'
const count = ref(0)
const msg = ref('神奇的语法')
const ok = true
</script>
<style scoped>
.text{
background-color: #f10808;
box-shadow: 0 0 10px;
border-radius: 10px;
padding: 20px;
}
</style>
<!-- 这是一个语句,而非表达式 -->
{{ var a = 1 }}
<!-- 条件控制也不支持,请使用三元表达式 -->
{{ if(ok) { return message } }}
Options类型的 API ,数据、方法、计算属性等、是分散在:data,methods,computed 中的,若想新增或者修改一个需求,就需要分别修改:data,methods,computed,不便于维护和复用。
可以用函数的方式,更加优雅的组织代码,让相关功能的代码更加有序的组织在一起。
setup 概述
setup 是 Vue3 中一个新的配置项,值是一个函数,它是 composition API "表演的舞台",组件中所用到的:数据,方法,计算属性,监视....等等,均配置在 setup 中。
特点如下:
<template>
<!-- html -->
<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 {
name: 'Person', // 组件名称
setup(){
// 数据
let name = '张三' // 注意这样写name不是响应式数据
let age = 12 // 注意这样写age不是响应式数据
let tel = '138888888'
// 方法
function changeName(){
name = '李四 }
function changeAge(){
age += 1 }
function showTel(){
alert(tel)}
// 将数据,方法交出去,模版中才可以使用
return {name,age,tel,changeName,changeAge,showTel}
}
}
</script>
<style>
.person{
background-color: skyblue;
box-shadow: 0 0 10px;
border-radius: 10px;
padding: 20px;
}
button{
margin: 0 5px;
}
</style>
setup 函数有一个语法糖,这个语法糖,可以让我们把 setup 独立出去,代码如下:
<template>
<!-- html -->
<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="Person234">
// 数据
let name = '张三' // 注意这样写name不是响应式数据
let age = 12 // 注意这样写age不是响应式数据
let tel = '138888888'
// 方法
function changeName(){
name = '李四 }
function changeAge(){
age += 1 }
function showTel(){
alert(tel)}
</script>
<style>
.person{
background-color: skyblue;
box-shadow: 0 0 10px;
border-radius: 10px;
padding: 20px;
}
button{
margin: 0 5px;
}
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import VueSetupExtend from 'vite-plugin-vue-setup-extend'
export default defineConfig({
plugins: [
vue(),
VueSetupExtend()
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
作用:定义响应式变量。
语法: let xxx = ref(初始值) .
返回值:一个 RefImpl 的实例对象,简称 ref 对象 或 ref , ref 对象的 value 属性是响应式的。
注意点:
作用:定义一个响应式对象(基本类型不要用它,要用ref,否则报错)
语法:let 响应式对象= reactive(源对象)
返回值:一个Proxy的实例对象,简称:响应式对象。
注意点:reactive定义的响应式数据是“深层次”的。
其实
ref
接收的数据可以是:基本类型(详细可以看3.3)、对象类型。
使用ref函数可以将一个初始值(不论是基本类型还是对象/数组)封装成一个响应式引用。例如,定义一个对象类型的响应式数据:
import { ref } from 'vue';
const user = ref({ name: '张三', age: 25 });
在这个例子中,user是一个响应式引用,其.value属性包含实际的对象数据。
访问ref包裹的值时,需要通过.value来读取或修改其内部的值。在JavaScript代码中:
console.log(user.value.name); // 输出: 张三
user.value.name = '李四'; // 更新用户名
而在Vue模板中,可以直接使用user,Vue会自动解包.value给你:
<template>
<div>{{ user.name }}</div>
</template>
当ref包裹的对象内部属性发生变化时,Vue的响应系统会自动追踪并触发依赖更新,确保UI能够相应地更新。
组件的生命周期:创建、挂载、更新、销毁
Vue2的生命周期
Vue 2 提供了以下生命周期钩子函数:
每个钩子函数都有其特定的用途,可以帮助您在组件的生命周期中执行特定的任务。
Vue3的生命周期
Vue 3的Composition API通过setup()函数引入,它没有直接对应Vue 2中的生命周期钩子,但提供了类似功能的组合式API。
常用的钩子:onMounted(挂载完毕)、onUpdated(更新完毕)、onBeforeUnmount(卸载之前)
示例代码
import { ref,onBeforeMount,onMounted,onBeforeUpdate,onUpdated,onBeforeUnmount,onUnmounted } from 'vue'
// 数据
let sum = ref(0)
// 方法
function changeSum(){
sum.value += 1
console.log(sum.value);
}
// 创建
console.log('创建')
// 挂载前
onBeforeMount(()=>{
console.log('挂载前');
})
// 挂载完毕
onMounted(()=>{
console.log('挂载完毕');
})
// 更新前
onBeforeUpdate(()=>{
console.log('更新前');
})
// 更新完毕
onUpdated(()=>{
console.log('更新完毕');
})
// 卸载前
onBeforeUnmount(()=>{
console.log('卸载前');
})
// 卸载完毕
onUnmounted(()=>{
console.log('卸载完毕');
什么是hook?—— 本质是一个函数,把setup函数中使用的Composition API进行了封装,类似于vue2.x中的mixin。
Vue 3 的路由系统是基于 Vue Router 4.x 的,以下是 Vue 3 中路由的基本使用方法:
安装 Vue Router
npm install vue-router
首先,你需要定义你的路由。每个路由映射到一个组件。创建一个components同级的router文件夹。例如:
然后创建一个router-->index.ts文件:
import {createRouter, createWebHistory} from 'vue-router'
import Home from '@/components/Home.vue'
import About from '@/components/About.vue'
import News from '@/components/News.vue'
const router = createRouter({
history: createWebHistory(), // 路由模式
routes: [ // 路由规则
{
path: '/home', //路径
component: Home
},
{
path: '/about',
component: About
},
{
path: '/news',
component: News
}
]
})
export default router
import { createApp } from "vue";
// 引入App根组件
import App from "./App.vue";
// 引入路由
import router from './router'
// 创建应用
const app = createApp(App);
// 使用路由器
app.use(router)
// 挂载整个应用到app容器中
app.mount("#app");
# 另外一种写法
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
在组件内部,你可以使用<router-link>进行导航,以及使用<router-view>来显示路由对应的组件:
<template>
<!-- html -->
<div class="app">
<h2 class="title">Vue路由测试</h2>
<!-- 导航区 -->
<div class="navigate">
<RouterLink to="/home" active-class="active">首页</RouterLink>
<RouterLink to="/news" active-class="active">新闻</RouterLink>
<RouterLink to="/about" active-class="active">关于</RouterLink>
</div>
<!-- 测试区 -->
<div class="main-content">
<router-view/>
</div>
</div>
</template>
<script lang="ts" setup>
import { RouterLink } from 'vue-router';
</script>
<RouterLink to="/home" active-class="active">首页</RouterLink>
<RouterLink :to="{path:'/home'}" active-class="active">首页</RouterLink>
优点:URL更加美观,不带有#,更接近传统的网站URL。
缺点:后期项目上线,需要服务端配合处理路径问题,否则刷新会有404错误。
const router = createRouter({
history:createWebHistory(), // history模式
/****/
})
优点:兼容性更好,因为不需要服务器端处理路径。
缺点:URL带有#不太美观,且在SEO优化方面相对较差.
作用:可以简化路由跳转及传参
const router = createRouter({
history: createWebHistory(), // 路由模式
routes: [ // 路由规则
{
name: 'home',
path: '/home', //路径
component: Home
},
{
name: 'about',
path: '/about',
component: About
},
{
name: 'news',
path: '/news',
component: News,
children: [
{
name: 'detail',
path: 'detail',
component: Detail
}
]
}
]
})
<!-- 第一种写法 -->
<!--简化前:需要写完整的路径(to的字符串写法) -->
<!-- <RouterLink :to="`/news/detail?id=${news.id}&title=${news.title}&content=${news.content}`">{{ news.title }}</RouterLink> -->
<!-- 第二种写法 -->
<!--简化后:直接通过名字跳转(to的对象写法配合name属性) -->
<router-link :to="{name:'guanyu'}">跳转</router-link>
接下来,定义你的路由。嵌套路由通常涉及定义一个父路由,该路由可以包含一个或多个子路由。下面是一个简单的示例,定义了一个news组件作为父路由,它有一个子路由:detail。
// 创建一个路由器,并暴露出去
// 第一步:引入createRouter
import {createRouter, createWebHistory} from 'vue-router'
import Home from '@/views/Home.vue'
import About from '@/views/About.vue'
import News from '@/views/News.vue'
import Detail from '@/views/Detail.vue'
// 第二步:创建路由器
const router = createRouter({
history: createWebHistory(), // 路由模式
routes: [ // 路由规则
{
name: 'home',
path: '/home', //路径
component: Home
},
{
name: 'about',
path: '/about',
component: About
},
{
name: 'news',
path: '/news',
component: News,
children: [
{
name: 'detail',
path: 'detail',
component: Detail
}
]
}
]
})
// 第三步:导出路由
export default router
注意:记得要加完整路径
在你的主组件中,使用<router-view>来渲染父路由的组件,同时在父组件内部使用另一个<router-view>来渲染子路由的组件。
<router-link to="/news/detail">xxxx</router-link>
<!-- 或 -->
<router-link :to="{path:'/news/detail'}">xxxx</router-link>
<!-- 跳转并携带query参数(to的字符串写法)(我个人不喜欢这种写法) -->
<router-link to="/news/detail?a=1&b=2&content=欢迎你">
跳转
</router-link>
<!-- 跳转并携带query参数(to的对象写法) (我更喜欢这样的写法)-->
<RouterLink
:to="{
//name:'xiang', //用name也可以跳转
path:'/news/detail',
query:{
id:news.id,
title:news.title,
content:news.content
}
}"
>
{{news.title}}
</RouterLink>
<template>
<div class="news-list">
<li>编号:{{ query.id }}</li>
<li>标题:{{ query.title }}</li>
<li>内容:{{ query.content }}</li>
</div>
</template>
<script setup lang="ts">
import { toRefs } from 'vue';
import { useRoute } from 'vue-router'
let route = useRoute()
let {query} = toRefs(route)
</script>
<!-- 跳转并携带params参数(to的字符串写法) -->
<RouterLink :to="`/news/detail/001/新闻001/内容001`">{{news.title}}</RouterLink>
<!-- 跳转并携带params参数(to的对象写法) -->
<RouterLink
:to="{
name:'xiang', //用name跳转
params:{
id:news.id,
title:news.title,
content:news.title
}
}"
>
{{news.title}}
</RouterLink>
import {useRoute} from 'vue-router'
const route = useRoute()
// 打印params参数
console.log(route.params)
温馨提示
备注1:传递params参数时,若使用to的对象写法,必须使用name配置项,不能用path。
备注2:传递params参数时,需要提前在规则中占位
作用:让路由组件更方便的收到参数(可以将路由参数作为props传给组件)
props忘记的可以回头翻看(3.12)
children: [
{
name: 'detail',
path: 'detail',
component: Detail,
// 第一种写法:将路由收到的所有params参数作为props传给路由组件
// props: true
// 第二种写法:函数写法,可以自己决定将什么作为props给路由组件
props: (route)=>{
return route.query
}
// 第三种写法:对象写法,可以自己决定将什么作为props给路由组件
/* props:{
a: '我是新闻列表的摘要',
b: '我是新闻列表的标题',
c: '我是新闻列表的作者'
} */
}
]
作用:控制路由跳转时操作浏览器历史记录的模式。
浏览器的历史记录有两种写入方式:分别为push和replace:
push是追加历史记录(默认值)。
replace是替换当前记录。
开启replace模式
<RouterLink replace .......>News</RouterLink>
实际上这种写法用的更多一些
编程式路由导航是指在Vue应用中通过JavaScript代码来控制路由的导航,而不是通过HTML中的<router-link>标签。这种方式提供了更多的灵活性和控制能力,特别是在需要根据条件或逻辑来决定导航路径的情况下非常有用。
在Vue 3中,编程式路由导航可以通过Vue Router提供的方法来实现。下面是一些常用的方法:
1、使用router.push()
router.push()方法是最常用的编程式导航方法之一,用于导航到一个新的位置。它可以接受一个路由对象或一个相对路径作为参数。
实例
import { useRouter } from 'vue-router';
let router = useRouter()
router.push({
name: 'detail',
query:{
id:news.id,
title:news.title,
content:news.content
}
})
2、使用router.replace()
router.replace()方法与router.push()类似,但不同之处在于它不会在浏览器的历史堆栈中添加新的记录,而是替换当前的历史记录。
实例
import { useRouter } from 'vue-router';
let router = useRouter()
router.push({
name: 'detail',
replace:{
id:news.id,
title:news.title,
content:news.content
}
})
作用:将特定的路径,重新定向到已有路由。
实例
{
path:'/',
redirect:'/about'
}
Pinia 是一个 Vue 专用的状态管理库,它提供了一种简洁、易于理解和使用的状态管理模式。Pinia 的设计目标是尽可能地保持简单,同时又足够强大以满足大多数状态管理的需求。在 Vue 3 中,Pinia 是一个非常受欢迎的选择,尤其是在那些需要状态管理但又不想引入像 Vuex 这样较重的解决方案的项目中。
Pinia 的特点
首先,你需要安装 Pinia。可以通过 npm 进行安装:
npm install pinia
操作src/main.ts
// 引入createApp用于创建应用
import { createApp } from "vue";
// 引入App根组件
import App from "./App.vue";
// 引入路由
import router from './router'
// 引入pinia
import { createPinia } from 'pinia'
// 创建应用
const app = createApp(App);
// 创建pinia
const pinia = createPinia()
// 使用pinia
app.use(pinia)
// 使用路由器
app.use(router)
// 挂载整个应用到app容器中
app.mount("#app");
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。