JavaScript入门 Vuex/elementPlus UI组件库 Day08

vuex


什么是vuex

状态管理器

        Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。因为我们是MVVM框架,view取决于我们model(数据),view如何展示称为元素状态,那么model数据也就是状态数据。

         vuex是基于flux设计原理实现的一个单向数据流状态管理器,但他不是唯一的状态管理器,还有个pinia

        管理状态数据的库

Vuex特点

        全局数据

                全局变量会导致全局数据污染,所以vuex一定是一个闭包

                集中式存储管理应用的所有组件的状态

        实现数据共享:简化Vue组件间通讯,可跨组件(子传父、父传子)

                eventBus:两个组件必须同时存在,并且监听要早于触发:数据不会缓存

                provide+inject:修改数据不能在子组件中进行,可以用computed缓存

                父子传子:不能跨组件传值,只能是父子关系才可以

        数据可预测化:使用发布订阅机制来实现;保证状态以一种可预测的方式发生变化(有序进行数据存储获取)

核心概念与原理

1. state:

页面状态管理容器对象。集中存储Vue components状态数据

定义和初始化全局需要托管的数据,因为托管的数据是状态,所以这个属性是state

2. mutations:

修改数据/扭转状态数据

状态改变操作方法,由actions中的commit(‘mutation 名称’)来触发。

是Vuex修改state的唯一推荐方法。该方法只能进行同步操作且方法名只能全局唯一

  • 修改数据的方法不能为异步方法,为什么?

     因为异步函数,什么时候结束,不清楚,但是setToken方法执行以后,会立刻发布更新消息,那么这样,发布出去的消息有问题,数据更新还没有执行完成。

        而且flux设计原理,规定mutation必须为一个纯函数--输出必须完成依赖输入,不能修改外部数据

3. commit:

状态改变提交操作方法。对mutation进行提交,是唯一能执行mutation的方法。

是一个提交数据的方法    

4. actions:

操作行为处理模块,执行数据处理的动作属性。这个动作不可以修改数据,因为修改数据只能在mutations可以。所以它获取到异步数据后需要一个commit方法进行数修改

actions可以定义异步任务,由组件中的$store.dispatch('action 名称', data1)来触发。然后由commit()来触发mutation的调用 , 间接更新 state。

5. dispatch:

操作行为触发方法,是唯一能执行action的方法。

6. getters:

state对象读取方法,取数据。图中没有单独列出该模块,应该被包含在了render中,Vue Components通过该方法读取全局state对象。 

getters和state是两个不同的模块,所以数据不能共享,那么只有这个方法把值传递进来

getters是获取数据的getter方法

因为getter方法传递给vuex以后,他还需要加工,所以可以把state传递进来

7.this.$store

this.$store中只有三个属性可用:getters、commit、dispatch,其他都是 _ 开头的私有属性

        getters是获取数据的getter方法

        commit提交数据,定义接口commit('type提交给这个方法中去',提交的数据),是一个提交数据的方法

        dispatch调遣/派遣一个动作,即actions


 使用步骤

1.下载安装

npm install vuex@4.0.2  --save 
npm install vuex@next --save

2.在src下的main.js引入、注册

//src/main.js
import { createApp } from 'vue'
import App from './views/index.vue'
import Vuex from 'vuex'
//Store这个方法/类执行以后会得到一个Store实例
const store = new Vuex.Store({
    state:{//定义和初始化全局需要托管的数据,因为托管的数据是状态,所以这个属性时state
        token: 100,
        userInfo: {}
    },
    getters:{
         mytoken(_state) {
            return _state.token
        },
        userInfo: _state => _state.userInfo
    },
    // 执行数据处理的动作属性中去执行--dispatch方法--调遣、派遣一个动作
    actions: {
        // 这个动作没有办法执行数据修改,因为数据修改只有mutations可以,所以它获取到异步数据以后需要一个commit方法进行数据修改
        async getUserInfo(_store, id) {
            let result = await ajax(id)
            _store.commit('setUserInfo', result)
        }
    },
 mutations: {
        setToken(_state, _token) {
            // 修改的是state的数据,这里没有state对象,那么只有这个方法把state传递进来
            // 第二个参数才是我们传递的数据
            _state.token = _token
        },
        setUserInfo(_state, _userInfo) {
            console.log('----------------- 赋值', _userInfo)
            _state.userInfo = _userInfo
        }
    }

})
// 也需要注入store
createApp(App).use(store).mount('#root')

