vue diary 9 (The end)

vue notes 9

21.Vuex

vuex is a state management pattern developed specifically for Vue.js applications. It draws lessons from redux, uses centralized storage to manage the state of all components of the application, and uses corresponding rules to ensure that the state changes in a predictable way.

Vuex features:

  1. It can centrally manage the shared data in vuex, which is easy to develop and maintain later

  2. It can efficiently realize the data sharing between components and improve the development efficiency

  3. The data stored in vuex is responsive, which can keep the data synchronized with the page in real time

  4. Generally, only the data shared between components is necessary to be stored in vuex;

    The private data in the component can still be stored in the data of the component itself

Usage scenario of vuex:

vue It can help us manage shared state, with more concepts and frameworks. This requires a trade-off between short-term and long-term benefits. If you do not intend to develop large single page applications, use Vuex It may be cumbersome and redundant. That's true - if your application is simple enough, you'd better not use it Vuex. A simple store The mode is sufficient. However, if you need to build a medium and large-scale single page application, you are likely to consider how to better manage the state outside the component, Vuex It will be called natural choice.
Introduction method of vuex:
  1. Download and import: npm i vuex;
  2. Vue cli, which is introduced when creating the development environment;

Introduction and use of Vuex:

//The import is in the main.js file
import Vuex from 'vuex'
Vue.use(Vuex);//The use method internally implements the binding of components to the prototype, so the data in Vuex can be accessed through this.$store in all components

const store = new Vuex.Store({//Create vuex warehouse
		state:{msg:'I'm data'}
})
//Mount to vm object
new Vue({
     render(h){return h(app)},
     router,
     store//After mounting, all components can directly obtain global data from the store
}).$mount( "#app")


//Create a separate Vuex file and then import it
//Create a separate store folder and create the index.js file under the folder:
import Vue from 'vue'//Introduce vue
import Vuex from 'vuex'//Import vuex
Vue.use(Vuex)//Enable vuex

//Create a vuex instance to store data and other operations are performed here
const store = new Vuex.store({
			state:{},
			mutations:{},
			actions:{},
			modules:{}
})

export default store;//Export vuex instance

//Introduce in main.js
import store from './store'
//Mount to vm object
new Vue({
	router,
	store,
	render:h=>h(App),
}).$mount('#app')

Properties of vuex:

  • State: state, used to save all data;

    const store=new Vuex.store({
               state:{msg:"I am all shared data"}
    });
    
    //Accessing data in components
    this.$store.state.msg
    
    
  • getter:getter is similar to calculating attributes. It will pass in the state object. You can operate on the data of the state object inside it

    //In the design store file
    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
        	  })
        }
      }
    })
    
    //Use in components
    this.$store.getters.bigMans
    
  • Mutation: the only way to change the state in the store in the component is to submit the mutation for change. You cannot directly use the assignment expression to set the data of the store. Because only when the data is updated through mutation can all components using the data refresh and update the UI.

    //Design
    const store = new Vuex.Store({
      state: {
        count: 1
      },
      mutations: {
    	//The first parameter is passed to state by default
    	increment (state,obj) {
    	  // Change status
    	  state.count=obj.n
    	}
      }
    })
    //Use direct trigger and transfer value in the component (submit load)
    this.$store.commit('increment',{n:100})
    //Passed in as object:
    this.$store.commit({
      type: 'increment',
      n:100
    })
    
    //It should be noted that the data processing method of mutation is synchronous, and asynchronous operation is not allowed
    mutations: {
      increment (state,obj) {
    	//If the fnAsync function is an asynchronous business function, the update will fail
    	fnAsync(() => {
    	  state.count=obj.n
    	})
      }
    }
    
  • Action: if you want to modify the state in the store asynchronously, you can use the action attribute. The action does not directly operate the store to change the state, but is submitted to the mutation.

    //Design
    const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment (state,obj) {
          state.count=obj.n
        }
      },
      actions: {
    	//By default, the first parameter passes an object like store
    	increment (context,obj) {
    		//Suppose fnAsync is an asynchronous business function
    		fnAsync(() => {		context.commit('increment',obj)
    		})      
    	}
      }
    })
    
    //use:
    //1. Direct distribution
    this.$store.dispatch('increment',{n:100})
    //2. Distribution in object form:
    this.$store.dispatch({
      type: 'increment',
      n:100
    })
    
  • Module: business block development. The store is divided into modules for development. Each module has its own state, mutation, action and getter

    //Block design:
    const moduleA = {
      namespaced: true,//Local namespace (make variables in state not conflict with variables with the same name in other modules)	
      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,//local name space 	
       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
      }
    })
    //Create a separate folder to store independent modules, and then summarize each module in the index.js folder
    //Document a:
    let a={
    	namespaced:true,
    	state:{
    		msg:"a of msg"
    	},
    	getters:{},
    	mutations:{},
    	actions:{}
    }
    export default a;
    //Document b
    let b={
    	namespaced:true,
    	state:{
    		msg:"b of msg"
    	},
    	getters:{},
    	mutations:{},
    	actions:{}
    }
    export default b;
    //Import and summarize in index.js
    import a from "./a.js"
    import b from "./b.js"
    const store = new Vuex.Store({
    			modules:{
    			a,
    			b
    			}
    })
    export default store;
    
    
    
    //Use in components:
    this.$store.state.a.msg // ->Status of ModuleA
    this.$store.state.b.msg // ->Status of moduleb
    this.$store.commit("a/change",100)-> moduleA of mutations
    this.$store.commit("b/change",200)-> moduleB of mutations
    this.$store.getters["a/x"]-> moduleA of getters
    this.$store.getters["b/x"]-> moduleB of getters
    this.$store.dispatch("a/change",100)-> moduleA of actions
    this.$store.dispatch("b/change",200)-> moduleB of actions
    

