vue日记9(The end)

vue笔记9

21.Vuex

vuex是一个专为Vue.js应用程序开发的状态管理模式。它借鉴了redux,采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

Vuex的特点:

  1. 能够在vuex中集中管理共享的数据,易于开发和后期维护

  2. 能够高效地实现组件之间的数据共享, 提高开发效率

  3. 存储在 vuex中的数据都是响应式的,能够实时保持数据与页面的同步

  4. 一般情况下,只有组件之间共享的数据,才有必要存储到vuex中;

    对于组件中的私有数据,依旧存储在组件自身的data中即可.

vuex的使用场景:

vue可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。如果不打算开发大型单页应用,使用Vuex可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用Vuex。一个简单的store模式足够所需。但是,如果需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex将会称为自然而然的选择。
vuex的引入方式:
  1. 下载引入:npm i vuex;
  2. vue-cli,创建开发环境时引入;

Vuex的引入使用:

//导入 在main.js文件中
import Vuex from 'vuex'
Vue.use(Vuex);//use方法内部实现了将组件绑定到原型上,所以在所有组件中才能通过this.$store访问到Vuex中的数据

const store = new Vuex.Store({//创建vuex仓库
		state:{msg:'我是数据'}
})
//挂载到vm对象
new Vue({
     render(h){return h(app)},
     router,
     store//挂载以后  所有的组件就可以直接从store中获取全局数据
}).$mount( "#app")


//创建单独的Vuex文件,再引入的方式
//创建单独的store文件夹,在文件夹下创建index.js文件:
import Vue from 'vue'//引入vue
import Vuex from 'vuex'//导入vuex
Vue.use(Vuex)//启用vuex

//创建vuex实例  存放数据等操作在这里进行
const store = new Vuex.store({
			state:{},
			mutations:{},
			actions:{},
			modules:{}
})

export default store;//导出vuex实例

//在main.js中引入
import store from './store'
//挂载到vm对象上
new Vue({
	router,
	store,
	render:h=>h(App),
}).$mount('#app')

