# vue+elementUI电商后台管理 **Repository Path**: bigcat_li/vbYFtsSm ## Basic Information - **Project Name**: vue+elementUI电商后台管理 - **Description**: vue+elementUI电商后台管理 - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-04-11 - **Last Updated**: 2023-06-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # vuex 核心目标: (1)vuex的基本使用步骤 (2)vuex的核心概念 (3)vuex实现常见的业务开发功能 #### vuex的概念:组件间共享数据的一种方式 父传子:v-bind属性绑定(拓展1) 子传父:v-on事件绑定(拓展2) 兄弟组件间的数据共享:EventBus(事件总线)(拓展3) ## 任意组件通信:vuex `vuex`是实现集中式状态、数据管理的一个`vue插件 `,多个组件共享状态进行集中式的管理(读、写) #### 思路 > - 1.npm i vuex > - 2.Vue.ues(Vuex) > - 3.store(创建) > - 4.vc==>store(让组件看得见store) #### `组件仍然保有局部状态` 使用 Vuex 并不意味着你需要将**所有的**状态放入 Vuex。虽然将所有的状态放到 Vuex 会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态。你应该根据你的应用开发需要进行权衡和确定。 ### 1.搭建vuex的开发环境(全局配置store) 全局配置`$store` > **实现思路** > > - 在`main.js`中引入vuex插件,挂载vuex,`作用`:创建vm时就可以传入store配置项进去,这样就可以全局使用$store了(store提供dispatch和commit方法) > - `import`最先被解析,无论它在何位置。所以将`Vue.ues(vuex)`放到src->store->index.js中去解析 1.创建文件:```src/store/index.js``` ```bash //该文件用于创建Vuex中最为核心的store //引入vue 为挂载vuex import Vue from 'vue' //引入vuex import Vuex from 'vuex' //全局挂载vuex 使用vuex插件 Vue.use(vuex) //准备actions--用于响应组件的动作 const action = {} //准备mutations--用于操作数据(state) const mutations = {} //准备state--用于存储数据 const state = {} //创建store 向外暴露store export default new Vuex.Store({ actions: actions, mutations, state, }) ``` 2.在```main.js```中创建vm时传入```store```配置项 ```bash //在main.js(vue项目) import Vue from 'vue' import Vuex from 'vuex' //完成02后 引入store import store from '相对路径' //挂载 完成02后去store->index.js挂载vuex,因为import在Vue.use()前执行,但执行store中的数据需要先挂载vuex才行!!!! //Vue.use(vuex) new Vue({ el:'#app', render:h=>h(App), //完成02后 配置store 组件的简写store:store store, }) ``` ### 2.基本使用 用一个组件与vuex的一次完整数据共享作为其他组件实现的`示例`,其他组件使用vuex同理可得 > **实现思路** > > - 实现基础sum++组件 > - 将组件中的需要共享的数据放到index,js(vuex中) > - 将组件中使用的方法,使用`$store`与`index.js`进行数据交互实现数据的共享 前提条件:vue2 准备components组件如下,以及上面配置好的两个(main.js与store(index.js)) ```xml //components组件 作用:实现基础sum++ ``` 1.初始化数据、配置```actions```、配置```mutations```,操作文件```store.js``` ```scss ...... //准备actions对象——响应组件中用户的动作 const actions = { //每一个事件都默认可以接收2个参数 jia(context,value) { // console.log(context, value); //commit向下传递('事件名称',值) context.commit('JIA', value) } } //准备mutations对象——修改state中的数据 const mutations = { JIA(state,value) { // console.log(this); //处理数据,此时共享的store中的sum值也随之改变 state.sum += value } } //准备state对象——保存具体的数据 const state = { sum:0 } ...... ``` ##### 如何使用 > - 组件中读取vuex中的数据:```$store.state.sum``` > - 组件中修改vuex中的数据:```$store.dispatch('action中的方法名',数据)``` 或 ```$store.commit('mutations中的方法名',数据)``` > 备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写```dispatch```,直接编写```commit``` ```xml ......
sum:{{ this.$store.state.sum }}
...... methods: { addSum() { //调用dispatch传递(事件名称,需要传递的值) this.$store.dispatch('jia',this.n); } }, ...... ``` -----现在点击页面上的按钮,简单的数据共享成功了---- ### 3.getter 当`state`中的数据需要经过`加工`后再使用时,可以使用getters加工。 `使用场景`:逻辑复杂且想复用 ##### 如何使用 > - 组件中读取数据:```$store.getters.bigSum``` 例如:

{{$store.getters.bigSum}}

,展示的就时getter中的bigSum值 1.在```store.js```中追加```getters```配置 ```js ...... const getters = { bigSum(state){ return state.sum * 10 } } //创建并暴露store export default new Vuex.Store({ ...... getters }) ``` //在本例中的使用 ```js ...... getters: { bigSum(state) { return state.sum*10 } }, ``` ### 4.mapstate,mapgetter mapState方法:用于帮助我们映射```state```中的数据为计算属性 mapGetters方法:用于帮助我们映射```getters```中的数据为计算属性 通常放在computed里面 将填入的字段`自动映射`为一个`计算属性`;`这是vuex已经封装好的方法直接用在需要的组件中即可(全局挂载过vuex)`,mapgetter同样用法。 在组件中引入mapstate ![image-20230520113752212](https://gitee.com/bigcat_li/typora/raw/master/img/202306042033902.png) 数组写法(常用) ```js mapState(['likes','friends','token','userInfo']) ``` 等价于下面的代码 ```js userInfo(){ return this.$store.state.userInfo }, token(){ return this.$store.state.token }, friends(){ return this.$store.state.friends }, likes(){ return this.$store.state.likes } ``` `当方法名与属性名`不一致`时可使用(对象写法)` ```js mapState({xihuan:'likes',penyou:'friends',miyao:'token',yhxx:'userInfo'}) ``` ### 5.mapaction,mapmutations mapActions方法:用于帮助我们生成与```actions```对话的方法,即:包含```$store.dispatch(xxx)```的函数 mapMutations方法:用于帮助我们生成与```mutations```对话的方法,即:包含```$store.commit(xxx)```的函数 通常放在methods里面 vuex封装的mapmutations样式,借助maputation生成对应的方法,方法会调用`commit`去联系mutation(store中的) ```js increment(value){ this.$store.commit('JIA',value) }, ``` 在组件中引入mapmutations ![image-20230520113752212](https://gitee.com/bigcat_li/typora/raw/master/images/202305301301874.png) 对象写法(常用) ```js Mapmutations({increment:'JIA',decrement:'JIAN'}) ``` 等价于下面的代码 ```js increment(){ this.$store.commit('JIA',this.n) }, decrement(){ this.$store.commit('JIAN',this,n) } ``` `数组写法` ```js Mapmutations(['JIA','JIAN']) ``` ```html ``` **注意** 在组件中使用increment,decrement方法时需要传参 ```html ``` *另外的写法见(拓展5)* ##### 2.mapaction(使用方法同上) 方法会去调用dispatch与vuex中的action联系 ```js incrementOdd(){ this.$store.dispatch('jiaOdd',this.n) }, incrementWait(){ this.$store.dispatch('jiaWait',this.n) } ``` **完整实现**:*图二创建在src->store文件夹->count.js* image-20230520145651524 ![流程图](https://gitee.com/bigcat_li/typora/raw/master/images/202305282228502.png) ​ #### 总结 > - 相同点:mapxxxx的使用方法都一样,对象或者数组样式 > > - 区别:1.mapstate与mapgetter放组件的computed里面,另外两个放methods里面 > > 2.mapaction与mapmutation在使用时,绑定参数时需要传参(原因见上面mapaction,mapmutation详细介绍) 备注:mapActions与mapMutations使用时,若需要传递参数需要:在模板中绑定事件时传递好参数,否则参数是事件对象。 # 拓展 -------------------------------纸上得来终觉浅,绝知此事要躬行。------------------------------- 总结: 在通信中,无论是子组件向父组件传值还是父组件向子组件传值,他们都有一个共同点就是有 **中间介质**,子向父的介质是`自定义事件`,父向子的介质是`props中的属性`。抓准这两点对于父子通信就好理解了 ### 1.父传子:v-bind属性绑定 父组件通过`import + component`写入子组件,然后`v-bind`绑定数据,子组件通过`props`接收 #### 思路 > - 父:自定义属性名 + 数据(要传递)=> v-bind:value="数据" > - 子:props ["父组件上的自定义属性名"] => 进行数据接收 > **实现思路** > > - 父组件中通过 `import` - `components` - `< />` 三部曲 注册子组件 > - 子组件在 `props` 对象中创建一个属性 `prop` > - 父组件在注册的子组件标签中添加 `prop` 属性,即 `prop="value"` > - 父组件可以通过 `v-bind:prop`(`:prop`)实现数据双向绑定 图解记忆法: ![image.png](https://gitee.com/bigcat_li/typora/raw/master/images/202305301301204.webp) ### 2.子传父:v-on事件绑定 子组件`click`设置点击事件,`$emit`设置通道后传参,父组件在`methods`接收 #### 思路 > - 子:this.$emit('自定义事件名称', 数据) 子组件标签上绑定@自定义事件名称 = '回调函数' > - 父:methods: { 回调函数() { //逻辑处理 } } > **实现思路** > > - 子组件中需要以某种方式的方法来触发一个自定义事件(例如点击事件) > - 子组件使用 `this.$emit` 方法,第一个参数为父组件定义的方法名称 `event`,第二个参数为传递的值 > - 在父组件中注册子组件并在子组件标签上绑定对自定义事件的监听(`event="Event"`),`Event(data)` 可以接收传过来的参数 图解记忆法: ![image.png](https://gitee.com/bigcat_li/typora/raw/master/images/202305301302356.webp) ### 3.兄弟组件间的数据共享:EventBus(事件总线) 兄`click`设置点击事件,用`$emit`设置通道传参给中转站,弟通过`$on`接收来自中转站的参数 Snipaste_2023-05-19_18-12-00 #### 思路 > - 通过中转站 let bus = new Vue() > - A:methods :{ 函数{bus.$emit(‘自定义事件名’,数据)} 发送 > - B:created (){bus.$on(‘A发送过来的自定义事件名’,函数)} 进行数据接受 #### 中转站文件 创建 bus.js 做为中转站文件 bus.js 内容为 ![image.png](https://gitee.com/bigcat_li/typora/raw/master/images/202305301302508.webp) #### child1.vue ![image.png](https://gitee.com/bigcat_li/typora/raw/master/images/202305301302273.webp) #### child2.vue ![image.png](https://gitee.com/bigcat_li/typora/raw/master/images/202305301302067.webp) > **总结** > > - 兄组件通过 `click` 设置点击事件 > - 兄组件通过 `$emit` 设置通道传参给中转站 > - 弟组件通过 `$on` 接收来自中转站的参数 涉及到很多组件共享会比较麻烦,庞大的项目多组件共享使用vuex实现(全局事件总线需要多次使用$emit与$on,数据庞大且冗余) 4.计算属性: ![image-20230520103629422](https://gitee.com/bigcat_li/typora/raw/master/images/202305301302223.png) 5.mapmutations的另外写法(只是看看,平时都不这样写) ```js methods:{ increment(){ this.atguiguJia(this.n) } ...mapmutations({atguiguJia:'JIA'}) } ``` ```html ``` 作者:清风夜半 链接:https://juejin.cn/post/6969553033545941022 来源:稀土掘金 转载:作者:ALKAOUA 链接:https://juejin.cn/post/6965062549771386887 来源:稀土掘金 # Cookie的使用? ### cookie、session、localStorage 和 sessionStorage 区别及应用场景? Cookie:存储在用户本地终端上的数据 Session :存储在服务器端的一组数据 localStorage: 没有时间限制的数据存储,第二天,下一周,下一年,只要你不删除仍然存在 sessionStorage: 针对一个[session](https://so.csdn.net/so/search?q=session&spm=1001.2101.3001.7020)的数据存储,当用户关闭浏览器时,数据会被删除 ![image-20230530112625508](https://gitee.com/bigcat_li/typora/raw/master/images/202305301302469.png) #### 应用场景 ### Cookie: - 一般用于判断用户是否登录过网站,以便于下次登录时可以自动登录或记住密码,如果我们删除Cookie中的内容,则下次登录的时候需要重新填写相应的所有有关信息 - 保存上次登录的时间等信息 - 保存上次浏览过的页面 - 保存浏览次数 ### localStorage: - 缓存静态文件内容的JS,CSS - 缓存不常使用的API接口数据 - 存储地理位置 ### SessionStorage: 用于敏感账号的一次性登录,关闭当时页面再次打开页面时需要重新登录 ### cookie、session、token之间的区别? Cookie:存储在用户本地终端上的数据 Session :存储在服务器端的一组数据 token:通常代表一小段字符串,可以存储到cookie里,随请求一起发过去,也可以存在服务器中。 ### http的post、get数据请求的区别? get只能使用url传数据,请求页面都使用的是get;当传输比较复杂的数据的时候使用post。 请求方法写的不一样,post请求中可以带请求体;get请求也可以带请求体,浏览器会自动忽略浏get中带的请求体。 使用post能做的get也能做,用浏览器访问页面的时候都是使用get请求。 **两者区别** - get通过url传递参数,post可以通过url和request body传递参数; - get可以缓存数据,post请求不能缓存; - get只能进行url编码,post传输的编码方式更多; - get请求的参数会保存在浏览器历史中,post不会; - get传参上限为2k,post没有限制; - get只接受ascll字符,post没有限制; **使用场景** GET一般用于获取/查询资源信息,而POST一般用于更新资源信息   1.很多人贪方便,更新资源时用了GET,因为用POST必须要到FORM(表单),这样会麻烦一点。   2.对资源的增,删,改,查操作,其实都可以通过GET/POST完成,不需要用到PUT和DELETE。   3.另外一个是,早期的但是Web MVC框架设计者们并没有有意识地将URL当作抽象的资源来看待和设计。还有一个较为严重的问题是传统的Web MVC框架基本上都只支持GET和POST两种HTTP方法,而不支持PUT和DELETE方法。 **场景使用的原因** 1. get是从服务器上获取数据,post是向服务器传送数据。 2.get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTPpost机制,*将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址*。用户看不到这个过程。 2. 对于get方式,服务器端用*Request.QueryString*获取变量的值,对于post方式,服务器端用*Request.Form*获取提交的数据。 3. get传送的数据量较小,不能大于*2KB*。post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为*80KB*,IIS5中为100KB。 4. get*安全性非常低*,post安全性较高。 ##### GET与POST的安全性 - GET 是将参数写在 URL 中 ? 的后面,并用 & 分隔不同参数;而 POST 是将信息存放在 *Message Body* 中传送,参数不会显示在 *URL* 中。 - GET请求提交的数据有长度限制(HTTP 协定本身没有限制 URL 及正文长度),POST请求没有内容长度限制。 - GET请求返回的内容会*被[浏览器缓存](https://www.zhihu.com/search?q=浏览器缓存&search_source=Entity&hybrid_search_source=Entity&hybrid_search_extra={"sourceType"%3A"answer"%2C"sourceId"%3A1784303721})起来*。而每次提交POST请求,浏览器在你按下F5时会跳出确认框,*不会缓存POST请求返回的内容*。 - GET对数据进行查询,POST主要对数据进行增删改!简单说,GET是只读,POST是写。 # 适配问题?