【学习vue 3.x】(五)VueRouter路由与Vuex状态管理

在这里插入图片描述

文章目录

  • 章节介绍
    • 本章学习目标
  • 路由的基本搭建与嵌套路由模式
    • vue路由的搭建
    • 嵌套路由模式
  • 动态路由模式与编程式路由模式
    • 动态路由模式
    • 编程式路由
  • 命名路由与命名视图与路由元信息
    • 命名路由
    • 命名视图
    • 路由元信息
  • 路由传递参数的多种方式及应用场景
    • 路由传参
  • 详解route对象与router对象
    • route对象与router对象
  • 路由守卫详解及应用场景
    • 路由守卫分类
    • 完整的导航解析流程
  • Vuex共享状态的基本开发流程
  • Vuex处理异步状态及应用场景
  • Vuex计算属性和辅助函数的使用
    • getters计算属性
    • 辅助函数
  • Vuex-persist对数据进行持久化处理
  • Vuex分割模块及多状态管理
  • 组合式API中使用Router和Vuex注意事项
  • Router_Vuex的任务列表综合案例
  • 搭建 Vite3 + Pinia2 组合模式
    • 总结内容

章节介绍

小伙伴大家好,本章将学习VueRouter路由与Vuex状态管理 - 组织与架构应用。

本章学习目标

本章将学习Vue3中的路由与状态管理,随着前后端分离式开发的兴起,单页面应用开发(即SPA页面)也越来越流行,所以前端路由与共享状态也越来越重要!

路由的基本搭建与嵌套路由模式

在前面的小节中,已经介绍了什么是前端路由以及前端路由所具备的特点。本小节就来对路由进行实际搭建吧。

vue路由的搭建

路由在vue中属于第三方插件,需要下载安装后进行使用。版本说明一下,Vue3搭配的是Vue Router4,目前正常安装的话,就是路由4的版本。如下:

npm install vue-router

安装好后,需要对路由进行配置,并且与Vue进行结合,让路由插件生效。在/src/router/index.js创建配置文件。

在这里插入图片描述

可以通过 createWebHistory()来创建history模式的路由,也可以通过createWebHashHistory()来创建hash模式的路由。那么在浏览器中输入的URL该如何展示对应的组件呢?可以通过这个组件来实现。

除了进行展示外,还可以通过方式进行声明式的路由跳转,代码如下:

<template><div><router-link to="/">首页</router-link> | <router-link to="/about">关于</router-link><router-view></router-view></div>
</template>

嵌套路由模式

往往我们的路由是比较复杂的,需要的层级也比较多,那么就会产生嵌套路由的模式,比如:localhost:8080/about/foolocalhost:8080/about/bar

import Foo from '@/views/Foo.vue'
import Bar from '@/views/Bar.vue'
const routes = [{path: '/about',component: About,children: [{path: 'foo',component: Foo},{path: 'bar',component: Bar}]}
]

可以看到嵌套路由是通过children属性来完成的,那么对于这种嵌套路由写法,我们对应的也要在一级路由对应页面中添加一个,这样才能切换显示二级路由所对应的页面。

动态路由模式与编程式路由模式

动态路由模式

所谓的动态路由其实就是不同的URL可以对应同一个页面,这种动态路由一般URL还是有规律可循的,所以非常适合做类似于详情页的功能。

在这里插入图片描述

// router/index.js,定义动态路由const routes = [{path: 'foo/:id',component: Foo}
]// views/Foo.vue,获取动态路由的id
export default {mounted(){console.log( this.$route.params.id );}
}

编程式路由

前面介绍过如何在页面中对路由进行切换,可以采用声明式写法来完成,但是往往这种方式不够灵活,首先不能更灵活的控制结构和样式,其次不能自动进行路由的跳转,必须点击操作才行。

那么编程式路由就会在JavaScript中通过逻辑的方式进行路由跳转,我们把这种写在JS中进行跳转路由的方式叫做编程式路由,这样方式会更加的灵活。

