手把手教小白Vue3(保姆式服务)

1.初识Vue3

2.Vue3组合式API

2.1认识create-vue

create-vue是官方新的脚手架工具,vite下一代构建工具

node -v   >16

npm init vue@latest

npm run dev

2.2 setup

<script setup>原始写法

<script>

export default {

  //执行时机比beforeCreate早

  //获取不到this

  //数据和函数必须return出去

  setup() {

    //数据

    const message = 'hello vue3'

    //函数

    const logMessage = () => {

      console.log(message)

    }

    return {

      message, logMessage

    }

  },

  beforeCreate() {

    console.log('beforeCreate函数')

  }

}

</script>

<template>

  <h1>{{ message }}</h1>

  <button @click="logMessage">点我</button>

</template>

语法糖写法

<script setup>

const message = 'this is message'

const logMessage = () => {

  console.log(message);

}

</script>

<template>

  <h1>{{ message }}</h1>

  <button @click="logMessage">点我</button>

</template>

总结:

1.setup选项的执行时机?

beforeCreate钩子之前,自动执行

2.setup写代码的特点是什么?

定义数据+函数,然后以对象方式return

3.<script setup>解决了什么问题?

经过语法糖的封装更简单的使用组合式API

4.setup中的this还指向组件实例吗?

不指向,组件实例还未创建,undefined

2.3 reactive()

接收对象类型数据的参数传入,返回响应式对象

<script setup>

//接收对象类型数据的参数传入,返回响应式对象

import { reactive } from 'vue'

const state = reactive({

  count: 100

})

const addOne = () => {

  state.count++

}

</script>

<template>

  <div>

    <div>{{ state.count }}</div>

    <button @click="addOne">+1</button>

  </div>

</template>

2.4 ref()

如果是简单类型,用ref() 推荐

接收简单类型和对象类型数据传入并返回响应式对象

本质是对传入数据包了一层,包成复杂类型之后,再借助reactive实现响应式。

脚本中访问数据需要通过.value,非脚本区域直接使用数据

<script setup>

//接收对象类型数据的参数传入,返回响应式对象

import { ref } from 'vue'

const count = ref(0)

console.log(count.value);

const addOne = () => {

  count.value++

}

</script>

<template>

  <div>

    <div>{{ count }}</div>

    <button @click="addOne">+1</button>

  </div>

</template>

总结:

1.reactive和ref函数共同作用是什么?

用函数调用的方式生成响应式数据

2.reactive vs ref?

reactive不能处理简单类型的数据

ref参数类型支持更好但是必须通过.value访问修改

ref函数的内部实现依赖于reactive函数

3.在实际工作中推荐使用哪个?

推荐使用ref函数,更加灵活统一

2.5 computed

最佳实践:不应该有副作用,异步请求,修改dom,避免直接修改计算属性的值。

<script setup>

import { ref, computed } from 'vue'

//声明数据

const list = ref(

  [1, 2, 3, 4, 5, 6, 7, 8]

)

//基于list派生一个计算属性,从list中过滤出 > 2

const computedList = computed(() => {

  return list.value.filter(item => item > 2)

})

//定义一个修改数组的方法

const addFn = () => {

  list.value.push(666)

}

</script>

<template>

  <div>

    <div>原始数据:{{ list }}</div>

    <div>计算后的数据:{{ computedList }}</div>

    <button @click="addFn">修改</button>

  </div>

</template>

2.6 watch

侦听简单对象和复杂对象以及immediate和deep,精确侦听对象的某个属性

<script setup>

import { ref, watch } from 'vue'

const count = ref(0)

const nickname = ref('张三')

const changeCount = () => {

  count.value++

}

const changeNickName = () => {

  nickname.value = nickname.value + '三'

}

//1.监视单个数据的变化

//watch(ref对象,(newValue,oldValue)=>{...})

// watch(count, (newValue, oldValue) => {

//   console.log(newValue, oldValue)

// })

// watch(nickname, (nv, ov) => {

//   console.log(nv, ov);

// })

//监视多个数据的变化

//watch([ref1,ref2],(newArr,oldArr)=>{...})

/* watch([count, nickname], (newArr, oldArr) => {

  console.log(newArr, oldArr);

}) */

//立刻执行immediate

