手把手教你使用vue2搭建微前端micro-app

news2024/11/18 17:23:10

简述

本文主要讲述新手小白怎么搭建micro-app,几乎是每一步都有截图说明。上手应该很简单。
本来我之前已经写了一篇手把手教程了,但是当时写的结个太乱了,趁着五一休假,重新整理了一番,加了文章目录,这样有助于阅读。

研究背景

这段时间在网上找了很多有关微前端相关的知识,起初本来是想着先搭建一个single-spa,但是奈何网上能找到的内容都是千篇一律。我也是搭了好久没搭出来。不知道为啥,反正就是一个劲的报错。
后面发现京东嫌弃single-spa太难用,他们自己搞了一套micro-app,那我想着这个应该比single-spa好用吧。很明显的好处就是,micro-app最起码能找到好理解的官网
但是对于项目的搭建,官网介绍的也是很粗糙,网上找到的也是一上来就npm,对于零基础的新手来说真的是太不友好了。说实话,渣渣的我看了都不知道npm在哪输入。不过还是在一步步的探索中取得了成功。
接下来先看一下搭建成功的效果图吧,图中展示了基座运行和两个子应用下运行的效果,即:可以单独运行,也可以整体运行:

​项目代码
演示效果
看完运行效果后,就开始搭建项目了

1、准备工作

1-1、创建项目

首先第一步就是先创建一个文件夹 ,如下图所示,我这边新建了一个叫micro-app-demo的文件夹,用webStrom打开,效果如下图所示:
​​​​​​​​​​在这里插入图片描述

1-2、创建vue项目

接下来就是创建vue,这个命令之前装single-spa的时候就遇到过,让我升级vue3。
所以你在安装时如果提示你升级,就按照提示进行升级,不然会报错。

vue create base

由于忘记截图,这个是之前搭single-spa时的截图,一样的道理,只是文件夹名称和create名称不一样而已,可以理解大概意思 。
在这里插入图片描述
提示vue create是vue cli3的唯一命令 ,而已使用的是vue cli 2.9.6 ,公司的电脑我也不敢随便改,怕影响到项目,所以接下来就算自己笔记本了。
创建时先升级到vue3

npm uninstall -g vue-cli
npm install -g @vue/cli

我笔记本只安装了vsCode,所以接下来的代码展示都是在vsCode中进行操作的。
接下来就步入正题,开始创建:

2、安装base(基座)

base我这边理解为基座,即:子应用都需要在base基座中配置,类似iframe框架

2-1、创建base文件夹,在文件夹下安装vue2项目

接上一步,使用vsCode将新建好的文件夹micro-app-demo打开,如下图所示,打开一个新终端,在下面输入命令创建base,创建时可选择vue2还是vue3,我这边以vue2为例,如果要选vue3的话,下面代码中的语法会不一样。
在这里插入图片描述
我这边选择vue2后,安装完成后,效果如下图所示:
在这里插入图片描述
可以从图中看到安装完后的整个目录,既然它有提示让我们运行,那就运行一下看看效果。运行效果如下:
在这里插入图片描述
接下来开始对base进行改造,注:下面的修改都是对base目录下的修改,别搞错地方了。

2-2、添加配置文件vue.config.js

在这里插入图片描述

module.exports = {
  devServer: {
      host: 'localhost'
      , port: 3000
  }
}

2-3、安装micro-app插件,安装在base目录下

在这里插入图片描述

npm install @micro-zoe/micro-app --save

安装完成后可以在package.json文件下看到刚刚安装好的 插件
在这里插入图片描述

2-4、micro配置

接下来创建两个文件夹,文件夹里面有两个js文件
在这里插入图片描述
base/src/micro/index.js

import microApp from '@micro-zoe/micro-app'
import * as config from './config'
 
 
/**启用 micro */
microApp.start({
    preFetchApps: config.MICRO_APPS
    , globalAssets: config.GLOBAL_ASSETS
})

base/src/micro/config.js

