• Vue路由(Vue Router)记录学习


    记录一下Vue Router 使用学习,本人在日常使用的一个总结纪录;写的不好勿喷!!!
    如有不对,欢迎大神们赐教!!!

    Vue Router 地址:https://router.vuejs.org/zh/introduction.html
    Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。

    1.安装 vue-router :

    方式一:直接下载 / CDN

    直接下载: https://unpkg.com/vue-router@4
    Unpkg.com 提供了基于 npm 的 CDN 链接。上述链接将始终指向 npm 上的最新版本。 你也可以通过像 https://unpkg.com/vue-router@4.0.15/dist/vue-router.global.js 这样的 URL 来使用特定的版本或 Tag。
    方式二:使用npm 安装

    # vue-router 3x
        npm install vue-router --save
        //或
        cnpm install vue-router --save
    
    # vue-router 4x
        npm install vue-router@4 --save
        //或
        cnpm install vue-router@4 --save
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.在router/index.js(路由文件)中。

    (vue-router 3x)路由文件

    import Vue from 'vue' // 引入vue
    import Router from 'vue-router' // 引入vue-router路由依赖
    //定义路由组件
    import HelloWorld from '@/components/HelloWorld' // 引入页面组件,命名为HelloWorld
    // Vue全局使用Router
    Vue.use(Router)
    
    // 定义路由配置
    export default new Router({
      routes: [                //配置路由
        {                        
          path: '/',            //链接路径
          name: 'HelloWorld',        //路由名称
          component: HelloWorld     //对应组件模板
        }
      ]
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    (vue-router 4x)路由文件

    import {createRouter, createWebHashHistory} from 'vue-router';
    // 1. 定义路由组件.
    import Login from '../views/login.vue'
    // 2.  定义一些路由 ; 每个路由都需要映射到一个组件。
    const routes = [
      {
        path: '/',
        name: 'Home',
        //路由懒加载 ,使用 webpack(需要 Webpack > 2.4),
        component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue')
      },
      { path: '/login', name:'Login', component: Login }
    ]
     3. 创建路由实例并传递 `routes` 配置
    const router = createRouter({
      // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
      history: createWebHashHistory(),
      routes // `routes: routes` 的缩写
    })
    export default router
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.入门使用:

    HTML方式

    <script src="https://unpkg.com/vue@3"></script>
    <script src="https://unpkg.com/vue-router@4"></script>
    
    <div id="app">
      <h1>Hello App!</h1>
      <p>
        <!--使用 router-link 组件进行导航 -->
        <!--通过传递 `to` 来指定链接 -->
        <!--`` 将呈现一个带有正确 `href` 属性的 `` 标签-->
        <router-link to="/">Go to Home</router-link>
        <router-link to="/about">Go to About</router-link>
      </p>
      <!-- 路由出口 -->
      <!-- 路由匹配到的组件将渲染在这里 -->
      <router-view></router-view>
    </div>
    

    JavaScript方式 在main.js中

    Vue2中使用

    import Vue from 'vue' // 引入vue
    import App from './App' // 引入根组件
    import router from './router' // 引入路由配置
    
    //productionTip(2.2.0 新增)   设置为 false 以阻止 vue 在启动时生成生产提示。
    Vue.config.productionTip = false // 关闭生产模式下给出的提示
    // Vue.config.silent = true  //取消 Vue 所有的日志与警告。
    
    // 创建并挂载到 #app (会替换 #app)
    new Vue({
      router,
      render: h => h(App)
    }).$mount('#app')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在 vue3 中使用

    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
    //  创建一个应用实例。
    const app = createApp(App)
    整个应用支持路由。
    app.use(router)
    //将应用实例挂载在一个容器元素中。
    app.mount('#app') 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    通过注入路由器,我们可以在任何组件内通过 this.$router 访问路由器,也可以通过 this.$route 访问当前路由。

    4、JavaScript使用路由,在web页面中

    1. 根组件的模板里面放上
    2. 路由跳转
      首页
      新闻
      
      • 1
      • 2

    动态路由 (编程式路由传参)

    路径参数(通过 params 传递)

    在 Vue Router 中,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数 .

    • 路径参数 用冒号:表示。
    • 当一个路由被匹配时,它的 params 的值将在每个组件中以 this.$route.params 的形式暴露出来。
    • 同一个路由中设置有多个路径参数,都会映射到 $route.params 上的相应字段
    //定义路由组件
    import Details from '@/components/Details' // 引入页面组件,命名为 Details
    // 这些都会传递给 `createRouter`
    const routes = [
      // 动态字段以冒号开始
      { path: 'details/:id', name: "details", component: Details },
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    router.push() 方法的参数可以是一个字符串路径,或者一个描述地址的对象。

    //选项式API写法
    
    /* 
      Vue3.2,引入语法糖;
        1、在 Vue3.2 之前变量必须 return 出来,template中才能使用;
        2、而在 Vue3.2 中只需要在 script 标签上加上 setup 属性,无需 return,template 便可直接使用
      如何使用setup语法糖
        只需在 script 标签上写上setup
        
    */
    //组合式API
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    注意,如果提供了 path,params 会被忽略:

    响应路由参数的变化

    使用带有参数的路由时需要注意的是,当用户从 /details/12 导航到 /details/16 时,相同的组件实例将被重复使用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会被调用。
    要对同一个组件中参数的变化做出响应的话,watch(监听) r o u t e 对象上的任意属性。 ‘ route 对象上的任意属性。 ` route对象上的任意属性。route对象上的属性:fullPath、hash、query、matched、meta(路由元信息)、name、params、path(路径)等属性`

    const Details = {
      template: '...',
      created() {
        this.$watch(
          () => this.$route.params,
          (toParams, previousParams) => {
            // 对路由变化做出响应...
          }
        )
      },
    }
    // 或者,使用 beforeRouteUpdate 导航守卫,它也可以取消导航:
    const Details = {
      template: '...',
      async beforeRouteUpdate(to, from) {
        // 对路由变化做出响应...
        this.userData = await fetchUser(to.params.id)
      },
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    通过 query 传递

    这种情况下 query (查询参数)传递的参数会显示在 url 后面,如:/details/001?kind=car

    //路由配置
    this.$router.push('/details/001?kind=car')
    this.$router.push({ path: '/details/001', query: { kind: "car" }})
    this.$router.push({ name: 'details', params: { id: '001' }, query: { kind: 'car' }})
    //组件通过 $route.query 获取数据,
    // 要对同一个组件中参数的变化做出响应的话,你可以简单地 watch $route 对象上的任意属性,在这个场景中,就是 $route.query 。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    通过 hash 传递

    通过此方式,url 路径中带有 hash,例如:/details/001#car

    //路由配置
    this.$router.push('/details/001#car')
    this.$router.push({ path: '/details/001', hash: '#car'})
    this.$router.push({ name: 'details', params: { id: '001' }, hash: 'car'})
    //组件通过 $route.hash.slice(1) 获取数据
    
    • 1
    • 2
    • 3
    • 4
    • 5

    通过 props 进行传递

    组件中使用 $route 会与路由紧密耦合,这限制了组件的灵活性,因为它只能用于特定的 URL。
    以解耦的方式使用 props 进行参数传递,主要是在路由配置中进行操作。

    • 1.布尔模式
      props 设置为 true 时,route.params 将被设置为组件的 props
      const User = {
        // 请确保添加一个与路由参数完全相同的 prop 名
        props: ['id'],
        template: '
      User {{ id }}
      '
      } const routes = [{ path: '/user/:id', component: User, props: true }] //注意:对于有命名视图的路由,你必须为每个命名视图定义 props 配置: const routes = [ { path: '/user/:id', components: { default: User, sidebar: Sidebar }, props: { default: true, sidebar: false } } ]
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
    • 2.对象模式
      当 props 是一个对象时,它将原样设置为组件 props。当 props 是静态的时候很有用。
      //路由配置
      const routes = [
        {
          path: '/hello',
          component: Hello,
          props: { name: 'World' }
        }
      ]
      //组件内取数据
      const Hello = {
        props: {
          name: {
            type: String,
            default: 'Vue'
          }
        },
        template: '
      Hello {{ name }}
      '
      } // 组件默认显示 Hello Vue,但路由配置了 props 对象,当路由跳转到 /hello 时,会显示传递过来的 name, 页面会显示为 Hello World。
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
    • 3.函数模式
      你可以创建一个返回 props 的函数。这允许你将参数转换为其他类型,将静态值与基于路由的值相结合等等。
    //路由配置
    const routes = [
      {
        path: '/search',
        component: SearchUser,
        props: route => ({ query: route.query.q })
      }
    ]
    //  URL /search?q=vue 将传递 {query: 'vue'} 作为 props 传给 SearchUser 组件。
    // 注意:请尽可能保持 props 函数为无状态的,因为它只会在路由发生变化时起作用。如果你需要状态来定义 props,请使用包装组件,这样 vue 才可以对状态变化做出反应。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    捕获所有路由或 404 Not found 路由

    • 常规参数只匹配 url 片段之间的字符,用 / 分隔。
    • 匹配任意路径,我们可以使用自定义的 路径参数 正则表达式
    const routes = [
      // 将匹配所有内容并将其放在 `$route.params.pathMatch` 下
      { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
      // 将匹配以 `/user-` 开头的所有内容,并将其放在 `$route.params.afterUser` 下
      { path: '/user-:afterUser(.*)', component: UserGeneric },
       // /:orderId -> 仅匹配数字
      { path: '/:orderId(\\d+)' },
      // /:productName -> 匹配其他任何内容
      { path: '/:productName' },
      //可重复参数
      // /:chapters ->  匹配 /one, /one/two, /one/two/three, 等
      { path: '/:chapters+' },
       // /:chapters -> 匹配 /, /one, /one/two, /one/two/three, 等
      { path: '/:chapters*' },
      //通过使用 ? 修饰符(0 个或 1 个)将一个参数标记为可选:
      // 匹配 /users 和 /users/posva
      { path: '/users/:userId?' },
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    确保转义反斜杠( \ ),就像我们对 \d (变成\d)所做的那样,在 JavaScript 中实际传递字符串中的反斜杠字符。

    * 在技术上也标志着一个参数是可选的,但 ? 参数不能重复。

    重定向和别名

    • redirect(重定向)
      重定向也是通过 routes 配置来完成,
      //是从 /home 重定向到 /
      const routes = [{ path: '/home', redirect: '/' }] 
      //重定向的目标也可以是一个命名的路由
      const routes = [{ path: '/home', redirect: { name: 'homepage' } }]
      //重定向的目标也可以是一个方法, 动态返回重定向目标
      const routes = [
        {
          // /search/screens -> /search?q=screens
          path: '/search/:searchText',
          redirect: to => {
            // 方法接收目标路由作为参数
            // return 重定向的字符串路径/路径对象
            return { path: '/search', query: { q: to.params.searchText } }
          },
        },
        {
          path: '/search',
          // ...
        },
      ]
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
    • alias(别名)
      通过别名,你可以自由地将 UI 结构映射到一个任意的 URL,而不受配置的嵌套结构的限制。使别名以 / 开头,以使嵌套路径中的路径成为绝对路径。
      const routes = [{ path: '/', component: Homepage, alias: '/home' }]

    导航守卫

    vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。

      1. beforeEach (全局前置守卫)
        在路由文件(router/index.js)中,使用 router.beforeEach 注册一个全局前置守卫
        beforeEach 添加一个导航守卫,在任何导航前执行。返回一个删除已注册守卫的函数。
      //  创建路由
      //createRouter:创建一个可以被 Vue 应用程序使用的路由实例。
      const router = createRouter({ ... })
      //添加导航守卫
      router.beforeEach(async (to, from) => {
        /*
          每个守卫方法接收两个参数:
            to: 即将要进入的目标 用一种标准化的方式
            from: 当前导航正要离开的路由 用一种标准化的方式
          一个可选参数:
            next:
          返回:
            false: 取消当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
            一个路由地址: 通过一个路由地址跳转到一个不同的地址,就像你调用 router.push() 一样,你可以设置诸如 replace: true 或 name: 'home' 之类的配置。当前的导航被中断,然后进行一个新的导航,就和 from 一样。
            如果遇到了意料之外的情况,可能会抛出一个 Error。这会取消导航并且调用 router.onError() 注册过的回调。
        */
        
        // 返回 false 以取消导航
        return false
      });
      
      /*
        当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中。
      */
      //注册全局守卫,三个参数
      router.beforeEach(async(to, from, next) => {
        if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
        else next()
      })
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
    • 2.beforeResolve(全局解析守卫)
      beforeResolve:添加一个导航守卫,在导航即将解析之前执行。在这个状态下,所有的组件都已经被获取,并且其他导航守卫也已经成功。返回一个删除已注册守卫的函数。
      router.beforeResolve(async to => {
        if (to.meta.requiresCamera) {
          try {
            await askForCameraPermission()
          } catch (error) {
            if (error instanceof NotAllowedError) {
              // ... 处理错误,然后取消导航
              return false
            } else {
              // 意料之外的错误,取消导航并把错误传给全局处理器
              throw error
            }
          }
        }
      })
      //router.beforeResolve 是获取数据或执行任何其他操作(如果用户无法进入页面时你希望避免执行的操作)的理想位置。
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    • 3.afterEach(全局后置钩子 )
      对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。
    • 4.beforeEnter(路由独享的守卫)
      • 在进入特定于此记录的守卫之前。注意如果记录有重定向属性,则 beforeEnter 无效。
      • beforeEnter 守卫 只在进入路由时触发,不会在 params、query 或 hash 改变时触发。
      • 它们只有在 从一个不同的 路由导航时,才会被触发。
      const routes = [
        {
          path: '/users/:id',
          component: UserDetails,
          beforeEnter: (to, from) => {
            // reject the navigation
            return false
          },
        },
      ]
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    • 5.组件内的守卫
      可以在路由组件内直接定义路由导航守卫(传递给路由配置的)
      • beforeRouteEnter 路由进入守卫
        1. 在渲染该组件的对应路由被验证前调用
        2. beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
        beforeRouteEnter (to, from, next) {
          next(vm => {
            // 通过 `vm` 访问组件实例
          })
        }
        //注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
      • beforeRouteUpdate 路由更新守卫
        1. 在当前路由改变,但是该组件被复用时调用
        2. 组件已经挂载好了,导航守卫可以访问组件实例 this
        beforeRouteUpdate (to, from) {
          // just use `this`
          this.name = to.params.name
        }
        
        • 1
        • 2
        • 3
        • 4
      • beforeRouteLeave 路由离开守卫
        1. 在导航离开渲染该组件的对应路由时调用
        2. beforeRouteUpdate 一样,它可以访问组件实例 this
        beforeRouteLeave (to, from) {
          const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
          if (!answer) return false
        }
        //离开守卫 通常用来预防用户在还未保存修改前突然离开。该导航可以通过返回 false 来取消
        
        • 1
        • 2
        • 3
        • 4
        • 5

    常用相关API

    • createRouter
      创建一个可以被 Vue 应用程序使用的路由实例。
      const routes = [
        {
          path: '/',
          name: 'Home',
          //懒加载
          component: () => import(/* webpackChunkName: "home" */ '../views/Home.vue')
        }
      ]
      const router = createRouter({
          history: createWebHashHistory(),
          routes: routes
      })
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    • createWebHistory
      创建一个 HTML5 历史,即单页面应用程序中最常见的历史记录。应用程序必须通过 http 协议被提供服务。
      createWebHistory() // 没有 base,应用托管在域名 `https://example.com` 的根目录下。
      createWebHistory('/folder/') // 给出的网址为 `https://example.com/folder/`
      
      • 1
      • 2
    • createWebHashHistory
      创建一个 hash 历史记录。对于没有主机的 web 应用程序 (例如 file://),或当配置服务器不能处理任意 URL 时这非常有用。
      注意:如果 SEO 对你很重要,你应该使用 createWebHistory。
      // at https://example.com/folder
      createWebHashHistory() // 给出的网址为 `https://example.com/folder#`
      createWebHashHistory('/folder/') // 给出的网址为 `https://example.com/folder/#`
      // 如果在 base 中提供了 `#`,则它不会被 `createWebHashHistory` 添加
      createWebHashHistory('/folder/#/app/') // 给出的网址为 `https://example.com/folder/#/app/`
      // 你应该避免这样做,因为它会更改原始 url 并打断正在复制的 url
      createWebHashHistory('/other-folder/') // 给出的网址为 `https://example.com/other-folder/#`
      
      // at file:///usr/etc/folder/index.html
      // 对于没有 `host` 的位置,base被忽略
      createWebHashHistory('/iAmIgnored') // 给出的网址为 `file:///usr/etc/folder/index.html#`
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

    Router 方法

    • addRoute
      • 添加一条新的路由记录作为现有路由的子路由。
      • 如果路由有一个 name ,并且已经有一个与之名字相同的路由,它会先删除之前的路由。
      • 函数签名addRoute(parentName: string | symbol, route: RouteRecordRaw): () => void
        • parentName(类型: string | symbol ) 父路由记录,route 应该被添加到的位置;可不写
        • route (l类型:RouteRecordRaw) 要添加的路由记录
        • 使用router.addRoute("layout", item)
      //定义特殊路由
      const routes_404 = {
        path: "/:pathMatch(.*)*",
        hidden: true,
        component: () => import(/* webpackChunkName: "404" */ '@/views/other/404'),
      }
      // 创建路由实例
      const router = createRouter({
        history: createWebHashHistory(),
        routes: [{{ path: 'details/:id', name: "details", component: () => import(/* webpackChunkName: "404" */ '@/views/Details') }}]
      })
      //添加路由
      router.addRoute(routes_404)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    • onError
      • 添加一个错误处理程序,在导航期间每次发生未捕获的错误时都会调用该处理程序。
      • 这包括同步和异步抛出的错误、在任何导航守卫中返回或传递给 next 的错误,以及在试图解析渲染路由所需的异步组件时发生的错误。
      router.onError((error) => {
        //error :注册的错误处理程序
        NProgress.done();
        ElNotification.error({
          title: '路由错误',
          message: error.message
        });
      });
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
    • push
      • 通过在历史堆栈中推送一个 entry,以编程方式导航到一个新的 URL。
      • push(to: RouteLocationRaw): Promise
        • to(类型RouteLocationRaw): 要导航到的路由地址
    • removeRoute
      • 通过名称删除现有路由。
      • removeRoute(name: string | symbol): void
        • name string | symbol 要删除的路由名称
        • router.removeRoute('about')
    • getRoutes
      获取所有 路由记录的完整列表。
      getRoutes(): RouteRecord[]
      router.getRoutes()
    • go
      • 允许你在历史中前进或后退。
      • go(delta: number): void
        • delta number 相对于当前页面,你要移动到的历史位置
        • go(-1): 原页面表单中的内容会丢失;
          this.$router.go(-1):后退+刷新;
          this.$router.go(0):刷新;
          this.$router.go(1) :前进
          
          • 1
          • 2
          • 3
    • back
      • 如果可能的话,通过调用 history.back() 回溯历史。相当于 router.go(-1)。
      • back(): 原页表表单中的内容会保留;
        this.$router.back():后退 ;
        this.$router.back(0) 刷新;
        this.$router.back(1):前进
        
        • 1
        • 2
        • 3
  • 相关阅读:
    还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)
    面试题 17.08. 马戏团人塔(最长上升子序列)
    React Native将 ipad 端软件设置为横屏显示后关闭 Modal 弹窗报错
    从头开始机器学习:线性回归
    Linux小程序---进度条
    LeetCode(力扣)455. 分发饼干Python
    模拟问题(中)
    Kubernetes——PV与PVC
    2023亚太杯数学建模思路 - 案例:ID3-决策树分类算法
    【算法刷题day34】Leetcode:1005. K 次取反后最大化的数组和、134. 加油站、135. 分发糖果
  • 原文地址:https://blog.csdn.net/weixin_44519188/article/details/126355062