<template><button @click="handleToBar">编程式路由跳转</button>
</template>
<script>export default {methods: {handleToBar(){this.$router.push('/about/bar');}}}
</script>

可以看到在动态路由中使用到了一个route对象,而在编程式路由中使用了一个router对象,那么这两个比较重要的路由对象,会在后面的小节中给大家进行详细的讲解。

命名路由与命名视图与路由元信息

命名路由

在路由跳转中,除了path 之外,你还可以为任何路由提供 name 的形式进行路由跳转。那么name方式的好处如下:

  • 没有硬编码的 URL
  • params 的自动编码/解码
  • 防止你在 url 中出现打字错误
  • 绕过路径排序(如显示一个)
// router/index.js,定义命名路由
const routes = [{path: '/about/bar',name: 'bar',component: Bar},{path: '/about/foo/:id',name: 'foo',component: Foo}
];
<!-- About.vue,使用命名路由跳转 -->
<template><div><router-link :to="{ name: 'bar' }">bar</router-link><router-link :to="{ name: 'foo', params: {id: 123} }">foo 123</router-link></div>
</template>

name的方式也支持动态路由形式。

命名视图

有时候想同时 (同级) 展示多个视图,而不是嵌套展示,这个时候就非常适合使用命名视图。
在这里插入图片描述

通过components字段配置多个组件,根据不同的router-view去渲染不同的组件。

路由元信息

有时,你可能希望将任意信息附加到路由上,如过渡名称、谁可以访问路由等。这些事情可以通过接收属性对象的meta属性来实现。

const routes = [{path: '/about/bar',name: 'bar',component: Bar,meta: { auth: false }},{path: '/about/foo/:id',name: 'foo',component: Foo,meta: { auth: true }}
];

定义好meta元信息后,可通过route对象去访问meta属性。