/**
* 子应用前缀
*/
export const CHILD_PREFIX = 'app'
 
 
/**
* 子应用地址
*/
export const MICRO_APPS = [
    { name: 'first-child', url: `http://localhost:3001/` }
    , { name: 'second-child', url: `http://localhost:3002/` }
]
 
 
/**
* 全局资源
*/
export const GLOBAL_ASSETS = {
    js: []
    , css: []
}

2-5、安装路由

这里路由我装低一点的版本,安装完成后package.json中可以看到效果
在这里插入图片描述

npm install vue-router@3

2-6、修改main.js

修改入口文件main.js,引入micro-app配置,在这里顺便将上一步安装的路由也引入
在这里插入图片描述

import './micro'
import Vue from 'vue'
import App from './App.vue'
import router from './router'
 
 
Vue.config.productionTip = false
 
 
new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

2-7、修改App.vue文件

在这里插入图片描述

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>|
      <router-link :to="`/${prefix}/first-child/home`">FirstChildHome</router-link>|
      <router-link :to="`/${prefix}/first-child/about`">FirstChildAbout</router-link>|
      <router-link :to="`/${prefix}/second-child/home`">SecondChildHome</router-link>|
      <router-link :to="`/${prefix}/second-child/about`">SecondChildAbout</router-link>
    </div>
    <div>
      <micro-app
        v-if="isChild"
        v-bind="micro"
        destory
        @created='created'
        @beforemount='beforemount'
        @mounted='mounted'
        @unmount='unmount'
        @error='error'
        @datachange='handleDataChange'
      ></micro-app>
      <router-view v-else></router-view>
    </div>
  </div>
</template>
 
 
<script>
import { MICRO_APPS, CHILD_PREFIX } from './micro/config.js'
 
 
export default {
  name: 'App',
  data () {
    return {
      isChild: false      /**是否为子模块 */
      , micro: {        
        url: ''       /**子模块地址 */
        , key: ''       /**vue 标签的 key 值,用于不同子模块间的切换时,组件重新渲染 */
        , name: ''      /**子模块名称,唯一 */
        , data: {}      /**子模块数据 */
        , baseroute: ''   /**子模块数据 */
      }
      , prefix: CHILD_PREFIX  /**子模块链接前缀 */
    }
  }
  , watch: {
    $route (val) { /**监听路由变化修改视图显示 */
      this.changeChild(val)
    }
  }
  , created () {
    this.changeChild(this.$route)
  }
  , methods: {
    created () { /**子模块创建 */
      console.log(`${this.micro.name}-created`)
    }
    , beforemount () { /**子模块挂载之前 */
      console.log(`${this.micro.name}-beforemount`)
    }
    , mounted () { /**子模块挂载 */
      this.loading = false
      console.log(`${this.micro.name}-mounted`)
    }
    , unmount () { /**子模块卸载 */
      console.log(`${this.micro.name}-unmount`)
    }
    , error () { /**子模块异常 */
      console.log(`${this.micro.name}-error`)
    }
 
 
    , getAppUrl (name) { /**获取子模块 url 和 name */
      return MICRO_APPS.find(app => app.name === name) || {}
    }
    , changeChild (route) { /**修改子视图显示 */
      let path = route.path.toLowerCase()
        , paths = path.split('/')
 
 
      /**判断是否为子模块,子模块有固定的前缀,在 micro/config 设置 */
      this.isChild = paths.length > 2 && paths[1] === CHILD_PREFIX
 
 
      if (this.isChild) {
        let app = this.getAppUrl(paths[2])
 
 
        this.micro = {
          ...app
          , data: { name: route.name }
          , key: `${app.name}`
          , baseroute: `/${CHILD_PREFIX}/${paths[2]}`
        }
      }
    }
    , handleDataChange (event) { /**获取子路由传递的信息 */
      let data = event.detail.data
      if(data.route) this.$router.push({ name: data.route.name })
    }
  }
}
</script>
 
 
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
 
 
#nav {
  padding: 30px;
}
 
 
#nav a {
  font-weight: bold;
  color: #2c3e50;
}
 
 
#nav a.router-link-exact-active {
  color: #42b983;
}
</style>