3.主页 views/index.vue 获取后显示值

//views/index.vue
<template>
    <div class="box">
        <h3>系统的名字</h3>
        <p>
            当前的token值:{{$store.getters.mytoken}}
        </p>
        <Home/>
    </div>
</template>
<script>
    import Home from './Home.vue'
    export default {
        components: { Home },
        created() {
            console.log(this.$store.getters.mytoken)
        }
    }
</script>

 4.首页 主页的子组件  src/views/Home.vue 修改上面首页token的值 commit(传递值)

//src/views/Home.vue
<template>
    <div class="box">
        <hr>
        <h4>首页 -- 欢迎您 -- {{name}}</h4>
        <p>
            <button @click="changeToken">修改token数据</button>
        </p>
        <Child/>
    </div>
</template>
<script>
    import Child from './Child.vue'
    export default {
        components: { Child },
        computed: {
            name() {
                // console.log('userInfo-----',this.$store.getters.userInfo);
                return this.$store.getters.userInfo.name
            }
        },
        methods: {
            changeToken() {
                let value = this.$store.getters.mytoken
                this.$store.commit('setToken', value + 1)
            }
        }
    }
</script>

 5.首页子组件 传递值给首页的欢迎您

//src/views/Child.vue
<template>
    <div class="box">
        <hr>
        <h5>这里是Home的子组件</h5>
        <p>
            名字: <input v-model='myname' type="text">
        </p>
        <p>
            <button @click="asyncFunc">异步请求数据修改</button>
        </p>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                myname: ''
            }
        },
        methods: {
            asyncFunc() {
                this.$store.dispatch('getUserInfo', this.myname)
            }
        }
    }
</script>

 使用步骤

1.下载安装:

npm install vuex@4.0.2  --save npm install vuex@next --save

2.新建实现store文件夹  index.js文件

import {createStore} from 'vuex'  //引入vuex,解构createStore
const store = createStore({  //使用createStore
    state:{  //状态
        count:0 //状态数据
    },
    mutations:{  //方法
        //state:状态,第二个及以后的参数是传入的参数用逗号隔开
        PLUS(state,user){  //大写_大写
            state.count++
            //stare.count = user
        },
        MINUS(state){
            state.count--
        }
    },
    actions:{  //方法
        plus({commit}){  //commit方法调用
            commit('PLUS')  //mutations下的方法名
        },
        minus({commit}){
            commit('MINUS')
        }
    },
    getters:{ //获取值
        num:(state)=>state.count
    }
})
export default store

3. main.js文件引入集成到vue  

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store' //store文件下的store
const app = createApp(App)
app.use(router)
app.use(store)  //集成
app.mount('#app')

4.使用vuex 

<template>
    <div>
        <p>显示vuex状态count : {{num}}</p>  <!--显示状态数据-->
        <button type="button" @click="onPlus">加一</button> <!--加一操作 触发方法操作store数据-->
    </div>
</template>
<script>
export default {
    //methods - 创建方法
    methods:{
        onPlus(){               //actions里的定义的名字,
            this.$store.dispatch('plus',参数)   //调用方法.将参数传回store
        }
    },
    computed:{
        num(){
            return this.$store.getters.num
        }
    }
}
</script>

...map 辅助函数

mapGetters 直接获取getters值

mapActions 直接操作行为处理

下载、创建、引入集成与前面一样 ,使用方法有些不同

使用

1.在组件里引入 .vue

