需要node16版本或者以上,
npm init vue@latest


在vue3中所有的创建都用了函数封装,保证了每个实例的独立性
setup组合式api
1、执行时间比beforeCreate还早
2、setup函数,获取不到this
3、数据和函数需要return出去才可以使用
<script>
export default {
setup(){
console.log("setup", this)
const message = "消息"
const aaa = () =>{
console.log("函数调用")
}
return {
message,
aaa
}
},
beforeCreate() {
console.log("beforeCreate")
}
}
script>
<template>
<div>{{message}}div>
<button @click="aaa">点击按钮button>
template>
)不需要return就可以使用函数和参数
<script setup>
const message = "消息"
const aaa = () =>{
console.log("函数调用")
}
script>
<template>
<div>{{message}}div>
<button @click="aaa">点击按钮button>
template>


<script setup>
import { reactive } from 'vue'
const state = reactive({
count: 100
})
const aaa = () => {
state.count++
}
script>
<template>
<div>{{state.count}}div>
<button @click="aaa">增加button>
template>
实际上ref是被给包了一层,可以打印看到变成了对象
1、在js中需要
变量.value去拿到值
2、在vue的template可以直接拿到值(vue3给拔了一层)
<script setup>
import { ref } from 'vue'
const count = ref(0)
console.log("包装了对象", count)
console.log("取值", count.value)
const aaa = () => {
count.value++
}
script>
<template>
<div>{{count}}div>
<button @click="aaa">增加button>
template>
<script setup>
import { ref, computed } from 'vue'
const list = ref([0,1,2,3,4,5])
const computedList = computed(()=>{
return list.value.filter(item => item > 2)
})
const aaa = () => {
list.value.push("666")
}
script>
<template>
<div>{{ list }}div>
<div>{{ computedList }}div>
<button @click="aaa">增加button>
template>
<script setup>
import { ref, computed } from 'vue'
const count = ref(1)
const computedList = computed({
//简写get: () => count.value + 1
get() {
return count.value + 1
},
set(val){
console.log(val)
count.value = val
}
})
const aaa = () => {
computedList.value = 100
}
script>
<template>
<div>{{ computedList }}div>
<button @click="aaa">增加button>
template>
<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
const name = ref('张三')
const setName = () => {
name.value = "里斯"
}
const setCount = () => {
count.value = 18
}
// 单个监听
watch(count, (newValue, oldValue)=>{
if (newValue == 18) {
name.value = "小伙子"
}
})
script>
<template>
<div>{{count}}div>
<div>{{name}}div>
<button @click="setName">修改名称button>
<button @click="setCount">修改年龄button>
template>
<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
const name = ref('张三')
const setName = () => {
name.value = "里斯"
}
const setCount = () => {
count.value = 18
}
//多个监听
watch([count, name], (newValue, oldValue)=>{
console.log(newValue, oldValue)
})
script>
<template>
<div>{{count}}div>
<div>{{name}}div>
<button @click="setName">修改名称button>
<button @click="setCount">修改年龄button>
template>

deep:true 对复杂类型进行深度监听
immdiate:true 页面初始化 立刻执行一次
这边就简写了
<script setup>
import { ref, watch } from 'vue'
const count = ref(0)
const name = ref('张三')
const setName = () => {
name.value = "里斯"
}
const setCount = () => {
count.value = 18
}
//多个监听
watch([count, name], (newValue, oldValue)=>{
console.log(newValue, oldValue)
},{
deep:true,
immdiate:true
})
script>
<template>
<div>{{count}}div>
<div>{{name}}div>
<button @click="setName">修改名称button>
<button @click="setCount">修改年龄button>
template>



语法
实例:其中:money是动态绑定的,到子组件就会动态变化

语法

案例

ref调用子组件内的方法
子组件
父组件

语法 顶层组件也可以把函数传递下去
语法:

例子

父组件

子组件
1、先接prop
2、注册emit发送事件
3、监听组件value
4、发送组件消息

语法

案例