/* watch([count, nickname], (newArr, oldArr) => {

  console.log(newArr, oldArr);

}, {

  immediate: true

}) */

//深度监视 deep,默认是浅层监视,ref简单类型,直接监视,ref2复杂类型,监视不到内部数据变化

const userInfo = ref({

  name: 'zs',

  age: 18

})

const setUserInfo = () => {

  userInfo.value.age++

}

/* watch(userInfo, (nv, ov) => {

  console.log(nv, ov)

}, {

  deep: true//深度监视,对象子属性变化也能监视到

}) */

//对于对象中的属性来进行监视,固定写法

watch(() => userInfo.value.age, (nv, ov) => {

  console.log(nv, ov);

})

</script>

<template>

  <div>

    {{ count }}

  </div>

  <button @click="changeCount">改数字</button>

  <div>

    {{ nickname }}

  </div>

  <button @click="changeNickName">改昵称</button>

  <div>------------------------------------------</div><br>

  <div>{{ userInfo }}</div>

  <button @click="setUserInfo">修改userinfo</button>

</template>

总结:

1.watch第一个参数需要加.value吗?

不需要

2.只能侦听单个数据吗?

单个或者多个

3.不开启deep,直接监视复杂类型,修改属性,能触发回调吗?

不能,默认浅层监听

4.不开启deep,精确侦听对象的某个属性?

可以把第一个参数写成函数的写法,返回要监听的具体属性。

2.7 Vue3生命周期API(选项式 VS 组合式)

选项式

组合式

beforeCreate/created

setup

beforeMount

onBeforeMount

mounted

onMounted

beforeUpdate

onBeforeUpdate

updated

onUpdated

beforeUnmount

onBeforeUnmount

unmounted

onUnmounted

<script setup>

import { onMounted } from 'vue';

//beforeCreate和created的相关代码

//一律放在setup中执行

const getList = () => {

  console.log('发送请求,获取数据');

}

//一进入页面的请求

getList()

//如果有些代码需要在mounted生命周期中执行

onMounted(() => {

  console.log('mounted生命周期函数-逻辑一')

})

onMounted(() => {

  console.log('mounted生命周期函数-逻辑二')

})

</script>

<template>

  <div>

    <h1>啤酒颜色</h1>

  </div>

</template>

<style></style>

--------------------

发送请求,获取数据

App.vue:12 mounted生命周期函数-逻辑一

App.vue:15 mounted生命周期函数-逻辑二

2.8父子传值

父传子

基本思想

1.父组件中给子组件绑定属性

2.子组件内部通过props选项接收

App.vue

<script setup>

//1.父组件中给子组件绑定属性

//2.子组件内部通过props选项接收

import { ref } from 'vue'

import SonCom from '@/components/son-com.vue'

const money = ref(100)

const getMoney = () => {

  money.value += 10

}

</script>

<template>

  <div>

    <h1>啤酒颜色---{{ money }} <button @click="getMoney">挣钱</button></h1>

    <!-- 给子组件添加属性方式传值 -->

    <SonCom car="宝马车" :money="money"></SonCom>

  </div>

</template>

<style></style>

son-com.vue

<script setup>

//1.父组件中给子组件绑定属性

//2.子组件内部通过props选项接收,编译器宏接收子组件传递的数据

const props = defineProps({

    car: String,

    money: Number

})

console.log(props.car);

</script>

<template>

    <div class="son">

        <h1>我是子组件-{{ car }}-{{ money }}</h1>

    </div>

</template>

<style scoped>

.son {

    background-color: pink;

}

</style>

子传父

基本思想

1.父组件中给子组件标签通过@绑定事件

2.子组件内部通过emit方法触发事件

<script setup>

//1.父组件中给子组件绑定属性

//2.子组件内部通过props选项接收

import { ref } from 'vue'

import SonCom from '@/components/son-com.vue'

const money = ref(100)

const getMoney = () => {

  money.value += 10

}

const changeFn = (newMoney) => {

  money.value -= newMoney

}

//子传父

//1.在子组件内部,emit触发事件

//2.在父组件,通过@监听

</script>