22. Use of UI framework in vue project

Introduction of element framework:

  • Installation: NPM I element UI - S

  • Introduction:

    • Import component library: import elementui from 'element UI'

    • Introduce global css Style: import 'element UI / lib / theme chalk / index. css'

      //The import method of elementUI can be partial import, and only the required components can be imported
      
      import {Button,Input} from "element-ui"
      import 'element-ui/lib/theme-chalk/index.css';
      
      //On demand import / partial import 1
       Vue.component(Button.name,Button)
       Vue.component(Input.name,Input)
      //On demand import / partial import 2
       Vue.use(Button)
       Vue.use(Input)
       
      //Global import
      import ElementUI from 'element-ui'
       Vue.use(ElementUI)
      
      

23. Packaging process

After the code is written in the vue environment, use the webpack packaging tool to package the project as a whole and host it to the back-end server.

  • After the project is hosted on the server, there is no cross domain problem, so you need to delete the configured cross domain scheme before packaging to avoid path problems.

  • Packaging instruction: npm run build;

  • Copy the packaged files to the public folder of the server for hosting.

  • Different Vue router modes will lead to different server hosting processing methods:

    • If the router is in hash mode, the path to access the page will become / # / hash. You need to configure the route in the server's route: router.get("/*",controller.home.all), and call the all method ` ` ` async all() in the controller{

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

      this.ctx.body=data.toString()

      }```Return the managed page to the front end. The web page will read the JS file according to the corresponding path and run it. If the route of the current web page matches the route of the JS code, the corresponding components will be rendered, and the web page will not be refreshed. The node of the server is also required_ In the modules > egg static > config > config.default.js file, configure the prefix attribute to "/" to make the file path read correctly after packaging and hosting.

      • hash mode has the advantages of good compatibility, no need for any setting and development on the back end, and will not send other requests except ajax and resource loading;
      • The disadvantage of hash mode is that it can not accurately capture the routing information. The demand for anchor function will conflict with the current routing mechanism. For the operation requiring redirection, the back end cannot obtain all the contents of the url, resulting in the inability of the back end to obtain the url data.
    • Use history mode: in this mode, every time you change the route, you will send a request to the back end. You also need to configure the "/ *" route in the server's route file, so that the front end will return the same page to the front end every time, run the JS code on this page, and then render the corresponding components through the corresponding route. When the server route has the same name as the internal route of the page JS file, the JS code is returned to the front end instead of the page in the route directly accessing the server—— Solution: avoid duplicate names.

vue development considerations

  • In the development process, the front and back ends are separated, so when you need to request the server for testing, you need to configure across domains.

    • When vue acts as a proxy server:

      • Download the axios module npm i axios, and import axios from 'axios' in main.js

      • Bind axios to the prototype object of vue: Vue.prototype.$axios = axios. Use this.$axios to make ajax requests when calling,

      • axios configuration in main.js: axios.defaults.baseURL="/api". Add '/ api' to the axios request URL. When packaging, just delete this code to avoid setting each request separately; axios.defaults.withCredentials=true, which allows the proxy server to carry cookie s when making requests

      • Agent configuration in vue.config.js file:

        module.exports={
        	lintOnSave:false,//Close strict mode to avoid error reporting due to blank line feed, etc
        	devServer:{
        			port:"8080",//Set the slogan of the requestor
        			host:"localhost",//Set requestor URL
        			proxy:{
        				"/api":{//Keyword, the URL containing / api in the axios request will be proxied
        					target:"http://127.0.0.1 ", / / proxy target URL
        					changeOrigin:true,//Allow change of source URL
        					pathRewrite:{"^/api":""}//When making proxy requests, remove the keyword '/ api' from the web address
        				}
        			}
        		}
        }
        
          port:"8080",//Set the slogan of the requestor
          	host:"localhost",//Set requestor URL
          	proxy:{
          		"/api":{//Keyword, the URL containing / api in the axios request will be proxied
          			target:"http://127.0.0.1 ", / / proxy target URL
          			changeOrigin:true,//Allow change of source URL
          			pathRewrite:{"^/api":""}//When making proxy requests, remove the keyword '/ api' from the web address
          		}
          	}
          }
        

        }

        
        
        

Tags: Javascript Front-end Vue.js

Posted on Mon, 25 Oct 2021 07:46:51 -0400 by petersen313