2-8、配置路由

我们虽然在2-5中安装了路由,但是没有对路由进行配置,所以这边要安装一个路由。
刚创建好的vue项目中没有对路由的配置,所以需要手动添加配置。
创建文件夹router,router中添加index.js文件
在这里插入图片描述
base/src/router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
 
 
import { CHILD_PREFIX } from '@/micro/config.js'
 
 
Vue.use(VueRouter)
 
 
const routes = [
    {
        path: '/'
        , name: 'Home'
        , component: () => import('../views/Home.vue')
    }
    , {
        path: '/about'
        , name: 'About'
        , component: () => import('../views/About.vue')
    }
    , {
        path: `/${CHILD_PREFIX}/first-child`
        , name: 'FirstChild'
        , children: [
            {
                path: 'home'
                , name: 'FirstHome'
            }
            , {
                path: 'about'
                , name: 'FirstAbout'
            }
        ]
    }
    , {
        path: `/${CHILD_PREFIX}/second-child`
        , name: 'SecondChild'
        , children: [
            {
                path: 'home'
                , name: 'SecondHome'
            }
            , {
                path: 'about'
                , name: 'SecondAbout'
            }
        ]
    }
]
 
 
const router = new VueRouter({
    mode: 'history'
    , routes
})
 
 
export default router

2-9、创建试图(views)

创建views文件夹,文件夹下面有home和about两个文件

在这里插入图片描述
base/src/views/Home.vue

<template>
    <div class="home">
        <img src="../assets/logo.png">
        <h1>基座-home page</h1>
    </div>
</template>
 
 
<script>
export default {
    name: 'Home'
}
</script>

base/src/views/About.vue

<template>
    <div class="about">
        <h1>基座-about page</h1>
    </div>
</template>

到此基座就搭建完成了,因为基座中有对子应用的配置,而子应用还没开始搭建,所以 这边暂时先不运行。

3、创建app_first(子应用1)

子应用为刚刚搭建完base的子应用,在例子中我们搭建两个子应用,为了方便起见,接下来的操作中我们一起把两个子应用都创建好,在去修改里面的配置。

创建之前需要注意的是,子应用与基座的层级关系是并列的,所以创建子应用时目录需要回到micro-app-demo目录下,具体操作如下:

3-1、创建app_first文件夹,在文件夹下安装vue2

在这里插入图片描述

cd ..  // 返回上一级目录
vue create app_first

3-2、创建app_second文件夹,在文件夹下安装vue2

这边为了减少麻烦我这边直接把app_second也创建了,等会就不用创建app_second了
在这里插入图片描述

vue create app_second

到这里子应用就都创建完成了,接下来开始对子应用开始配置,因为一下子有了三个目录文件,很容易搞错,所以配置的时候一定要看清楚哪个文件夹下的哪个文件。
接下来开始对spp_first(子应用1)的修改,注:接下来的所有修改都在app_first文件夹下

3-3、修改vue.config.js

修改vue.config.js文件,设置允许跨域
在这里插入图片描述

module.exports = {
  devServer: {
      host: 'localhost'
      , port: 3001
      , headers: { // 设置本地运行的跨域权限
          'Access-Control-Allow-Origin': '*',
      }
  }
}

3-4、micro配置

和基座一样,在src下创建文件夹micro/index.js。不同的是,子应用不需要config.js了
在这里插入图片描述
app_first/src/micro/index.js

// 设置 webpack 的公共路径
__webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__ || '/'

3-5、修改main.js

在这里插入图片描述