<template>

  <div>

    <h1>啤酒颜色---{{ money }} <button @click="getMoney">挣钱</button></h1>

    <!-- 给子组件添加属性方式传值 -->

    <SonCom @changeMoney="changeFn" car="宝马车" :money="money"></SonCom>

  </div>

</template>

<style></style>

<script setup>

//1.父组件中给子组件绑定属性

//2.子组件内部通过props选项接收,编译器宏接收子组件传递的数据

const props = defineProps({

    car: String,

    money: Number

})

console.log(props.car);

const emit = defineEmits(['changeMoney'])

const buy = () => {

    emit('changeMoney', 5)

}

</script>

<template>

    <div class="son">

        <h1>我是子组件-{{ car }}-{{ money }}</h1>

        <button @click="buy">花钱</button>

    </div>

</template>

<style scoped>

.son {

    background-color: pink;

}

</style>

2.9模板引用的概念

defineExpose()

默认情况下,<script setup>语法糖下组件内部的属性和方法是不开放给父组件访问的,可以通过defineExpose编译宏指定哪些属性和方法允许访问。

<script setup>

import Test from '@/components/test.vue'

import { ref, onMounted } from 'vue'

//模板引用,获取dom,获取组件

//

//

const inp = ref(null)

//生命周期钩子,onMounted

onMounted(() => {

  // console.log(inp.value)

  // inp.value.focus()

})

const clickFn = () => {

  inp.value.focus()

}

const testRef = ref(null)

const getCom = () => {

  console.log(testRef.value)

  console.log(testRef.value.count)

  testRef.value.sayHi()

}

</script>

<template>

  <div>

    <input ref="inp" type="text">

    <button @click="clickFn">点击让输入框聚焦</button>

    <Test ref="testRef"></Test>

    <button @click="getCom">获取组件</button>

  </div>

</template>

<style></style>

<script setup>

const count = 999

const sayHi = () => {

    console.log(打招呼)

}

defineExpose({

    count,

    sayHi

})

</script>

<template>

    <div>

        <h1>我是用于测试的组件---{{ count }}</h1>

    </div>

</template>

<style></style>

2.9 provide和inject

顶层组件向任意底层组件传递数据和方法,实现跨层组件通信。

顶层provide底层inject

<script setup>

import { provide, ref } from 'vue'

import CenterCom from './components/center-com.vue'

//1.跨层传递普通数据

provide('theme-color', 'pink')

//2.跨层传递响应式数据

const count = ref(100)

provide('count', count)

setTimeout(() => {

  count.value++

}, 2000)

//3.跨层传递函数=》给子孙后代可以修改数据的方法

provide('changeCount', (newCount) => {

  count.value = newCount

})

</script>

<template>

  <div>

    <h1>我是顶层组件</h1>

    <CenterCom></CenterCom>

  </div>

</template>

<style></style>

center-com.vue

<script setup>

import BottomCom from './bottom-com.vue'

</script>

<template>

    <div>

        <h2>我是中间组件</h2>

        <BottomCom></BottomCom>

    </div>

</template>

<style></style>

bottom-com.vue

<script setup>

import { inject } from 'vue'

const themeColor = inject('theme-color')

const count = inject('count')

const changeCount = inject('changeCount')

const clickFn = () => {

    changeCount(1000)

}

</script>

<template>

    <div>

        <h3>我是底层组件--{{ themeColor }}--{{ count }}</h3>

        <button @click="clickFn">更新count</button>

    </div>

</template>

<style></style>

2.10Vue3.3新特性-defineOptions

背景说明:

无法添加平级属性,defineProps与defineEmits这两个宏

引入defineOptions宏,定义OptionsAPI的选项

index.vue

<script setup>

defineOptions({

    name: 'LoginIndex'

})

</script>

<template>

    <div>

        我是登录页

    </div>

</template>

<style></style>

2.11Vue3.3新特性-defineModel

新特性前

<script setup>

import MyInput from '@/components/my-input.vue'

import { ref } from 'vue';

const txt = ref('123456')

</script>

<template>

  <div>

    <MyInput v-model="txt"></MyInput>

    {{ txt }}

  </div>

</template>

<style></style>

my-input.vue

<script setup>

defineProps({

    modelValue: String

})

const emit = defineEmits(['update:modelValue'])

</script>