vite.config.js中开启)
安装
npm install pinia
导包
import { createApp } from 'vue'
import App from './App.vue'
//1、导入
import { createPinia } from 'pinia'
//2、.use(createPinia())
createApp(App).use(createPinia()).mount('#app')
使用
新建目录store,新建counter.js
import { defineStore } from "pinia";
import { ref,computed } from "vue";
export const useCounterStore = defineStore('counter', () => {
//声明变量
const count = ref(100)
//声明函数action
const addCount = () => count.value++
const subCount = () => {
count.value--
}
//计算属性getters(computed)
const double = computed(() => count.value * 2)
//声明变量
const msg = ref('hello')
return {
addCount,
subCount,
count,
msg,
double
}
})
App.vue
<script setup>
import Son1Com from '@/components/Son1Com.vue';
import Son2Com from '@/components/Son2Com.vue';
script>
<template>
<Son1Com>Son1Com>
<Son2Com>Son2Com>
template>
Son1Com
<script setup>
import { useCounterStore } from '@/store/counter'
const counterStore = useCounterStore()
script>
<template>
<h1>{{ counterStore.count }}h1>
<div>我是Son1div>
<button @click="counterStore.addCount">+button>
<h3>{{counterStore.double}}h3>
template>
Son2Com
<script setup>
import { useCounterStore } from '@/store/counter'
const counterStore = useCounterStore()
script>
<template>
<h1>{{ counterStore.count }}h1>
<div>我是Son2div>
<button @click="counterStore.subCount">-button>
template>

注意直接解构不会响应式
如何变成响应式

官网
使用
安装
npm i pinia-plugin-persistedstate
将插件添加到 pinia 实例上在main.js当中
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
createApp(App).use(pinia).mount('#app')
使用在counter.js中
import { defineStore } from "pinia";
import { ref,computed } from "vue";
export const useCounterStore = defineStore('counter', () => {
//声明变量
const count = ref(100)
return {
count
}
},{
// 开启持久化
persist: true,
})
持久化参数
import { defineStore } from "pinia";
import { ref,computed } from "vue";
export const useCounterStore = defineStore('counter', () => {
//声明变量
const count = ref(100)
return {
count
}
},{
// 开启持久化
persist: {
//看文档
}
})
其中paths持久存储哪些值
记得在main.js中vue实体记得use一下pinia

使用
命令
npm install -g pnpm
pnpm create vue

项目创建
vscode中prettier插件卸载
安装ESLint插件
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = {
root: true,
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-prettier/skip-formatting'
],
parserOptions: {
ecmaVersion: 'latest'
},
//此处开始配置
rules: {
'prettier/prettier': [
'warn',
{
singleQuote: true, //单引号
semi: false, //无分号
printWith: 80, //行宽
trailingComma: 'none', //不加对象|数组最后的逗号
endOfLine: 'auto' // 换行符号不限
}
],
//ESLint关注代码规范
'vue/multi-word-component-names': [
'warn',
{
ignores: ['index'] //vue组件名称多单词组成(忽略index.vue)
}
],
'vue/no-setup-props-destructure': ['off'], //关闭prop结构的校验(props结构丢失响应式)
//变量未定义报错
'no-undef': 'error'
}
}


1和2加上去
{
"explorer.confirmDelete": false,
"security.workspace.trust.untrustedFiles": "open",
"workbench.editorAssociations": {
"*.dll": "default"
},
// 1保存自动修复
"editor.codeActionsOnSave": {
"source.fixAll": true
},
// 2关闭保存自动格式化
"editor.formatOnSave": false
}

简单介绍

其中这个文件是router文件夹下的index.js文件
import.meta.env.BASE_URL这个是比如使用了hash模式,其中那个#号可以在这通过变量传来,变量在vite.config.js文件中
语法
支持vue2的用法直接在模板中进行$xxx.push
pnpm add axios
封装跟vue2差不多,你自己看着找找
唯一不同的就是next换成了
//全局前置路由,配合浏览器localStorage进行鉴权操作
const urls = ['/pay','/myOrder']
router.beforeEach((to, from, next) =>{
// console.log(to, from);
if(!urls.incloudes(to.path)){
return true
}
//如果没有token并且还是鉴权路径
return '/login'
})
// 全局后置路由,简单写一个弹窗,在进入每一个路由组件后弹出一句话
router.afterEach(() =>{
alert('欢迎你!!');
})