一篇文章弄懂vue3常用API

目录

    • 1、使用vite创建项目
    • 2、建立路由router
    • 3、引入vuex
    • 4、引入elementPlus
    • 6、ref,reactive
    • 7、生命周期钩子
    • 8、计算属性computed
    • 9、侦听器watch
    • 10、父子传值props
      • a、父传子
      • b、子传父
    • 11、Provide/inject传值(不限层级)
    • 12、slots 和 attrs
    • 13、defineExpose(对外暴露属性)
    • 14、toRef和toRefs
    • 15、shallowReactive、shallowRef和triggerRef
    • 16、toRaw、markRaw
    • 17、getCurrentInstance(慎用)
    • 18、获取标签dom元素。
    • 19、CSS变量注入
    • 20、vue3插槽
      • a、匿名插槽
      • b、具名插槽
      • c、作用域插槽
    • 21、pinia的使用
      • 安装
      • 创建store仓库
      • 数据持久化
    • 22、vue3+ts的使用
    • 23、基于vite创建vue3
    • 24、setup语法糖插件

1、使用vite创建项目

npm init @vitejs/app vue3-vite-demo

2、建立路由router

打开文件,建立router路由文件,建立index.js文件
一篇文章弄懂vue3常用API_第1张图片

import { createRouter, createWebHashHistory } from "vue-router";
import globalRoutes from "./globalRoutes";
import mainRoutes from "./mainRoutes";

const router = createRouter({
  history: createWebHashHistory(),
  scrollBehavior: () => ({ y: 0 }),
  isAddDynamicMenuRoutes: false, // 是否已经添加动态(菜单)路由
  routes: globalRoutes.concat(mainRoutes),
});
export default router;

安装路由命令

npm install vue-router@4
/或
npm install vuex@next --save

运行项目可能出现报错,是因为安装的vue-router版本是3及以下。要安装v4版本还有createRouter等Api。如果安装了还是有报错,关闭项目,重启服务器即可。
一篇文章弄懂vue3常用API_第2张图片
路由建立好了之后在main.js里引用
一篇文章弄懂vue3常用API_第3张图片
这时候路由引用完毕。

路由跳转

一篇文章弄懂vue3常用API_第4张图片
接受路由参数query或params
在这里插入图片描述

import { useRouter } from "vue-router";
const router = useRouter();
router.push({ name: "" });

另开一个页面的路由跳转方式

  const { href } = router.resolve({
      name: "softwares",
      query: { basicInfoId: row.basicInfoId },
    });
    window.open(href, "_blank");

修改Vite的配置文件,支持alias别名@(路径名指定@为src)
一篇文章弄懂vue3常用API_第5张图片

import { defineConfig } from 'vite'
import path from 'path'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
    }
  },
  plugins: [vue()]
})

3、引入vuex

安装vuex

npm install vuex@next --save

main.js中引入
一篇文章弄懂vue3常用API_第6张图片

一篇文章弄懂vue3常用API_第7张图片

import { createStore } from 'vuex'

export default createStore({
  state: {
    name: ''
  },
  mutations: {
    name: (state, newValue) => {
      state.name = newValue
    }
  },
  actions: {
    setName: (ctx, value) => {
      console.log(ctx);
      console.log(value);
      ctx.commit('name', value)
    }
  }
})

页面中使用
一篇文章弄懂vue3常用API_第8张图片
使用模块化vuex
src\store\index.js建立模块化
一篇文章弄懂vue3常用API_第9张图片
建立common模块
一篇文章弄懂vue3常用API_第10张图片
全局通用模块,可要可不要
一篇文章弄懂vue3常用API_第11张图片
页面中使用
一篇文章弄懂vue3常用API_第12张图片

4、引入elementPlus

npm install element-plus --save

完整引入和按需引入参照官网https://element-plus.gitee.io/zh-CN/guide/quickstart.html

一篇文章弄懂vue3常用API_第13张图片

6、ref,reactive

reactive 和 ref 都是用来定义响应式数据的, reactive更推荐去定义复杂的数据类型, ref 更推荐定义基本类型