/**引入 publicPath 设置 */
import './micro'
 
 
import Vue from 'vue'
import App from './App.vue'
import router from './router'
 
 
Vue.config.productionTip = false
 
 
// new Vue({
//  router,
//  render: function (h) { return h(App) }
// }).$mount('#app')
 
 
let app
 
 
/**
* 挂载函数
*/
function mount () {
  app = new Vue({
    el: '#app',
    router,
    render: function (h) { return h(App) }
  })
}
 
 
/**
* 卸载函数
*/
function unmount () {
  app.$destroy()
  app.$el.innerHTML = ''
  app = null
}
 
 
/**微前端环境下,注册mount和unmount方法 */
if (window.__MICRO_APP_ENVIRONMENT__)
  window[`micro-app-${window.__MICRO_APP_NAME__}`] = { mount, unmount }
else
  mount()

3-6、安装路由

在这里插入图片描述

cd app_first // 1.先进入子应用1目录下
npm install vue-router@3 // 2.安装路由

3-7、修改App.vue文件

在这里插入图片描述

<template>
  <div id="app">
    <div id="nav">
      <router-link :to="`${prefix}/home`">子应用1Home</router-link> |
      <router-link :to="`${prefix}/about`">子应用1About</router-link> |
      <button @click="goto('SecondHome')">SecondHome</button> |
      <button @click="goto('SecondAbout')">SecondAbout</button>
    </div>
    <router-view />
  </div>
</template>
 
 
<script>
export default {
  name: 'App'
  , data () {
    return {
      prefix: window.__MICRO_APP_BASE_ROUTE__ || ''
    }
  }
  , methods: {
    dataListener (data) {
      if (data.name !== this.$route.name) /** 不判断时会报一个“冗余导航【NavigationDuplicated】”的异常 */
        this.$router.push({ name: data.name })
    }
    , goto (name) {
            // 向基项目发送数据
      window.microApp && window.microApp.dispatch({ route: { name } })
    }
  },
  created () {
    /** 绑定数据【data属性】监听事件 */
    window.microApp && window.microApp.addDataListener(this.dataListener)
  }
  , destroyed () {
    /** 移除数据【data属性】监听事件 */
    window.microApp && window.microApp.removeDataListener(this.dataListener)
  }
}
</script>
 
 
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
 
 
#nav {
  padding: 30px;
}
 
 
#nav a {
  font-weight: bold;
  color: #2c3e50;
}
 
 
#nav a.router-link-exact-active {
  color: #42b983;
}
</style>

3-8、配置路由

创建router文件夹,配置路由
在这里插入图片描述
app_first/src/router/index

import Vue from 'vue'
import VueRouter from 'vue-router'
 
 
Vue.use(VueRouter)
 
 
const routes = [
    {
        path: window.__MICRO_APP_BASE_ROUTE__ || '/' /**根据项目运行的不同环境,设置路径的前缀 */
        , name: 'Home'
        , redirect: { name: 'FirstHome' }
        , component: () => import('../views/Empty.vue')
        , children: [
            {
                path: 'home'
                , name: 'FirstHome'
                , component: () => import('../views/Home.vue')
            }
            , {
                path: 'about'
                , name: 'FirstAbout'
                , component: () => import('../views/About.vue')
            }
        ]
    }
]
 
 
const router = new VueRouter({
    mode: 'history',
    routes
})
 
 
export default router

3-9、创建视图(views)

在这里插入图片描述
app_first/src/views/About.vue

<template>
    <div class="about">
      <h1>First Child About Page</h1>
    </div>
  </template>  

app_first/src/views/Empty.vue

<template>
    <router-view />
</template>

app_first/src/views/Home.vue

<template>
    <div class="home">
        <img
            alt="Vue logo"
            src="../assets/logo.png"
        >
        <h1>First Child Home Page</h1>
    </div>
</template>
 
 
<script>
export default {
    name: 'Home'
}
</script>

到此app_first就算改造完成了,怀着忐忑的心情运行一下,果然,,,没让我失望,是真的在认真报错。

npm run serve

3-10、报错处理

在这里插入图片描述
可以看到有4条错误,先从第一条开始解决吧