<template>

    <div>

        <input type="text" :value="modelValue" @input="e => emit('update:modelValue', e.target.value)">

    </div>

</template>

<style></style>

新特性后

vite.config.js

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'

import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/

export default defineConfig({

  plugins: [

    vue({

      script: {

        defineModel: true

      }

    }),

  ],

  resolve: {

    alias: {

      '@': fileURLToPath(new URL('./src', import.meta.url))

    }

  }

})

my-input.vue

<script setup>

import { defineModel } from 'vue'

const modelValue = defineModel()

</script>

<template>

    <div>

        <input type="text" :value="modelValue" @input="e => modelValue = e.target.value">

    </div>

</template>

<style></style>

3.Pinia

3.1什么是Pinia?

Pinia是Vue最新的状态管理工具,是Vuex的替代品

npm i pinia

在main.js中

import { createApp } from 'vue'

import { createPinia } from 'pinia'

import App from './App.vue'

const pinia = createPinia()//创建pinia实例

const app = createApp(App)//创建根实例

app.use(pinia)

app.mount('#app')

案例

counter.js

import { defineStore } from "pinia"

import { ref } from "vue"

//定义store

//defineStore(仓库唯一标识,()=>{})

export const userCounterStore = defineStore('counter', () => {

    //声明数据

    const count = ref(1110)

    //声明操作数据的方法 action 普通函数

    const addCount = () => {

        count.value++

    }

    const subCount = () => {

        count.value--

    }

    //声明基于数据派生的计算属性

    //声明数据state msg

    const msg = ref('hello pinia')

    return { count, msg, addCount, subCount }

})

App.vue

<script setup>

import Son1Com from '@/components/Son1Com.vue'

import Son2Com from '@/components/Son2Com.vue'

import { userCounterStore } from '@/store/counter'

const counterStore = userCounterStore()

console.log(counterStore)

</script>

<template>

  <div>

    <h3>App.vue根组件 - {{ counterStore.count }} - {{ counterStore.msg }}</h3>

    <Son1Com></Son1Com>

    <Son2Com></Son2Com>

  </div>

</template>

<style scoped></style>

Son1Com

<script setup>

import { userCounterStore } from '@/store/counter'

const counterStore = userCounterStore()

</script>

<template>

    <div>

        <h3>我是Son1 - {{ counterStore.count }}</h3>

        <button @click="counterStore.addCount">+</button>

    </div>

</template>

<style scoped></style>

Son2Com

<script setup>

import { userCounterStore } from '@/store/counter'

const counterStore = userCounterStore()

</script>

<template>

    <div>

        <h3>我是Son2 - {{ counterStore.count }}</h3><button @click="counterStore.subCount">-</button>

    </div>

</template>

<style scoped></style>

//声明基于数据派生的计算属性

    const double = computed(() => count.value * 2)

3.2 action异步实现

编写方式:异步action函数的写法和组件中获取异步数据的写法完全一致

接口地址:http://geek.itheima.net/v1_0/channels

截图.png

需求:在Pinia中获取频道列表数据并把数据渲染App组件的模板中

npm i axios

channel.js

import axios from "axios"

import { defineStore } from "pinia"

import { ref } from "vue"

export const useChannelStore = defineStore('channel', () => {

    //声明数据

    const channelList = ref([])

    //声明操作数据的方法

    const getList = async () => {

        //支持异步

        const { data: { data } } = await axios.get('http://geek.itheima.net/v1_0/channels')

        channelList.value = data.channels

        console.log(data.channels);

    }

    //声明getters相关

    return {

        channelList, getList

    }

})

App.vue

<script setup>

import Son1Com from '@/components/Son1Com.vue'

import Son2Com from '@/components/Son2Com.vue'

import { userCounterStore } from '@/store/counter'

import { useChannelStore } from '@/store/channel'

const counterStore = userCounterStore()

const channelStore = useChannelStore()

</script>

<template>

  <div>

    <h3>App.vue根组件 - {{ counterStore.count }} - {{ counterStore.msg }}</h3>

    <Son1Com></Son1Com>

    <Son2Com></Son2Com>

    <hr>

    <button @click="channelStore.getList">获取频道数据</button>

    <ul>

      <li v-for="item in channelStore.channelList" :key="item.id">{{ item.name }}</li>

    </ul>

  </div>