ref 和 reactive 本质我们可以简单的理解为ref是对reactive的二次包装, ref定义的数据访问的时候要多一个.value
一篇文章弄懂vue3常用API_第14张图片

7、生命周期钩子

一篇文章弄懂vue3常用API_第15张图片
一篇文章弄懂vue3常用API_第16张图片

8、计算属性computed

一篇文章弄懂vue3常用API_第17张图片
还可以在reactive中直接使用

const data=reactive({
		name:"zhangyi",
		username:computed(()=>{
			return data.name.slice(1,2)
		})
	})

9、侦听器watch

监听reactive响应式数据中的某个属性,要将箭头函数写成函数return的方式才有效。
一篇文章弄懂vue3常用API_第18张图片

如果监视的是reactive定义的响应式数据,则无法正确获得oldValue!!!
一篇文章弄懂vue3常用API_第19张图片
watch 和 watchEffect 都是侦听器,但是写法和使用上有一些区别。
watch:

1.具有一定的惰性lazy 第一次页面展示的时候不会执行,只有数据变化的时候才会执行
2.参数可以拿到当前值和原始值
3.可以侦听多个数据的变化,用一个侦听起承载

watchEffect :

没有过多的参数 只有一个回调函数
1.立即执行,没有惰性,页面的首次加载就会执行。
2.自动检测内部代码,代码中有依赖 便会执行
3.不需要传递要侦听的内容 会自动感知代码依赖,不需要传递很多参数,只要传递一个回调函数
4.不能获取之前数据的值 只能获取当前值
5.一些=异步的操作放在这里会更加合适

监听对象p中的name属性
一篇文章弄懂vue3常用API_第20张图片
监听器对象形式写法

watch:{
	obj:{
		handle(newVal,oldVal){
			console.log(newVal,oldVal)
		},
		immediate:true,
		deep:true
	}
}

10、父子传值props

a、父传子

父组件
一篇文章弄懂vue3常用API_第21张图片
子组件
一篇文章弄懂vue3常用API_第22张图片

b、子传父

子组件
一篇文章弄懂vue3常用API_第23张图片
父组件
一篇文章弄懂vue3常用API_第24张图片
vue2中sync写法在vue3中的使用。(父子组件传值响应式,即子组件发生改变,父组件同步改变)

父组件
必须使用v-model形式传值给子组件
一篇文章弄懂vue3常用API_第25张图片
子组件
先通过defineProps接受传递过来的name,然后通过defineEmits和update:name使用父子数据双向绑定
一篇文章弄懂vue3常用API_第26张图片
注:上方写错了。const emit = defineEmits([“name”])修改为上方const emit = defineEmits([“update:name”])

11、Provide/inject传值(不限层级)

Provide/inject用于不限层级的传值,父组件中Provide参数,子或孙组件都可通过inject拿到参数值。
父组件
一篇文章弄懂vue3常用API_第27张图片
子组件
一篇文章弄懂vue3常用API_第28张图片

12、slots 和 attrs

可以通过useContext从上下文中获取 slots 和 attrs。不过提案在正式通过后,废除了这个语法,被拆分成了useAttrs和useSlots。示例:

// 旧
<script setup>
  import { useContext } from 'vue'
 
  const { slots, attrs } = useContext()
</script>
 
// 新
<script setup>
  import { useAttrs, useSlots } from 'vue'
  
  const slots = useSlots();
  const attrs = useAttrs();
  console.log(attrs); // 查看父组件传来的自定义属性
</script>

attrs

父组件的标签可以加各种"属性",能和props对应上的就变成了子组件的props,对应不上的就都是attrs,不限于函数,各种类型都行。
一篇文章弄懂vue3常用API_第29张图片
一篇文章弄懂vue3常用API_第30张图片
如果没有声明defineProps接收父传递过来的属性,则由useAttrs接收。如果声明了defineProps接收,则useAttrs为空。
console.log(attrs)打印如下
一篇文章弄懂vue3常用API_第31张图片

13、defineExpose(对外暴露属性)

子组件使用defineExpose对外暴露属性
一篇文章弄懂vue3常用API_第32张图片
父组件可接受到子组件暴露出来的属性
一篇文章弄懂vue3常用API_第33张图片