bug1:mircro/index.js百度找到要加if条件。就修改了一下,修改完成后就剩3个bug了
在这里插入图片描述

if (window.__MICRO_APP_ENVIRONMENT__) {
    // eslint-disable-next-line
    __webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__ || '/'
  }

接下来的三个 问题看出来是view命名的问题,需要驼峰命名啥的,应该是eslint引起的,继续百度解决方法
需要在package.json中修改
在这里插入图片描述

"vue/multi-word-component-names": 0 // 多字符组件名称,不设置检测

修改完成后继续跑,又报错,没路由,奇怪,我刚刚明明装了路由,有上面的截图 为证,但是就是不见了,可能在修改上面bug的时候百度好多种解决方法,试着试着不小心删掉了吧,既然没了那就重装一下吧。
在这里插入图片描述
安装完后又出现了
在这里插入图片描述
安装完成后在重新跑,,,耶耶耶耶耶耶,成功了,效果如下图所示,可以看到子应用1的效果:
在这里插入图片描述

4、创建app_second(子应用2)

接下来开始修改子应用2,(在上面3-2中已经创建好了子应用2),有了1的辛酸历程后,2的修改应该会很轻松,几乎和1一模一样,虽然我不想在写一遍了。但是既然文章叫手把手教学,那就在啰嗦一遍吧。

4-1、修改vue.config.js

修改vue.config.js文件,设置允许跨域访问,和app_first不同的是端口修改成3002
在这里插入图片描述

module.exports = {
  devServer: {
      host: 'localhost'
      , port: 3002
      , headers: { // 设置本地运行的跨域权限
          'Access-Control-Allow-Origin': '*',
      }
  }
}

4-2、micro配置

和基座一样,在src下创建文件夹micro/index.js。不同的是,子应用不需要config.js了
这边已经将子应用1中的bug修改掉,加上了if
在这里插入图片描述
app_second/src/micro/index.js

// 设置 webpack 的公共路径
if (window.__MICRO_APP_ENVIRONMENT__) {
    // eslint-disable-next-line
    __webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__ || '/'
}

4-3、修改main.js

在这里插入图片描述

/**引入 publicPath 设置 */
import './micro'
 
 
import Vue from 'vue'
import App from './App.vue'
import router from './router'
 
 
Vue.config.productionTip = false
 
 
// new Vue({
//  router,
//  render: function (h) { return h(App) }
// }).$mount('#app')
 
 
let app
 
 
/**
* 挂载函数
*/
function mount () {
  app = new Vue({
    el: '#app',
    router,
    render: function (h) { return h(App) }
  })
}
 
 
/**
* 卸载函数
*/
function unmount () {
  app.$destroy()
  app.$el.innerHTML = ''
  app = null
}
 
 
/**微前端环境下,注册mount和unmount方法 */
if (window.__MICRO_APP_ENVIRONMENT__)
  window[`micro-app-${window.__MICRO_APP_NAME__}`] = { mount, unmount }
else
  mount()

4-3、安装路由

在这里插入图片描述

ctrl+c // 中断app_first的运行
cd .. // 返回上级目录
cd app_second // 1.先进入子应用2目录下
npm install vue-router@3 // 2.安装路由
"rules": {
      "vue/multi-word-component-names": 0
    }

4-4、修改App.vue文件

在这里插入图片描述

<template>
  <div id="app">
    <div id="nav">
      <router-link :to="`${prefix}/home`">子应用2Home</router-link> |
      <router-link :to="`${prefix}/about`">子应用2About</router-link> |
      <button @click="goto('SecondHome')">SecondHome</button> |
      <button @click="goto('SecondAbout')">SecondAbout</button>
    </div>
    <router-view />
  </div>
