一.vuex
1.简单介绍
一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
特点
多个组件之间实现数据的共享,任何一个组件去操作vuex中共享的数据,其它组件都会同 步更新
共享对象store是独立于App根组件之外
2.安装vuex
特别说明
vue2 安装vuex3 -->npm install vuex@3
vue3 安装vuex4 -->npm install vue@4
创建目录和js文件
目录 :vuex
jvuex目录下创建js文件:store.js
在store.js文件中创建核心对象,并对外暴露
store.js文件的一种写法
(import Vue from 'vue/types/umd' 错误 ---->改为 :import Vue from 'vue')
// 引入Vue,Vue.use(vuex)会使用到Vue对象
import Vue from 'vue/types/umd'
// 导入vuex插件
import Vuex from 'vuex'
// 使用插件
Vue.use(Vuex)
const store = new Vuex.store({
// 他是一个负责执行某个行为的对象
actions: {},
// 他是一个负责更新的对象
mutations: {},
// 他是一个状态对象
state: {}
})
// 暴露store对象
export default store
store.js文件的第二种写法
// 引入Vue,Vue.use(vuex)会使用到Vue对象
import Vue from 'vue/types/umd'
// 导入vuex插件
import Vuex from 'vuex'
// 使用插件
Vue.use(Vuex)
const actions = {}
const mutations = {}
const state = {}
export default new Vuex.store({
// 他是一个负责执行某个行为的对象
actions: actions,
// 他是一个负责更新的对象
mutations: mutations,
// 他是一个状态对象
state: state,
})
store.js文件的第三种写法
// 引入Vue,Vue.use(vuex)会使用到Vue对象
import Vue from 'vue/types/umd'
// 导入vuex插件
import Vuex from 'vuex'
// 使用插件
Vue.use(Vuex)
const actions = {}
const mutations = {}
const state = {}
export default new Vuex.store({actions,mutations,state})
store.js文件编写好后,在全局配置文件main.js中进行配置
import Vue from 'vue'
import App from './App.vue'
// 导入Vuex插件的核心对象store
import store from './vuex/store'
new Vue({
render: h => h(App),
/**
* 左边是配置项,右边是变量名,加上这个配置项后,vm和所有的vc对象都会多一个$store属性
* 也就是说,可以通过vm.$store获取到store对象
*/
store: store,
}).$mount('#app')
整体过程(store.js)
// 引入Vue,因为下面使用Vuex插件的时候需要Vue
import Vue from 'vue'
// 引入vuex插件
import Vuex from 'vuex'
// 使用插件
Vue.use(Vuex)
// 创建三个vuex插件的核心对象:actions对象、mutations对象、state对象
const actions = {
// N多个action
// 每一个action都是一个callback(回调函数)
// 在action这种回调函数中编写复杂的业务逻辑
// 有个原则:action是专门用来处理业务逻辑,或者说发送AJAX请求的。
//plusOne : function(){}
// 简写
// context参数:context是vuex的上下文(context可以看做是store对象的缩小版)
// value参数:传过来的数据
plusOne(context, value){
// 处理业务
value = value + 1
// 调用其它的action这个回调函数
//context.dispatch('otherAction', value)
// 业务逻辑处理完成之后,继续向下一个环节走,就轮到了数据的更新。
// 提交上下文环境(所有的事儿都做完了,该最后一步了,更新数据了,怎么办?提交)
context.commit('PLUS_ONE', value)
},
// 这里可能还会有其它的action
// ...
/* otherAction(context, value){
console.log(6666)
} */
}
const mutations = {
// N多个mutation
// 每一个mutation都是一个callback(回调函数)
// 每一个mutation这个回调函数的作用就是:更新state
// 只要state一更新,因为是响应式的,所以页面就重新渲染了。
// state参数:状态对象
// value参数:上一环节传过来的数据
PLUS_ONE(state, value){
state.num += value
}
}
// 等同于Vue当中的data(只不过这里我们不叫做数据,叫做状态)
// 状态对象(数据对象),已经做了响应式处理的。
const state = {
num : 0
}
// 简写形式
export default new Vuex.Store({actions,mutations,state})
/* // 创建store对象(这个store对象是vuex插件中的老大,最核心的对象,这个对象store是用来管理actions对象、mutations对象、state对象。)
const store = new Vuex.Store({
// 它是一个负责执行某个行为的对象
actions : actions,
// 它是一个负责更新的对象
mutations : mutations,
// 它是一个状态对象
state : state
})
// 导出store对象(暴露之后,别人想用可以使用import进行引入)
export default store */
三个vuex插件的核心对象:actions对象、mutations对象、state对象
actions对象:包含多个action对象,每一个action对象都是一个回调函数,在action中编码复杂的业务逻辑,或者发送ajax请求
(加一操作)
const actions : { plusOne(context, value){ value = value + 1 // 调用其它的action这个回调函数 //context.dispatch('otherAction', value) // 业务逻辑处理完成之后,继续向下一个环节走,就轮到了数据的更新。 // 提交上下文环境(所有的事儿都做完了,该最后一步了,更新数据了,怎么办?提交) context.commit('PLUS_ONE', value) }, }
mutations对象: 包含有多个mutation, 每一个mutation都是一个callback(回调函数),每一个mutation这个回调函数的作用就是:更新state,只要state一更新,因为是响应式的,所以页面就会重新渲染。
state参数:状态对象
value参数:上一环节(actions对象)传过来的数
state对象:(等同于Vue当中的data(只不过这里我们不叫做数据,而是叫做状态))状态对象(数据对象),已经做了响应式处理的。
APP.vue代码
<template>
<div>
<h1>数字:{{$store.state.num}}</h1>
<button @click="plusOne">点我加1</button>
</div>
</template>
<script>
export default {
name : 'App',
data() {
return {
startNum : 0
}
},
methods: {
plusOne(){
// 这里的代码在实际开发中可能会比较复杂。
// 业务逻辑复杂,代码比较多。
// 如果你将这些代码放到这里的话,这些业务逻辑代码无法得到复用。
// 无法在其他组件中使用,在其他组件中使用的时候,你还需要把这些代码再写一遍。
//this.$store.state.num++
// 调用vuex的API。
// dispatch是vuex的API。调用这个方法之后,store对象中的plusOne这个action回调函数会被自动调用。
// dispatch:分发
// 交给plusOne这个action去处理这个事儿。
this.$store.dispatch('plusOne', this.startNum)
}
},
}
</script>
调用vuex的API
dispatch是vuex的API。调用这个方法之后,store对象中的plusOne这个action回调函数会被自动调用。 交给plusOne这个action去处理这个事
--dispatch:分发
未完待续
二.route
Vue.js 的路由(Routing)是构建单页面应用(SPA, Single Page Application)的核心部分,它允许用户在不同的视图(或页面)之间进行导航,而无需重新加载整个页面。Vue Router 是 Vue.js 官方的路由管理器,与 Vue.js 深度集成,使得构建单页面应用变得简单
- route:路由器是用来管理/调度各个路由的
- router:对于一个应用来说,一般路由器只需要一个,但路由是由多个的
每一个路由都由key和value组成:key是路径,value是组件,key和value之间的映射关系就是路由
路由的本质:一个路由表示了一组对应关系
路由器的本质:管理多组对应关系(管理路由)
使用路由
vue-router 也是一个插件
安装vue-router
- vue2 要安装vue-router3 npm i vue-router@3
- vu3 要安装vue-router4 1 npm i vue-router@4
1.在main.js文件配置
- main.js 中引入并使用vue-router 导入:importVueRouter from ‘vue-router’
- 使用:Vue.use(VueRouter) new Vue 时添加新的配置项:一旦使用了vue-router插件,在newVue的时候可以添加一个全新的配置 项:router
import Vue from 'vue' import App from './App.vue' import router from '@/router/index.js' // 导入vue-router插件 import VueRouter from 'vue-router' Vue.config.productionTip = false // 使用vue-router插件 Vue.use(VueRouter) new Vue({ render: h => h(App), // router : 路由器对象 router: router }).$mount('#app')
2.在src目录下,新建一个router文件夹,新建一个index.js
1.导入vue-router插件
import VueRouter from "vue-router";
2.创建路由器对象,在路由器对象中配置路由
const router = new VueRouter({ })
3.配置路由
- routes 是一个数组,数组的每一个元素都是一个路由对象
- path 是路径,当监测到地址栏发生的变化与路径相同时,就切换到与之映射的组件
path: '/hebei',
路径每次都以 / 开始
- component 是组件,配置组件前,需要把配置的组件导入
routes: [ { path: '/hebei', component : hebei },
4.暴露路由器对象
// 暴露路由器对象 export default router
index.js整体代码
// 导入vue-router插件 import VueRouter from "vue-router"; // 导入需要路由的组件 import hebei from "@/components/hebei.vue"; import henan from "@/components/henan.vue"; // 创建路由器对象,在路由器对象中配置路由 const router = new VueRouter({ // 在这里配置路由 routes: [ { path: '/hebei', component : hebei }, { path: '/henan', component : henan } ] }) // 暴露路由器对象 export default router
3.在<template>标签中使用路由
- 使用了路由方式,就不能使用超链接标签了
<router-link to="在index.js文件中配置的path路径"></router-link>
- 告诉vue组件在哪里展示(占位)
<router-view></router-view>
运行截图
注意:地址栏与组件的变化
3.多级路由
1.在router目录下的index.js文件的在添加一个配置项 children
routes: [ { path: '/hebei', component: MyHebei, children: [{ path: 'handan', component: handan }] }]
- 多级路由中的 children的 path 配置项不需要在添加 / 开头
- 在使用路由的组件中,<router-link to="所有父组件的path/children的path"
<template> <div> <div> <P><router-link to="/hebei/handan">河北页面</router-link></P> </div> <router-view></router-view> </div> </template>
通常,组件分为普通组件和路由组件
普通组件放在components目录下
路由组件放在pages目录下
4.路由query传参 ----提高复用性
从MyHebei.vue组件传递参数到HanDan组件
<template> <div> <div> <P ><router-link :to="`/hebei/handan?areaName=${areaName[0]}`" >河北页面</router-link ></P > </div> <router-view></router-view> </div> </template> <script> export default { name: "MyHebei", // 传递的数据 data() { return { areaName: ["光明区"], }; }, }; </script>
<router-link :to="`/hebei/handan?areaName=${areaName[0]}`">河北页面</router-link>
使用模板字符串
注意:data 配置项绑定 v-bind
HanDan.vue组件接收参数
<template> <div>{{ $route.query }}</div> </template> <script> export default { name: "HanDan", mounted() { console.log(this.$route.query); }, }; </script>
接收 : $route拿到与之关联的路由对象
$route.query拿到传递的参数
5.路由中以对象传递参数
<template> <div> <div> <P> <router-link :to="{ path: '/hebei/handan', query: { areaName: areaName[0], }, }">河北页面</router-link> </P> </div> <router-view></router-view> </div> </template> `/hebei/handan?areaName=${areaName[0]}` <script> export default { name: "MyHebei", // 传递的数据 data() { return { areaName: ["光明区"], }; }, }; </script>