14、toRef和toRefs

toRef 是将某个对象中的某个值转化为响应式数据,其接收两个参数,第一个参数为 obj 对象;第二个参数为对象中的属性名。
一篇文章弄懂vue3常用API_第34张图片
区别:
ref 是对传入数据的拷贝;toRef 是对传入数据的引用
ref 的值改变会更新视图;toRef 的值改变不会更新视图

toRefs作用就是将传入的对象里所有的属性的值都转化为响应式数据对象,该函数支持一个参数,即 obj 对象。
一篇文章弄懂vue3常用API_第35张图片

15、shallowReactive、shallowRef和triggerRef

shallowReactive这是一个浅层的 reactive,原本的 reactive 是深层的,shallowReactive这是一个用于性能优化的API。优化reactive

const obj = {
            a: 1,
            first: {
                b: 2,
                second: {
                    c: 3
                }
            }
        }
//如果使用reactive包裹,则obj的每一层都是proxy响应式数据对象,
//某些情况下对性能有影响
const state = reactive(obj)
//如果使用shallowReactive包裹,则只有第一层a:1是proxy响应式数据对象,
//只有第一层a发生改变了才会触发页面改变,b、c改变只会改变值,
//不会触发视图更新。
const state = shallowReactive(obj)

shallowRef,这是一个浅层的 ref,与 shallowReactive 一样是拿来做性能优化的,优化ref
shallowReactive 是监听对象第一层的数据变化用于驱动视图更新,那么 shallowRef 则是监听 .value 的值的变化来更新视图的
一篇文章弄懂vue3常用API_第36张图片
可以看出在change2方法里通过.value改变属性的方式不会触发视图更新。但是可以引入triggerRef方法触发视图更新
一篇文章弄懂vue3常用API_第37张图片

16、toRaw、markRaw

toRaw 方法是用于获取 ref 或 reactive 对象的原始数据的
一篇文章弄懂vue3常用API_第38张图片
在这里插入图片描述
可以看出reactive数据会使原始数据也发生改变。如果要获取原始数据,则通过toRaw方法获取:
一篇文章弄懂vue3常用API_第39张图片
注意: 补充一句,当 toRaw 方法接收的参数是 ref 对象时,需要加上 .value 才能获取到原始数据对象

markRaw 方法可以将原始数据标记为非响应式的,即使用 ref 或 reactive 将其包装,仍无法实现数据响应式,其接收一个参数,即原始数据,并返回被标记后的数据。
一篇文章弄懂vue3常用API_第40张图片
一篇文章弄懂vue3常用API_第41张图片

代码中可以看到,被markRaw包裹的obj再进行reactive包裹,也不会成为响应式数据。

17、getCurrentInstance(慎用)

Vue2的任何一个组件中想要获取当前组件的实例可以通过 this 来得到,而在Vue3中我们大量的代码都在 setup 函数中运行,并且在该函数中 this 指向的是 undefined,所以这里要使用getCurrentInstance方法获取实例
一篇文章弄懂vue3常用API_第42张图片

一篇文章弄懂vue3常用API_第43张图片一篇文章弄懂vue3常用API_第44张图片
在这里插入图片描述
ctx 和 proxy 的内容十分类似,只是后者相对于前者外部包装了一层 proxy,由此可说明 proxy 是响应式的。
**注意:**开发环境下才能获取到当前组件的实例,换句话说就是这个方法只是在开发环境下用于调试使用的;在生产环境下拿不到实例。 大家不要依赖 getCurrentInstance 方法去获取组件实例来完成一些主要功能,否则在项目打包后,一定会报错的。

18、获取标签dom元素。

在Vue2中,我们获取元素都是通过给元素一个 ref 属性,然后通过 this.$refs.xx 来访问的,但这在Vue3中已经不再适用了
一篇文章弄懂vue3常用API_第45张图片

19、CSS变量注入

<template>
  <span>zhangyi</span>  
</template>
 
<script setup>
  import { reactive } from 'vue'
 
  const state = reactive({
    color: 'red'
  })
</script>
  