</template>

<style scoped></style>

3.3 storeToRefs 保持响应式

//此时直接解构,不处理,数据会丢失响应式

const { count, msg } = storeToRefs(counterStore)

//方法可以直接解构

const { channelList } = storeToRefs(channelStore)

const { getList } = channelStore

3.4 Pinia持久化插件

官方文档:Home | pinia-plugin-persistedstate

安装:npm i pinia-plugin-persistedstate

将插件添加到 pinia 实例上

import { createPinia } from 'pinia'

import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()

pinia.use(piniaPluginPersistedstate)

main.js

import { createApp } from 'vue'

import { createPinia } from 'pinia'

//导入持久化插件

import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

import App from './App.vue'

const pinia = createPinia()//创建pinia实例

//pinia插件安装配置

pinia.use(piniaPluginPersistedstate)

const app = createApp(App)//创建根实例

app.use(pinia)

app.mount('#app')

用法,组合式

import { defineStore } from 'pinia'

export const useStore = defineStore(

  'main',

  () => {

    const someState = ref('你好 pinia')

    return { someState }

  },

  {

    persist: true,

  }

)

第三个参数:

, {

    persist: true

}

修改参数

persist: {

        key: 'hm-counter',//Key 用于引用 storage 中的数据

        paths: ['count']//哪些数据需要被持久化

    }

3.5 总结

4.Vue3大事件管理系统

Vue3 compositionAPI Pinia/Pinia持久化处理Element Plus(表单校验,表格处理,组件封装)  pnpm包管理升级 Eslint + prettier更规范的配置

husky(Git hooks工具)代码提交之前,进行校验请求模块设计VueRouter4路由设计AI大模型开发一整个项目模块(掌握最新的开发方式)

4.1pnpm包管理器-创建项目

pnpm - 速度快、节省磁盘空间的软件包管理器 | pnpm中文文档 | pnpm中文网

优势:比同类工具快2倍,节省磁盘空间

pnpm常用指令:

  1. pnpm install
  2. pnpm add axios
  3. pnpm add axios -D
  4. pnpm remove axios
  5. pnpm dev

安装:npm i -g pnpm

创建项目:pnpm create vue

Vue3-big-event-admin

选择。。。

cd Vue3-big-event-admin

pnpm install

pnpm format

pnpm dev

4.2Eslint配置代码风格

配置文件.eslintrc.cjs,规范纠错

1.prettier,美化代码

官网:Prettier · Opinionated Code Formatter

2.vue组件名称多单词组成(忽略index.vue)

3.props解构(关闭)

4.3配置代码检查工作流

提交前做代码检查

1.初始化git仓库,执行git init即可

2.初始化husky工具配置,执行pnpm dlx husky-init&&pnpm install即可

Husky

3.修改.husky/pre-commit文件

npm test改为pnpm lint

问题:历史问题

暂存区eslint校验

1.安装lint-staged包:pnpm i lint-staged -D

2.package.json配置lint-staged命令

脚本增加:

"lint-staged":"lint-staged"

"lint-staged":{

    "*.{js,ts,vue}":[

      "eslint --fix"

    ]

  },

3..husky/pre-commit文件修改

4.4目录调整

自定义改动:

1.删除一些初始化的默认文件

2.修改剩余代码内容

3.新增调整我们需要的目录结构

4.拷贝全局样式和图片,安装预处理器支持

pnpm add sass -D

继续启动:pnpm dev

4.5 vue-router4路由代码解析

路由初始化D:\front-projects\Vue3-big-event-admin\src\router\index.js

import { createRouter, createWebHistory,createWebHashHistory } from 'vue-router'

//创建路由实例

//1.history模式:createWebHistory 地址栏不带#号

//2.hash模式:createWebHashHistory  地址栏带#号

// console.log(import.meta.env.DEV)

//vite中的环境变量 vite.config.js  base:'/',

const router = createRouter({

  history: createWebHistory(import.meta.env.BASE_URL),

  routes: []

})

export default router

D:\front-projects\Vue3-big-event-admin\src\App.vue

<script setup>

//vue3中,获取路由对象router useRouter  获取路由参数route useRoute

import { useRouter,useRoute } from 'vue-router'

const router = useRouter()