<script>
import { mapGetters,mapActions } from 'vuex'  //引入
</script>
<template>
	<div>
		<p>显示vuex状态count : {{ num }}</p>
		<button type="button" @click="minus">减一</button>
	</div>
</template>

2.使用  .vue

export default {
	data() {
		return {}
	},
	//methods - 创建方法
	methods: {
		// onMinus() {
		// 	this.$store.dispatch('minus')
		// },   上下实现的效果一样
        // ...mapActions({
		//计算属性名: vuex中actions定义名称
        //     onMinus:'minus'
        // })  计算属性名随意取,如果和actions名一样就用下面这个方式
        ...mapActions(['minus']) //当计算属性名和vuex中getters定义名称相同时,使用如下方式实现
	},
	computed: {
		// num(){
		//     return this.$store.getters.count
		// },
		// ...mapGetters({
		//计算属性名: vuex中getters定义名称
		//     num:'count'
		// })
		...mapGetters(['num']),
	},
}

持久化存储

1.安装vuex-persistedstate插件

npm install vuex-persistedstate --save

 2.在store中的index.js中引入

该插件默认持久化所有state,当然也可以指定需要持久化的state:

import { createStore } from 'vuex'
import createPersistedState from 'vuex-persistedstate'  //引入持久化 哪个vue需要持久化就在哪里引入
const store = createStore({
    plugins: [
		createPersistedState({
			storage: window.sessionStorage, //默认 修改存储的状态
			key: 'userkey',   //上下两个可以不写 默认key为vuex
            reducer(data) {
              return {
              // 设置只储存state中的myData  不设置为存储所有
              myData: data.myData
            }
		}),
	],
})

Module模块化

应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter 

1.在store文件下创建modules文件夹,文件夹内创建各种所需要处理的模块

//cart.js
const cart = {  //在cart这个命名空间下
	namespaced: true, //命名空间指定模块名
	state: {
		list: [],
	},
	mutations: {
		ADD_Cart(state, product) {
			state.list.push(product)
		},
	},
	actions: {
		addCart({ commit }) {
			commit('ADD_Cart')
		},
	},
	getters: {
		// list:state=>state.list
		list(state) {
			return state.list
		},
	},
}
export default cart

store中的index.js 

import { createStore } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import user from './modules/user'  //导入user.js
import cart from './modules/cart'  //导入cart.js
const store = createStore({
	modules: { //集成模块
		user,
		cart,
	}
})
export default store
//Home.vue
import { mapGetters } from "vuex";
export default {
	data() {
		return {
			// user: null,
		}
	},
	computed:{
		user(){
			return this.$store.getters['cart/list'] //cart这个命名空间下的list
		}
		// ...mapGetters(['user'])
	},

elementPlus UI组件库


1.下载安装组件库

NPM****
$ npm install element-plus --save
# Yarn
$ yarn add element-plus
# pnpm
$ pnpm install element-plus

2. 按需导入 自动按需导入推荐

首先你需要安装unplugin-vue-components 和 unplugin-auto-import这两款插件

npm install -D unplugin-vue-components unplugin-auto-import

3.vite.config.js 配置插件

 import { defineConfig } from 'vite'
 import AutoImport from 'unplugin-auto-import/vite'
 import Components from 'unplugin-vue-components/vite'
 import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
 export default defineConfig({
 // ...
 plugins: [
     // ...
     AutoImport({
     resolvers: [ElementPlusResolver()],
     }),
     Components({
     resolvers: [ElementPlusResolver()],
     }),
 ],
 })

 Icon图标下载

npm install @element-plus/icons-vue

 按需导入

直接通过设置类名为 el-icon-iconName 来使用即可 

//Login.vue        
<script>import {User} form '@element-plus/icons-vue'</script>
<el-icon> <User /> </el-icon>
<script>export default {
	components: {
		User,
		Lock,
	},
}</script>

//或者
<i class="el-icon-share"></i>
<i class="el-icon-delete"></i>
<el-button type="primary" icon="el-icon-search">搜索</el-button>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值