<style scoped>
  span {
    // 使用v-bind绑定state中的变量
    color: v-bind('state.color');
  }  
</style>

20、vue3插槽

a、匿名插槽

一篇文章弄懂vue3常用API_第46张图片

b、具名插槽

一篇文章弄懂vue3常用API_第47张图片

c、作用域插槽

描述:作用域插槽其实就是带数据的插槽,即带参数的插槽,简单的来说就是子组件提供给父组件的参数,该参数仅限于插槽中使用,父组件可根据子组件传过来的插槽数据来进行不同的方式展现和填充插槽内容。

插槽名可以是动态变化的v-slot:[slotName]
一篇文章弄懂vue3常用API_第48张图片
以下是vue2的插槽,在vue2.6中。下述的API被软废弃(3.0正式废弃),取而代之的是内置指令v-slot,可以缩写为【#】

// Parent.vue
<child>
  <!-- 默认插槽 -->
  <div>默认插槽</div>  
  <!-- 具名插槽 -->
  <div slot="header">具名插槽header</div>
  <!-- 作用域插槽 -->
  //data同上,是子组件传递过来的值
  <div slot="footer" slot-scope="data">
    {{data.name}}
  </div>
</child>

21、pinia的使用

官网地址:https://pinia.vuejs.org/
Pinia.js是由Vue.js团队核心成员开发的新一代状态管理器,使用Composition Api进行重新设计的,也被视为下一代Vuex。Pinia是一个Vue的状态管理库,允许跨组件、跨页面进行全局共享状态,也由于其设计的简洁性、和对typescript的良好支持,取代Vuex指日可待。

Pinia.js 有如下特点:

1、完整的 typescript 的支持;
2、足够轻量,压缩后的体积只有1.6kb;
3、去除 mutations,只有 state,getters,actions(这是我最喜欢的一个特点);
4、actions 支持同步和异步;
5、没有模块嵌套,只有 store 的概念,store 之间可以自由使用,更好的代码分割;
6、无需手动添加 store,store 一旦创建便会自动添加;

安装

$ yarn add pinia
$ npm i pinia
$ pnpm i pinia

一篇文章弄懂vue3常用API_第49张图片
main.js中引入

//main.js
import { createPinia } from 'pinia'
const pinia = createPinia()
app.use(pinia)

一篇文章弄懂vue3常用API_第50张图片

创建store仓库

//src/store/index.js
import { defineStore } from 'pinia';
export const mainStore = defineStore("main", {
  state() {
    return {
      name: 'hello pinia',
      age: 20
    }
  },
  getters: {
    get() {
      return this.name + "," + 'zhangyi';
    }
  },
  actions: {
    increment() {
      this.age++;
    }
  }
})

页面使用
一篇文章弄懂vue3常用API_第51张图片

但一般不建议store.age++直接修改,建议通过 actions 去修改 state,action 里可以直接通过 this 访问。

<template>
  <div>
    <div> {{store.age}}</div>
    <div> {{store.name}}</div>
    <!-- 使用store里的getter -->
    <div>{{store.get}}</div>
    <div><button @click="add"> add</button></div>
    <div><button @click="addObj"> addObj</button></div>
    <div><button @click="addFun"> addFun</button></div>
    <div><button @click="addAction"> addAction</button></div>
  </div>
</template>
<script lang="ts" setup>
import { reactive, ref } from "vue";
import { mainStore } from "@/store/index";
const store = mainStore();

//单条数据修改
const add = () => {
  store.age++;
  console.log(store.age);
};
//多条数据修改--对象形式
const addObj = () => {
  store.$patch({
    age: store.age + 2,
    name: "zhangyi",
  });
};
//多条数据修改--函数形式
const addFun = () => {
  store.$patch((state: any) => {
    state.age = store.age + 2;
    state.name = "zhangyi";
  });
};
//通过action修改
const addAction = () => {
  store.increment();
};
</script>
<style lang='less' scoped>
</style>

解构store
当store中的多个参数需要被使用到的时候,为了更简洁的使用这些变量,我们通常采用结构的方式一次性获取所有的变量名

ES传统方式解构(能获取到值,但是不具有响应性)
一篇文章弄懂vue3常用API_第52张图片