</template>
 
 
<script>
export default {
  name: 'App'
  , data () {
    return {
      prefix: window.__MICRO_APP_BASE_ROUTE__ || ''
    }
  }
  , methods: {
    dataListener (data) {
      if (data.name !== this.$route.name) /** 不判断时会报一个“冗余导航【NavigationDuplicated】”的异常 */
        this.$router.push({ name: data.name })
    }
    , goto (name) {
            // 向基项目发送数据
      window.microApp && window.microApp.dispatch({ route: { name } })
    }
  },
  created () {
    /** 绑定数据【data属性】监听事件 */
    window.microApp && window.microApp.addDataListener(this.dataListener)
  }
  , destroyed () {
    /** 移除数据【data属性】监听事件 */
    window.microApp && window.microApp.removeDataListener(this.dataListener)
  }
}
</script>
 
 
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
 
 
#nav {
  padding: 30px;
}
 
 
#nav a {
  font-weight: bold;
  color: #2c3e50;
}
 
 
#nav a.router-link-exact-active {
  color: #42b983;
}
</style>

4-5、配置路由

创建router文件夹,配置路由
在这里插入图片描述
app_second/src/router/index
注:这边路由中的name需要修改成Second…,与base中设置的子路由名称保持一致,我这边刚开始搭建的时候就漏掉了,后面在学习代码过程中发现了,又重新做了修改

import Vue from 'vue'
import VueRouter from 'vue-router'
 
 
Vue.use(VueRouter)
 
 
const routes = [
    {
        path: window.__MICRO_APP_BASE_ROUTE__ || '/' /**根据项目运行的不同环境,设置路径的前缀 */
        , name: 'Home'
        , redirect: { name: 'SecondHome' }
        , component: () => import('../views/Empty.vue')
        , children: [
            {
                path: 'home'
                , name: 'SecondHome'
                , component: () => import('../views/Home.vue')
            }
            , {
                path: 'about'
                , name: 'SecondAbout'
                , component: () => import('../views/About.vue')
            }
        ]
    }
]
 
 
const router = new VueRouter({
    mode: 'history',
    routes
})
 
 
export default router

4-6、创建视图(views)

在这里插入图片描述
app_second/src/views/About.vue

<template>
    <div class="about">
      <h1>Second Child About Page</h1>
    </div>
  </template>  

app_second/src/views/Empty.vue

<template>
    <router-view />
</template>

app_second/src/views/Home.vue

<template>
    <div class="home">
        <img
            alt="Vue logo"
            src="../assets/logo.png"
        >
        <h1>Second Child Home Page</h1>
    </div>
</template>
 
 
<script>
export default {
    name: 'Home'
}
</script>

到此app_second也算改造完了,接下来运行一下

npm run serve

嘿嘿嘿,果然有了1的慢吞吞后,2就快多了,也没让我失望,一下子就成功了,结果如下:
在这里插入图片描述

5、运行基座目录

通过前面的操作后,子应用1和子应用2都已经运行出来了,在运行基座目录之前,先解决一下子应用中遇到的那个bug
在这里插入图片描述

"rules": {
      "vue/multi-word-component-names": 0
    }

改造完成后,就可以运行基座了,当然我发现如果要运行基座,且想在基座中看到子应用,那么两个子应用也要一起运行,所以我在vsCode中开三个终端,将三个都运行了
在这里插入图片描述
分别看一下每一个的运行吧:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
好了,运行完后,接下来看一下浏览器的显示效果:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

总结

我这篇文章写的很啰嗦,如果照着一步步操作应该是不会遇到什么大问题的,因为我这边也是一步步探索出来的结果。纯小白探索,所以如果想搭建micro-app的话,我这篇文章应该很适合小白操作。
当然我也有参考文章,就是参考文章写的没有我这边这么细致,对于新手来说,还是不太友好的。
下一篇micro-app在本文基座上的一些学习笔记

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/485375.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何显示文件夹的后缀和隐藏文件

© Ptw-cwl 文章目录 前言文件夹后缀隐藏文件 如何设置显示文件夹的后缀和隐藏文件 前言 文件夹后缀 文件后缀是指文件名中最后一个“.”后面的一串字符&#xff0c;用来表示该文件的类型或格式。不同的文件类型有不同的后缀&#xff0c;例如&#xff0c;常见的图片文件…