const route = useRoute()

  const goList = ()=>{

    router.push('/list')

    console.log(router,route)

  }

</script>

<template>

  <div>

    我是APP

    <button @click="$router.push('/home')">跳首页</button>

    <button @click="goList">跳列表页</button>

  </div>

</template>

<style scoped></style>

4.6 引入Element Plus组件库

按需引入

1.安装:pnpm add element-plus

2.配置按需导入:官方文档:https://element-plus.org/zh-CN/guide/quickstart.html

3.直接使用组件

pnpm install element-plus

按需导入:npm install -D unplugin-vue-components unplugin-auto-import

vite.config.js

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'

import vue from '@vitejs/plugin-vue'

// vite.config.ts

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

import Components from 'unplugin-vue-components/vite'

import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

// https://vitejs.dev/config/

export default defineConfig({

  plugins: [

    vue(),

    AutoImport({

      resolvers: [ElementPlusResolver()],

    }),

    Components({

      resolvers: [ElementPlusResolver()],

    }),

  ],

  base:'/',

  resolve: {

    alias: {

      '@': fileURLToPath(new URL('./src', import.meta.url))

    }

  }

})

4.7 Pinia构建仓库和持久化

D:\front-projects\Vue3-big-event-admin\src\stores\user.js

import {defineStore} from 'pinia'

//用户模块 token setToken removeToken

export const useUserStore = defineStore('big-user',()=>{

    const token = ref('')

    const setToken = (newToken)=>{

        token.value = newToken

    }

    const removeToken = ()=>{

        token.value = ''

    }

    return {token,setToken,removeToken}

})

<script setup>

//vue3中,获取路由对象router useRouter  获取路由参数route useRoute

import { useRouter,useRoute } from 'vue-router'

import { useUserStore } from '@/stores/user.js'

const router = useRouter()

const route = useRoute()

  const goList = ()=>{

    router.push('/list')

    console.log(router,route)

  }

const userStore = useUserStore()

</script>

<template>

  <div>

    我是APP

    <test-demo></test-demo>

    <el-button @click="$router.push('/home')">跳首页</el-button>

    <el-button @click="goList">跳列表页</el-button>

    <el-button type="primary">Primary</el-button>

    <el-button type="success">Success</el-button>

    <p>{{ userStore.token }}</p>

    <el-button @click="userStore.setToken('Bearer kjksdjfllsdjflsdjflsdj')">登录</el-button>

    <el-button @click="userStore.removeToken()">退出</el-button>

  </div>

</template>

<style scoped></style>

如果要持久化,则安装: pinia-plugin-persistedstate

官方文档:

Home | pinia-plugin-persistedstate

pnpm add pinia-plugin-persistedstate -D

main.js

import persist from 'pinia-plugin-persistedstate'

app.use(createPinia().use(persist))

user.js第三个参数增加

,{

    persist : true

}

4.8 仓库统一管理

pinia独立维护

D:\front-projects\Vue3-big-event-admin\src\stores\index.js

import { createPinia } from 'pinia'

import persist from 'pinia-plugin-persistedstate'

const pinia = createPinia()

pinia.use(persist)

export default pinia

D:\front-projects\Vue3-big-event-admin\src\main.js

import { createApp } from 'vue'

import App from './App.vue'

import router from './router'

import pinia from './stores'

import '@/assets/main.scss'

const app = createApp(App)

app.use(pinia)

app.use(router)

app.mount('#app')

仓库统一导出

//main.js

import { createApp } from 'vue'

import App from './App.vue'

import router from './router'

import pinia from './stores'

import '@/assets/main.scss'

const app = createApp(App)

app.use(pinia)

app.use(router)

app.mount('#app')

//index.js

import { createPinia } from 'pinia'

import persist from 'pinia-plugin-persistedstate'

const pinia = createPinia()

pinia.use(persist)

export default pinia

// import { useUserStore } from './modules/user'

// export { useUserStore }

export * from './modules/user'//接收所有的按需导出

// export * from './modules/counter'

//App.vue

import { useUserStore } from '@/stores'

4.9 数据交互

axios配置

装包:pnpm add axios

利用 axios.create 创建一个自定义的 axios 来使用

axios中文文档|axios中文网 | axios

  • 18
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值