vuex的属性:
  • state:state状态,用来保存所有数据;

    const store=new Vuex.store({
               state:{msg:"我就是所有共享的数据"}
    });
    
    //在组件中访问数据
    this.$store.state.msg
    
    
  • getter:getter类似于计算属性,会传入state对象,可以在其内部对state对象的数据进行操作

    //设计  store文件中
    const store = new Vuex.Store({
      state: {
        arr: [
          { id: 1, text: '...', birth: "1997-02-03" },
          { id: 2, text: '...', birth:  "2019-10-03" }
        ]
      },
      getters: {
         bigMans(state) {
          return state.arr.filter((man)=>{
        	  let manY=new Date(man.birth).getFullYear()
        	  let nowY=new Date().getFullYear()
        	  return (nowY-manY)>=18
        	  })
        }
      }
    })
    
    //在组件中使用
    this.$store.getters.bigMans
    
  • mutation:组件中更改store中的状态的唯一方法时提交mutation进行更改,不能直接使用赋值表达式设置store的数据。因为只有当通过mutation来更新数据,才会使所有使用该数据的组件刷新,更新UI。

    //设计
    const store = new Vuex.Store({
      state: {
        count: 1
      },
      mutations: {
    	//默认传第一个参数传state
    	increment (state,obj) {
    	  // 变更状态
    	  state.count=obj.n
    	}
      }
    })
    //在组件中使用  直接触发并传值(提交载荷)
    this.$store.commit('increment',{n:100})
    //以对象的形式传入:
    this.$store.commit({
      type: 'increment',
      n:100
    })
    
    //需要注意的是,mutation处理数据的方式是同步的,不能进行异步操作
    mutations: {
      increment (state,obj) {
    	//如果fnAsync函数是一个异步业务函数,就会导致更新失败
    	fnAsync(() => {
    	  state.count=obj.n
    	})
      }
    }
    
  • action:如果要进行异步修改store中状态的操作,可以使用action属性。action并不是直接操作store更改状态,而是提交到mutation。

    //设计
    const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment (state,obj) {
          state.count=obj.n
        }
      },
      actions: {
    	//默认第一个参数传一个跟store一样的对象
    	increment (context,obj) {
    		//假设fnAsync是一个异步业务函数
    		fnAsync(() => {		context.commit('increment',obj)
    		})      
    	}
      }
    })
    
    //使用:
    //1.直接分发
    this.$store.dispatch('increment',{n:100})
    //2.以对象形式分发:
    this.$store.dispatch({
      type: 'increment',
      n:100
    })
    
  • module:业务分块开发。将store分割成模块(module)进行开发,每个模块拥有自己的state、mutation、action、getter

    //分块设计:
    const moduleA = {
      namespaced: true,//局部命名空间(让state的中变量与其他模块中的同名变量不冲突)	
      state: { msg:1 },
      mutations: { change(state,n){state.msg=n} },
      actions: { change(context,n){context.commit("change",n)} },
      getters: { x(state){return state.msg} }
    }
    
    const moduleB = {
       namespaced: true,//局部命名空间	
       state: {  msg:1 },
       mutations: { change(state,n){state.msg=n} },
       actions: { change(context,n){context.commit("change",n)} },
       getters: { x(state){return state.msg} }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    //建立单独的文件夹存放独立的模块,然后在index.js文件夹中,将各模块汇总
    //文件a:
    let a={
    	namespaced:true,
    	state:{
    		msg:"a的msg"
    	},
    	getters:{},
    	mutations:{},
    	actions:{}
    }
    export default a;
    //文件b
    let b={
    	namespaced:true,
    	state:{
    		msg:"b的msg"
    	},
    	getters:{},
    	mutations:{},
    	actions:{}
    }
    export default b;
    //在index.js中引入,汇总
    import a from "./a.js"
    import b from "./b.js"
    const store = new Vuex.Store({
    			modules:{
    			a,
    			b
    			}
    })
    export default store;
    
    
    
    //组件中的使用:
    this.$store.state.a.msg // -> moduleA 的状态
    this.$store.state.b.msg // -> moduleB 的状态
    this.$store.commit("a/change",100)-> moduleA 的mutations
    this.$store.commit("b/change",200)-> moduleB 的mutations
    this.$store.getters["a/x"]-> moduleA 的getters
    this.$store.getters["b/x"]-> moduleB 的getters
    this.$store.dispatch("a/change",100)-> moduleA 的actions
    this.$store.dispatch("b/change",200)-> moduleB 的actions
    

22.UI框架在vue项目中的使用

​ element框架的引入:

  • ​ 安装:npm i element-ui -S

  • ​ 引入:

    • 引入组件库:import ElementUI from 'element-ui'

    • 引入全局css样式:import 'element-ui/lib/theme-chalk/index.css'

      //elementUI的引入方式可以局部导入,只引入需要的组件
      
      import {Button,Input} from "element-ui"
      import 'element-ui/lib/theme-chalk/index.css';
      
      //按需导入/局部导入1.
       Vue.component(Button.name,Button)
       Vue.component(Input.name,Input)
      //按需导入/局部导入2.
       Vue.use(Button)
       Vue.use(Input)
       
      //全局引入
      import ElementUI from 'element-ui'
       Vue.use(ElementUI)
      
      

23.打包流程

在vue环境中将代码编写完成后,使用webpack打包工具,将项目整体打包,托管到后端服务器。

  • 项目托管到服务器后就不存在跨域问题了,所以需要在打包前将配置的跨域方案删除,避免出现路径问题。

  • 打包指令:npm run build;

  • 将打包后生成的文件复制到服务器的public文件夹下进行托管。

  • vue-router的模式不同会导致服务器托管处理方式不同:

    • 如果router是在hash模式下,访问页面的路径会变成/#/hash,需要在服务器的路由中配置路由:router.get("/*",controller.home.all),调用controller中的all方法```async all(){

      let data=fs.readFileSync(__dirname+"/…/public/index.html")

      this.ctx.body=data.toString()

      }```给前端返回托管的页面。网页会根据对应的路径读取JS文件然后运行,当前网页的路由匹配到JS代码的路由,则会渲染相应的组件,网页并不会刷新。还需要在服务器的node_modules>egg-static>config>config.default.js文件中,将prefix属性配置为"/",让打包托管后的文件路径读取正确。

      • hash模式的优点是兼容性好,不需要在后端进行任何设置和开发,并且不会发送除ajax和资源加载之外的其他请求;
      • hash模式的缺点是无法准确捕获路由的信息,对于需要锚点功能的需求会与当前路由机制发生冲突,对于需要重定向的操作,后端无法获取url全部内容,导致后台无法得到url数据。
    • 使用history模式:这种模式每次更改路由都会向后端发送请求,也需要在服务器的路由文件中配置"/*"路由,使前端每次请求时,都给前端返回相同的页面,由该页面运行JS代码,再通过对应的路由渲染相应的组件。当服务器路由与页面JS文件内部路由重名时,在直接访问服务器的路由,给前端返回JS代码,而不是页面。——解决:避免重名。

在这里插入图片描述

vue开发注意事项

  • 在开发的过程中,前后端是分开的,所以进行测试时需要请求服务器时,需要进行跨域的配置。

    • vue做代理服务器时:

      • 下载axios模块npm i axios,在main.js中引入import axios from 'axios'

      • 将axios绑定在vue的原型对象上:Vue.prototype.$axios = axios,在调用时使用this.$axios来进行ajax请求,

      • main.js中的axios配置:axios.defaults.baseURL="/api",给axios请求网址上加上’/api’,打包时只需删掉这一句代码,避免单独给每个请求设置;axios.defaults.withCredentials=true,允许代理服务器进行请求时携带cookie

      • vue.config.js文件中的代理配置:

        module.exports={
        	lintOnSave:false,//关闭严格模式,避免因空格换行等导致报错
        	devServer:{
        			port:"8080",//设定请求方端口号
        			host:"localhost",//设定请求方网址
        			proxy:{
        				"/api":{//关键词,axios请求中含/api的网址会被代理
        					target:"http://127.0.0.1",//代理目标网址
        					changeOrigin:true,//允许改变来源网址
        					pathRewrite:{"^/api":""}//进行代理请求时,将网址中的关键词'/api'去掉
        				}
        			}
        		}
        }
        
          port:"8080",//设定请求方端口号
          	host:"localhost",//设定请求方网址
          	proxy:{
          		"/api":{//关键词,axios请求中含/api的网址会被代理
          			target:"http://127.0.0.1",//代理目标网址
          			changeOrigin:true,//允许改变来源网址
          			pathRewrite:{"^/api":""}//进行代理请求时,将网址中的关键词'/api'去掉
          		}
          	}
          }
        

        }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值