对象浅拷贝的5种方式

参考原文:浅拷贝的五种实现方式 - 掘金 (juejin.cn) 哈喽 大家好啊 最近发现自己对对象都不是很熟练&#xff0c;特别是涉及到一些复制&#xff0c;深浅拷贝的东西 1.Object.assign 首先 我们创建一个空对象obj1 然后创建一个对象obj2 用object.assign(目标对象&#xff0c…

庖丁解牛函数知识---C语言《2》

目录 前言&#xff1a; 1.嵌套调用函数 2.链式访问 3.函数的声明与定义 4.*递归 5.递归与非递归 ❤博主CSDN:啊苏要学习 ▶专栏分类&#xff1a;C语言◀ C语言的学习&#xff0c;是为我们今后学习其它语言打好基础&#xff0c;C生万物&#xff01; 开始我们的C语言之旅吧…

C6678学习-GPIO

文章目录 1、简介2、框图3、寄存器4、地址 1、简介 C6678中共有16个GPIO&#xff0c;GPIO0~GPIO15。这些引脚的功能如下 ​ 通用输入输出管脚​ 中断&EDMA事件管脚 2、框图 1、GPIO作为通用输入输出时&#xff0c;用到的寄存器为DIR、SET_DATA、OUT_DATA、CLR_DATA、IN_…

AI奇点已至,是黎明前的黑暗,还是黑夜前的黄昏

2022年11月&#xff0c;OPEN AI公司推出了ChatGPT 3模型&#xff0c;瞬间引爆全球话题&#xff0c;所有业内人士都在感叹他的强大&#xff0c;比尔盖茨也曾经评价道&#xff0c;ChatGPT将会改变世界 &#xff0c;是一个相当于PC和互联网的革命性产品。 作为信息行业人&#xff…

网络请求与远程资源

网络请求与远程资源 网络分层 一、OSI七层模型、TCP/IP概念层模型 区别&#xff1a;OSI模型注重通信协议必要的功能是什么&#xff0c;TCP/IP模型更强调在计算机上实现协议应该开发哪种程序。 二、应用层的网络协议 FTP&#xff1a;文本传输协议SMTP&#xff1a;简单邮件传输协…

简单理解什么是序列化

为什么要序列化 序列化的目的就是为了对象可以在网络层进行传输&#xff0c; 比如通过后端传给前端数据。 什么是序列化 我们以Java为例。 序列化就是把对象转化为可传输的字节序列过程&#xff0c;这个字节序列可以是字符串&#xff0c;比如JSON格式的字符串&#xff0c;把…

基于海洋捕食者算法的极限学习机(ELM)回归预测-附代码

基于海洋捕食者算法的极限学习机(ELM)回归预测 文章目录 基于海洋捕食者算法的极限学习机(ELM)回归预测1.极限学习机原理概述2.ELM学习算法3.回归问题数据处理4.基于海洋捕食者算法优化的ELM5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;本文利用海洋捕食者算法对极限学习…

一种结合白平衡统计信息和曝光信息的软光敏算法专利学习

背景技术 随着科技的发展&#xff0c;对视频监控设备提出了越来越高的要求。大部分视频监控设备 都需要能够全天候的监控。ICR的中文名称为双滤光片切换器&#xff0c;是用于让滤光片白天切换到红外截止滤光片和晚上切换到全光谱滤光片的监控设备配件。白天的时候&#xff0c…

2023年5月3日 单调栈及其应用