<!-- Foo.vue -->
<script>
export default {mounted(){this.$route.meta.auth   // true}
}
</script>

路由传递参数的多种方式及应用场景

路由传参

我们经常要在路由跳转的时候传递一些参数,这些参数可以帮助我们完成后续的一些开发和一些处理。路由的传递参数主要有以下三种方式:

  • query方式(显示) -> $route.query
  • params方式(显示) -> $route.params

两种显示传递数据的差异点主要为,query是携带辅助信息,而params是界面的差异化。

<!-- About.vue -->
<template><div><router-link :to="{ name: 'bar', query: { username: 'xiaobai' } }">bar</router-link><router-link :to="{ name: 'foo', params: { username: 'xiaoqiang' } }">foo</router-link></div>
</template><!-- Bar.vue -->
<script>export default {mounted(){console.log(this.$route.query);}}
</script>
<!-- foo.vue -->
<script>export default {mounted(){console.log(this.$route.params);}}
</script>

前两种都是显示传递数据,那么第三种是隐式传递数据,这种方式并不会把数据暴露出来。

<!-- About.vue -->
<template><div><router-link :to="{ name: 'bar', params: { username: 'xiaoqiang' } }">bar</router-link></div>
</template><!-- Bar.vue -->
<script>export default {mounted(){console.log(this.$route.params);}}
</script>

但是这里需要注意以下,隐式发送过来的数据,只是临时性获取的,一旦刷新页面,隐藏的数据就会消失,所以在使用的时候要额外注意以一下。

详解route对象与router对象

在前面小节中,我们频繁的使用过route对象和router对象,这两个对象在路由中非常的重要,下面我们来详细的学习一下。

route对象与router对象

首先route对象用来获取路由信息,而router对象用来调用路由方法的。具体区别在于,route对象是针对获取操作的,主要是操作当前路由的,而router对象是针对设置操作的,主要是操作整个路由系统对应的功能。

route对象具体功能如下:

  • fullPath
  • hash
  • href
  • matched
  • meta
  • name
  • params
  • path
  • query

主要就是一些路由信息,像常见的动态路由参数,query数据,meta元信息,url路径等等。

router对象具体功能如下:

  • addRoute
  • afterEach
  • back
  • beforeEach
  • beforeResolve
  • currentRoute
  • forward
  • getRoutes
  • go
  • hasRoute
  • push
  • removeRoute

主要就是一些方法,动态改变路由表,路由守卫, 历史记录的前进后退,编程式路由等等。

路由守卫详解及应用场景

正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。

守卫主要的作用就是在进入到指定路由前做一个拦截,看一下我们是否具备权限,如果有权限就直接进入,如果没权限就跳转到其他页面。

路由守卫分类

一般可以分为三种路由守卫使用的方式:

  • 全局环境的守卫
  • 路由独享的守卫
  • 组件内的守卫

先来看一下如何设置全局的路由守卫,一般在路由配置文件中进行设置。

router.beforeEach((to, from, next)=>{if(to.meta.auth){next('/');}else{next();}
})

其中to表示需要进入到哪个路由,from表示从哪个路由离开的,那么next表示跳转到指定的页面。

有时候我们只是想给某一个指定的路由添加守卫,那么可以选择设置路由独享的守卫方式。

const routes = [{name: 'bar',component: Bar,beforeEnter(to, from, next){if(to.meta.auth){next('/');}else{next();}}}
];

还可以通过在.vue文件中进行路由守卫的设置,代码如下:

<script>export default {name: 'FooView',beforeRouteEnter(to, from, next){if(to.meta.auth){next('/');}else{next();}}}
</script>

完整的导航解析流程

  1. 导航被触发。
  2. 在失活的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫(2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

Vuex共享状态的基本开发流程

在上一个小节中,我们介绍了什么是Vuex,本小节我们一起来看一下Vuex共享状态的基本开发流程。首先我们来看一下Vuex的经典流程图。
在这里插入图片描述

我们可以看到,基本上就是先准备好一个共享数据state,然后渲染我组件中,通过组件调用dispatch -> actions -> commit -> mutations的方式来进行state修改。

那么这里我们先不考虑dispatch -> actions,因为这两个环节是处理异步程序的,那么我们直接组件去调用commit就可以触发mutations中定义的方法,这样在这个方法中进行state的修改。

首先在/src/store/index.js创建一个状态管理的配置文件,然后在main.js中让vuex于vue进行结合,就像我们路由的使用一样。

//  store/index.js
const store = createStore({state: {count: 0},mutations: {change(state, payload){state.count += payload;}}
});//  main.js
import store from './store'
app.use(store)

下面看一下如何在页面中显示state数据和如何通过commit修改我们的共享数据,代码如下:

<template><div><button @click="change(5)">点击</button>hello home, {{ $store.state.count }}</div>
</template>
<script>export default {name: 'HomeView',methods: {handleClick(){this.$store.commit('change', 5);}}}
</script>

Vuex处理异步状态及应用场景

本小节中将讲解一下Vuex中如何处理异步程序,因为在上一个小节中提到过,mutations中只能处理同步,不能处理异步,所以异步的工作就交给了 actions 来完成。

那么如何触发actions中定义的方法呢,就需要通过dispatch进行触发,具体代码如下:

const store = createStore({state: {count: 0},actions: {change(context, payload){setTimeout(()=>{context.commit('change', payload)}, 1000)}},mutations: {change(state, payload){state.count += payload;}}
});
<script>export default {name: 'HomeView',methods: {handleClick(){this.$store.dispatch('change', 5);}}}
</script>

这样在vue devtools插件中就可以更好的观察到异步数据的变化。那么异步处理的应用场景有哪些呢?异步的获取后端的数据,这样可以利用状态管理来充当MVC架构中的C层,不仅衔接前后端,还能对数据进行共享,可以在切换路由的时候做到减少请求次数,而且状态管理配合本地存储进行数据持久化也是非常的方便。

Vuex计算属性和辅助函数的使用

Vuex中除了提供常见的异步处理和同步处理外,还提供了一些辅助的操作方式,比如:状态管理下的计算属性和简化操作的辅助函数。

getters计算属性

在Vuex中通过定义getters字段来实现计算属性,代码如下:

const store = createStore({state: {count: 0}getters: {doubleCount(state){return state.count * 2;}}
});
<template><div>{{ count }}, {{ doubleCount }}</div>
</template>

当count数据发生改变的手,对应的计算属性doubleCount也会跟着发生改变。

辅助函数

在Vuex中为了让我们使用共享数据或调用方法的时候,更加简单易用,提供了对应的辅助函数,分别为:mapState、mapGetters、mapMutations、mapActions。

<template><div><button @click="change(5)">点击</button>hello home, {{ count }}, {{ doubleCount }}</div>
</template><script>import { mapState, mapGetters, mapActions } from 'vuex';export default {name: 'HomeView',methods: {...mapActions(['change'])},computed: {...mapState(['count']),...mapGetters(['doubleCount'])}}
</script>

辅助函数最大的优点就是可以处理大量共享数据的需求,这样写起来会非常的简便,因为只需要往数组里添加子项即可。

Vuex-persist对数据进行持久化处理

默认情况下Vuex状态管理是不会对数据进行持久化存储的,也就是说当我们刷新浏览器后,共享状态就会被还原。那么我们想要在刷新的时候能够保持成修改后的数据就需要进行持久化存储,比较常见的持久化存储方案就是利用本地存储来完成,不过自己去实现还是比较不方便的,下面我们通过第三方模块来实现其功能。

模块github地址:https://github.com/championswimmer/vuex-persist。根据地址要求的配置操作如下:

// npm install vuex-persistimport VuexPersistence from 'vuex-persist';
const vuexLocal = new VuexPersistence({storage: window.localStorage,reducer: (state) => ({count: state.count})
})const store = createStore({state: {count: 0,msg: 'hello'}plugins: [vuexLocal.plugin]
});

默认情况下,vuex-persist会对所有共享状态进行持久化,那么如果我们只需要对指定的属性进行持久化就需要配置 reducer字段,这个字段可以指定需要持久化的状态。

这样当我们修改了state下的count,那么刷新的时候会不会还原了,并且通过chrome浏览器中Application下的Local Storage进行查看。

Vuex分割模块及多状态管理

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

那么这个时候,所有共享状态的值都在一起,所有的方法也都放在了一起,维护起来非常的不方便。那么Vuex中可利用modules属性来配置模块化的共享状态,那么对于后期维护起来是非常方便的,也利于大型项目的架构。

在/store下创建一个modules文件夹,然后编写一个message.js,代码如下:

const state = {msg: 'hello'
};
const getters = {upperMsg(state){return state.msg.toUpperCase()}
};
const actions = {};
const mutations = {change(state, payload){state.msg = payload;}
};
export default {namespaced: true,state,getters,actions,mutations
}

模块中的选项跟index.js中的选项是一样的,对外提供接口的时候,可以看到一个namespaced字段,这表示当前模块的一个命名空间,主要是为了防止跟其他模块之间产生冲突,在调用的时候需要携带对应的命名空间标识符才行。

再来看一下index.js如何去收集我们的模块,并如何去使用我们的模块。

// store/index.js
import message from '@/store/modules/message'
const store = createStore({modules: {message}
});
<!-- About.vue -->
<template><div><button @click="change('hi')">点击</button>hello about, {{ msg }}, {{ upperMsg }}</div>
</template><script>
import { mapState, mapGetters, mapMutations } from 'vuex';export default {name: 'AboutView',methods: {// handleClick(){//   this.$store.commit('message/change', 'hi');// }...mapMutations('message', ['change'])},computed: {//  msg(){//   return this.$store.message.msg;//  },//  upperMsg(){//   return this.$store.getters['message/upperMsg']//  }...mapState('message', ['msg']),...mapGetters('message', ['upperMsg'])}}
</script>

在辅助函数的情况下,也可以进行很好的调用,辅助函数的第一个参数就是命名空间的名字。

组合式API中使用Router和Vuex注意事项

前面介绍的路由和状态管理都是在选项式API中进行使用的,那么路由和状态管理在组合式API中使用的时候,需要注意哪些问题呢?

主要就是路由会提供两个use函数,分别为:useRoute和useRouter;同理状态管理页提供了一个use函数,useStore来操作的。

先来看一下路由相关use函数的使用情况:

<script setup>
import { useRoute, useRouter } from 'vue-router'
const route = useRoute();
const router = useRouter();
console.log( route.meta );
console.log( router.getRoutes() );
</script>

基本上跟选项式API中的用法是一样的,并没有太大的区别。

再来看一下状态管理相关use函数的使用情况:

<script setup>
import { useStore } from 'vuex'
const store = useStore();
console.log( store.state.count );
console.log( store.state.message.msg );
</script>

得到store对象,接下来的操作也是跟选项式API中使用的是一样的。

Router_Vuex的任务列表综合案例

本小节将对本章学习的路由加状态管理做一个综合案例,通过案例来巩固本章所学知识点。

在这里插入图片描述

首先先来配置案例中的路由,主要有三个页面,分别对应所有任务,已完成任务,未完成任务。

import { createRouter, createWebHistory } from 'vue-router'
import Todo from '@/views/Todo.vue'
import Complete from '@/views/Complete.vue'
import Incomplete from '@/views/Incomplete.vue'
const routes = [{path: '/',redirect: '/todo'},{path: '/todo',component: Todo},{path: '/complete',component: Complete},{path: '/incomplete',component: Incomplete,}
];
const router = createRouter({history: createWebHistory(),routes
})
export default router;

在来配置一下Vuex状态管理,主要对任务列表进行共享状态处理:

import { createStore } from "vuex";
const store = createStore({state: {todoList: [{isChecked: true, id: 1, task: '第一个任务'},{isChecked: false, id: 2, task: '第二个任务'}]},actions: {},mutations: {add(state, payload){state.todoList.unshift({ isChecked: false, id: state.todoList.length, task: payload });}},getters: {complete(state){return state.todoList.filter((v)=> v.isChecked)},incomplete(state){return state.todoList.filter((v)=> !v.isChecked)}}
});
export default store;

最后看一下三个页面的基本逻辑处理:

<!-- Todo.vue -->
<template><div><ul><li v-for="item in todoList" :key="item.id" :class="{ through: item.isChecked }"><input type="checkbox" v-model="item.isChecked"> {{ item.task }}</li></ul></div>
</template>
<script setup>
import { computed, defineComponent } from 'vue';
import { useStore } from 'vuex';
defineComponent({name: 'TodoView'
});
const store = useStore();
const todoList = computed(()=> store.state.todoList)
</script>
<!-- Complete.vue -->
<template><div><ul><li v-for="item in todoList" :key="item.id" :class="{ through: item.isChecked }"><input type="checkbox" v-model="item.isChecked"> {{ item.task }}</li></ul></div>
</template>
<script setup>
import { computed, defineComponent } from 'vue';
import { useStore } from 'vuex';
defineComponent({name: 'CompleteView'
});
const store = useStore();
const todoList = computed(()=> store.getters.complete)
</script>
<!-- Incomplete.vue -->
<template><div><ul><li v-for="item in todoList" :key="item.id" :class="{ through: item.isChecked }"><input type="checkbox" v-model="item.isChecked"> {{ item.task }}</li></ul></div>
</template>
<script setup>
import { computed, defineComponent } from 'vue';
import { useStore } from 'vuex';
defineComponent({name: 'IncompleteView'
});
const store = useStore();
const todoList = computed(()=> store.getters.incomplete)
</script>

搭建 Vite3 + Pinia2 组合模式

前面我们介绍过Vite和Pinia,其中Vite是最新的脚手架,基于原生ESM方式;而Pinia则是最新的状态管理,比Vuex使用起来更加简单。

本小节我们将演示Vite如何去搭配Pinia来完成项目的开发。

首先对Vite3脚手架进行初始化的安装。

  1. 安装脚手架

    # npm 6.x
    npm create vite@latest vite-study
    # yarn
    yarn create vite vite-study
    # pnpm
    pnpm create vite vite-study
    
  2. 选择框架:因为Vite可以和很多框架配合使用,所以这里我们选择:Vite + Vue

    ? Select a framework: » - Use arrow-keys. Return to submit.Vanilla
    >   VueReactPreactLitSvelte
    
  3. 选择变体:这里先选择自定义形式

    ? Select a variant: » - Use arrow-keys. Return to submit.JavaScriptTypeScript
    >   Customize with create-vueNuxt
    
  4. 选择安装Pinia

    ? Add Pinia for state management? >> No / Yes
    Yes
    
  5. 进入项目:安装第三方模块,并启动项目

    cd vite-study
    npm install
    npm run devVITE v3.1.0  ready in 408 ms➜  Local:   http://127.0.0.1:5173/➜  Network: use --host to expose
    

在安装好Vite后,打开/src/stores可以看到自动安装好了一个示例模块counter.js,代码如下:

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {const count = ref(0)const doubleCount = computed(() => count.value * 2)function increment() {setTimeout(()=>{count.value++}, 2000)}return { count, doubleCount, increment }
})

这里的风格可以是上一个小节中介绍的配置写法,也可以利用组合式API风格来编程Pinia。这里做了一个共享状态count,又做了一个计算属性doubleCount,还有一个方法increment。

在共享方法中是不分同步还是异步的,对于vue devtools都是可以很好的进行监控的,所以比Vuex使用起来要简单一些。下面看一下共享状态是如何进行渲染和方法调用的。

<!-- App.vue -->
<script setup>import { useCounterStore } from './stores/counter';import { storeToRefs } from 'pinia';const counterStore = useCounterStore();const { count, doubleCount } = storeToRefs(counterStore);const handleClick = () => {counterStore.increment();};
</script>
<template><header><button @click="handleClick">点击</button>{{ count }}, {{ doubleCount }}</header>
</template>

Pinia对于模块化的操作方式也比Vuex要简单一些,直接在/stores创建下新创建一个模块JS即可,如:message.js。message.js的代码跟counter.js的代码是一样的格式,使用的时候也是一样的操作行为。

总结内容

  • 了解什么是前端路由,以及Vue3中如何使用vue-router路由
  • 掌握路由的基本操作,如:编程式路由、动态路由、路由守卫等
  • 了解什么是共享状态,以及Vue3中如何使用vuex共享状态
  • 掌握vuex的基本操作,如:同步异步方法、模块化、持久化等
  • 综合应用以及Vuex下一代版本,Pinia存储库

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数学视野】Softmax 函数和 Gibbs 分布之间的数学桥梁

Softmax 函数和 Gibbs 分布之间的数学桥梁 文章目录 一、说明二、Softmax 函数的定义和组件三、从逻辑到多类的泛化3.1 连接到 Gibbs 分布3.2 统计力学背景3.3 切换到 Softmax 功能 四、优化和计算稳定性4.1 Softmax 的梯度4.2 链接到信息论 五、总结 一、说明 softmax 函数是各…

瘦身秘籍:如何使用 PyInstaller 打造超小型 Python 可执行文件

你是否曾经尝试过将你的 Python 程序打包成一个可执行文件&#xff0c;却发现生成的文件大得惊人&#xff1f;别担心&#xff0c;本文将教你如何使用 PyInstaller 尽可能减小生成的 onefile 大小&#xff0c;让你的程序轻盈如风&#xff01; 1. 使用虚拟环境 首先&#xff0c…

MyBatis(XML映射器操作)

文章目录 XML映射器操作&#xff08;XxxMapper.xml&#xff09;文件目录1.基本介绍1.优点2.常用顶级元素 2.环境配置1.在原来的父模块下创建一个子模块2.删除没用的两个文件夹3.创建基本目录4.父模块的pom.xml5.jdbc.properties6.mybatis-config.xml7.测试使用MonsterMapperTes…

【JS篇之】异常

前言&#xff1a;在代码编写过程中&#xff0c;最常遇到的就是程序异常。其实异常并非坏事&#xff0c;它可以让开发人员及时发现、定位到错误&#xff0c;提醒我们做正确的事情&#xff0c;甚至在某些时候&#xff0c;我们还会手动抛出异常。 1.异常的分类 在JS中&#xff0…

考研英语作文---写作要义

应用文结构 例题 信件 ------第一段写法 第一段 第二段 第三段 第一段 第三段 第二段 强调句方式开头方式 练习

【Vue 2.x】学习vue之一基础部分

文章目录 Vue 一基础部分第一章1、git两个分支主分支子分支 使用方法方式1&#xff1a;采用命令的方式操作分支方式2&#xff1a;在idea中使用git的分支 向git远程仓库提交时忽略文件使用git时的一些冲突注意事项 2、Vue问题1&#xff1a;什么是Vue&#xff1f;问题2&#xff1…

数据库(MySQL)—— DML语句

数据库&#xff08;MySQL&#xff09;—— DML语句 什么是DML语句添加数据给全部字段添加数据批量添加数据 修改数据删除数据 什么是DML语句 在MySQL中&#xff0c;DML&#xff08;Data Manipulation Language&#xff0c;数据操纵语言&#xff09;语句主要用于对数据库中的数…

金融案例:统一查询方案助力数据治理与分析应用更高效、更安全

随着企业数据规模的增长和业务多元化发展&#xff0c;海量数据实时、多维地灵活查询变成业务常见诉求。同时多套数据库系统成为常态&#xff0c;这既带来了数据管理的复杂性&#xff0c;又加大了数据使用的难度&#xff0c;面对日益复杂的数据环境和严格的数据安全要求&#xf…

开发一个语音聊天社交app小程序H5需要多少钱?

社交&#xff0c;即时通讯APP系统。如何开发一个社交App||开发一个即时通信应用是一项复杂而充满挑战的任务&#xff0c;需要考虑多个技术、开发时间和功能方面的因素。以下是一个概要&#xff0c;描述了从技术、开发时间和功能角度如何开发这样的应用&#xff1a; 1. 技术要点…

Linux查看某一个程序的安装路径

前提 这一方法的前提条件是&#xff1a;必须是运行着的程序。 方法 这里以查找运行的nginx的安装目录为例。 查看nginx运行进程&#xff0c;查看当前进程的PID&#xff0c;例子中的PID就是7992。 nginps -aux|grep nginx执行ls -l /proc/进程号/exe&#xff0c;然后会打印…

十一、大模型-Semantic Kernel与 LangChain 的对比

Semantic Kernel 与 LangChain 的对比 Semantic Kernel 和 LangChain 都是用于开发基于大型语言模型&#xff08;LLM&#xff09;的应用程序的框架&#xff0c;但它们各有特点和优势。 基本概念和目标 Semantic Kernel 是一个由微软开发的轻量级 SDK&#xff0c;旨在帮助开发…

C++Day 7 作业

1、lambda #include <iostream>using namespace std;int main() {int a 100;int b 90;int temp;auto fun [&]()mutable->int {temp a;ab;btemp;};fun();cout<<a<<endl;return 0; } 2、vector #include <iostream> #include <vector>…