<template>
  <div>
    <div>ES传统方式解构(能获取到值,但是不具有响应性)</div>
    <div> {{age}}</div>
    <div> {{name}}</div>
  </div>
</template>
<script lang="ts" setup>
import { reactive, ref } from "vue";
import { mainStore } from "@/store/index";
const store = mainStore();
const { name, age } = store;
</script>
<style lang='less' scoped>
</style>

Pinia解构方法:storeToRefs

应该像composition API使用props一样,从pinia中导出storeToRefs进行获取响应式数据。
一篇文章弄懂vue3常用API_第53张图片

<template>
  <div>
    <div>Pinia解构方法:storeToRefs</div>
    <div> {{age}}</div>
    <div> {{name}}</div>
  </div>
</template>
<script lang="ts" setup>
import { reactive, ref } from "vue";
import { mainStore } from "@/store/index";
import { storeToRefs } from "pinia";
const store = mainStore();
const { name, age } = storeToRefs(store);

</script>
<style lang='less' scoped>
</style>

store之间的相互调用
新建同级别store
一篇文章弄懂vue3常用API_第54张图片

import { defineStore } from 'pinia';
export const allanStore = defineStore("allan", {
  state() {
    return {
      moveList: ["蜘蛛侠"]
    }
  },
  getters: {},
  actions: {}
})

在原 store 中引入 allanStore,并获取 moveList
一篇文章弄懂vue3常用API_第55张图片

import { defineStore } from 'pinia';
import { allanStore } from './allanStore'
export const mainStore = defineStore("main", {
  state() {
    return {
      name: 'hello pinia',
      age: 20
    }
  },
  getters: {
    get() {
      return allanStore().moveList;
    }
  },
  actions: {
    increment() {
      this.age++;
    }
  }
})

数据持久化

插件 pinia-plugin-persist 可以辅助实现数据持久化功能。

npm i pinia-plugin-persist --save

使用

// main.js
import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
const pinia = createPinia()
pinia.use(piniaPluginPersist)

接着在对应的 store 里开启 persist 即可。

import { defineStore } from 'pinia';
export const mainStore = defineStore("main", {
  state() {
    return {
      name: 'hello pinia',
      age: 20
    }
  },
  getters: {
    get() {
      return this.name + "," + 'zhangyi';
    }
  },
  actions: {
    increment() {
      this.age++;
    }
  },
  // 开启数据缓存
  persist: {
    enabled: true
  }
})

自定义 key
可以在 strategies 里自定义 key 值,并将存放位置由 sessionStorage 改为 localStorage。

persist: {
  enabled: true,
  strategies: [
    {
      key: 'main',
      storage: localStorage,
    }
  ]
}

持久化 state中某个变量

state: () => {
  return {
    name: '张三',
    age: 18,
    gender: '男'
  }  
},

persist: {
  enabled: true,
  strategies: [
    {
      storage: localStorage,
      paths: ['name', 'age']
    }
  ]
}

上面我们只持久化 name 和 age,并将其改为localStorage, 而 gender 不会被持久化,如果其状态发送更改,页面刷新时将会丢失,重新回到初始状态,而 name 和 age 则不会。

22、vue3+ts的使用

一篇文章弄懂vue3常用API_第56张图片

23、基于vite创建vue3

命令

npm init @vitejs/app 项目名称

然后把vue3的src删掉,把vue-cli创建的vue3里面的src文件复制粘贴过来。再把package.json复制粘贴过来即可。

24、setup语法糖插件

unplugin-auto-import

解决场景:在组件开发中无需每次都引入import { ref,onmounted…}等等

1、下载安装

npm i unplugin-auto-import -D

2、配置:vite.config.js中
一篇文章弄懂vue3常用API_第57张图片

/*
 * @Descripttion: 
 * @Date: 2022-09-20 16:30:03
 */
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

import AutoImport from "unplugin-auto-import/vite"

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    AutoImport({
      imports: ["vue", "vue-router"]//自动导入相关函数
    })
  ]
})

还没写完。补充ing

你可能感兴趣的:(vue,vue.js,javascript,npm)