文章目录 单调栈的应用[830. 单调栈 - AcWing题库](https://www.acwing.com/problem/content/description/832/)[P5788 【模板】单调栈 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)](https://www.luogu.com.cn/problem/P5788)[84. 柱状图中最大的矩形 - 力扣&#xff08;Lee…

chatGPT的翻译能力如何-GPT批量翻译软件

ChatGPT翻译软件 如果您正在为翻译工作而烦恼&#xff0c;或者需要面对语种广泛的国际化业务&#xff0c;那么ChatGPT翻译软件是您的不二之选。 ChatGPT翻译软件基于自然语言处理技术&#xff0c;利用先进的机器学习算法和深度神经网络模型&#xff0c;能够快速、高效地进行多…

将Egg项目部署到阿里云服务器

目录 1、连接阿里云服务器&#xff0c;上传文件 2、在阿里云服务器上安装Nodejs 3、下载项目依赖 4、安装 egg-scripts 模块 5、启动项目 6、阿里云服务器开启7001端口 1、连接阿里云服务器&#xff0c;上传文件 推荐使用FileZilla Client工具连接云服务器&#xff0c;可…

基于蝴蝶算法的极限学习机(ELM)回归预测-附代码

基于蝴蝶算法的极限学习机(ELM)回归预测 文章目录 基于蝴蝶算法的极限学习机(ELM)回归预测1.极限学习机原理概述2.ELM学习算法3.回归问题数据处理4.基于蝴蝶算法优化的ELM5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;本文利用蝴蝶算法对极限学习机进行优化&#xff0c;并…

LVS+Keepalived 高可用群集部署

一、LVSKeepalived 高可用群集 在这个高度信息化的 IT 时代&#xff0c;企业的生产系统、业务运营、销售和支持&#xff0c;以及日常管理等环节越来越依赖于计算机信息和服务&#xff0c;对高可用&#xff08;HA&#xff09;技术的应用需求不断提高&#xff0c;以便提供持续的…

[Git] Git零基础?带你快速入门,示例练习上手

&#x1f61a;一个不甘平凡的普通人&#xff0c;致力于为Golang社区和算法学习做出贡献&#xff0c;期待您的关注和认可&#xff0c;陪您一起学习打卡&#xff01;&#xff01;&#xff01;&#x1f618;&#x1f618;&#x1f618; &#x1f917;专栏&#xff1a;算法学习 &am…

STL--list

一、list介绍 列表是序列容器&#xff0c;允许在序列内的任何位置执行恒定时间插入和擦除操作&#xff0c;以及双向迭代 列表容器作为双向链表实现;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个和后一个元素 它们与forward_list非常…

3.rabbitMQ之发布确认高级和整合springboot(重要)找了很多博客整理出来的

1.极端情况下 rabbitMQ需要重启,导致消息投递失败(生产者发消息全部丢失)(交换机或者队列出问题) 生产者需要把数据放到缓存,用定时任务重新发送 解决方法: 0.必须配置文件写 spring.rabbitmq.publisher-confirm-typecorrelatedspring.rabbitmq.publisher-returnstruecorrelati…

appuploader 入门使用

回想一下我们发布 iOS 应用&#xff0c;不仅步骤繁琐&#xff0c;非常耗时。一旦其中一步失误了&#xff0c;又得重新来。作为一名优秀的工程师不应该让这些重复的工作在浪费我们的人生。在软件工程里面&#xff0c;我们一直都推崇把重复、流程化的工作交给程序完成。这次的文章…

【shell脚本】for循环语句

循环语句与函数 一、循环与遍历1.1循环1.2遍历1.3循环与遍历 二、for循环2.1for循环的基本格式2.2for循环小实验2.3双层for循环实验 三、while循环3.1 while格式 四、跳出循环4.1continue跳出循环实验4.2break跳出循环实验 一、循环与遍历 1.1循环 循环 (Loop) 是计算机编程中…

不会前端,怎么快速打造属于自己的个人博客?

个人博客 简介提前准备 一、初始化vuepress项目二、页面配置首页配置顶部配置顶部导航栏路由配置侧边导航栏配置 三、打包部署四、数据统计插槽自定义插槽配置整体结构页面效果 项目地址 简介 主要教大家如何快速搞一个属于自己的博客网站&#xff0c;特别是一些不怎么会前端的…