Scaffolding file structure
├── node_modules ├── public │ ├── favicon.ico: tab icon │ └── index.html: main page ├── src │ ├── assets: store static resources │ │ └── logo.png │ │── component: storage component │ │ └── HelloWorld.vue │ │── App.vue: Summarize all components │ │── main.js: entry file ├── .gitignore: configuration ignored by git version control ├── babel.config.js: babel configuration file ├── package.json: application package configuration file ├── README.md: application description file ├── package-lock.json: package version control file
About different versions of Vue
-
The difference between vue.js and vue.runtime.xxx.js:
-
vue.js is a full version of Vue, including: core functions + template parser.
-
vue.runtime.xxx.js is the running version of Vue, which only includes: core functions; no template parser.
-
-
Because vue.runtime.xxx.js does not have a template parser, the template configuration item cannot be used, and the createElement function received by the render function needs to be used to specify the specific content.
vue.config.js configuration file
-
Use vue inspect > output.js to view the default configuration of Vue scaffolding.
-
Scaffolding can be customized using vue.config.js. For details, see: Vue CLI
ref attribute
-
Used to register reference information for elements or subcomponents (replacement of id)
-
What the application gets on the html tag is the real DOM element, and what the application gets on the component tag is the component instance object (vc)
-
How to use:
-
Mark:
<h1 ref="xxx">.....</h1>
or<School ref="xxx"></School>
-
Obtain:
this.$refs.xxx
-
props configuration item
-
Function: Let the component receive data from the outside
-
Pass data:
<Demo name="xxx"/>
-
Receive data:
-
The first way (receive only):
props:['name']
-
Second way (restricted type):
props:{name:String}
-
Third way (restrict type, restrict necessity, specify default value):
props:{ name:{ type: String, //Type required:true, //necessity default:'Lao Wang' //default value } }
Remarks: props are read-only. The bottom layer of Vue will monitor your modification of props. If you modify props, a warning will be issued. If the business needs really need to be modified, please copy the content of props to a copy of data, and then modify it The data in data.
-
mixin
-
Function: The configuration shared by multiple components can be extracted into a mix-in object
-
How to use:
The first step is to define the mixin:
{ data(){....}, methods:{....} .... }
The second step uses mixins:
Global mixin:
Vue.mixin(xxx)
Local mixin:mixins:['xxx']
plug-in
-
Function: used to enhance Vue
-
Essence: An object containing the install method, the first parameter of install is Vue, and the second and subsequent parameters are the data passed by the plug-in user.
-
Define the plugin:
object.install = function (Vue, options) { // 1. Add a global filter View.filter(....) // 2. Add global directives Directive.view(....) // 3. Configure global mixin (combination) Vue. mixin(....) // 4. Add instance method Vue.prototype.$myMethod = function () {...} Vue.prototype.$myProperty = xxxx }
-
Use the plugin:
Vue.use()
scoped style
-
Function: Let the style take effect locally to prevent conflicts.
-
Writing:
<style scoped>
Summarize the TodoList case
-
Component coding process:
(1). Split static components: components should be split according to function points, and the naming should not conflict with html elements.
(2). Realize dynamic components: consider the storage location of the data, whether the data is used by a component or some components:
1). A component is in use: just put it in the component itself.
2). Some components are in use: put them on their common parent component (state promotion).
(3). Realize interaction: start from binding events.
-
props apply to:
(1). Parent component ==> child component communication
(2). Child component ==> parent component communication (requiring the parent to give the child a function first)
-
When using v-model, remember: the value bound by v-model cannot be the value passed by props, because props cannot be modified!
-
If the value passed by props is an object type, Vue will not report an error when modifying the properties in the object, but this is not recommended.
webStorage
-
The storage content size generally supports about 5MB (different browsers may vary)
-
The browser implements the local storage mechanism through the Window.sessionStorage and Window.localStorage properties.
-
Related APIs:
-
xxxxxStorage.setItem('key', 'value');
This method accepts a key and a value as parameters, and will add the key-value pair to the storage, and if the key exists, update its corresponding value. -
xxxxxStorage.getItem('person');
This method accepts a key name as a parameter and returns the value corresponding to the key name.
-
xxxxxStorage.removeItem('key');
This method accepts a key name as a parameter and deletes the key name from the storage.
-
xxxxxStorage.clear()
This method clears all data in storage.
-
-
Remark:
-
The content stored in SessionStorage will disappear when the browser window is closed.
-
The content stored in LocalStorage needs to be manually cleared before it disappears.
-
xxxxxStorage.getItem(xxx)
If the value corresponding to xxx cannot be obtained, the return value of getItem is null. -
JSON.parse(null)
The result is still null.
-
Component custom events
-
A way of communication between components, suitable for: child components ===> parent components
-
Usage scenario: A is the parent component, B is the child component, and B wants to pass data to A, then it needs to bind a custom event to B in A (event callback is in A).
-
Bind custom events:
-
The first way, in the parent component:
<Demo @jiyun="test"/>
or<Demo v-on:jiyun="test"/>
-
The second way, in the parent component:
<Demo ref="demo"/> ...... mounted(){ this.$refs.xxx.$on('jiyun',this.test) }
-
If you want a custom event to be triggered only once, you can use
once
modifiers, or$once
methods.
-
-
Trigger a custom event:
this.$emit('jiyun',数据)
-
Unbind custom events
this.$off('jiyun')
-
Components can also be bound to native DOM events, requiring the use of
native
modifiers. -
Note: When
this.$refs.xxx.$on('jiyun',回调)
binding a custom event, the callback must either be configured in methods or use an arrow function, otherwise this will cause problems!
Global Event Bus (GlobalEventBus)
-
A way of communication between components, suitable for any communication between components.
-
Install the global event bus:
new View({ ...... beforeCreate() { Vue.prototype.$bus = this //Install the global event bus, $bus is the vm of the current application }, ...... })
-
Using the event bus:
-
Receive data: If component A wants to receive data, then bind a custom event to $bus in component A, and the callback of the event stays in component A itself.
methods(){ demo(data){......} } ...... mounted() { this.$bus.$on('xxxx',this.demo) }
-
provide data:
this.$bus.$emit('xxxx',数据)
-
-
It is best to use $off in the beforeDestroy hook to unbind the events used by the current component.
Message Subscription and Publishing (pubsub)
-
A way of communication between components, suitable for any communication between components.
-
Steps for usage:
-
Install pubsub:
npm i pubsub-js
-
import:
import pubsub from 'pubsub-js'
-
Receive data: If A component wants to receive data, it subscribes to the message in A component, and the subscribed callback stays in A component itself.
methods(){ demo(data){......} } ...... mounted() { this.pid = pubsub.subscribe('xxx',this.demo) //Subscribe to news }
-
provide data:
pubsub.publish('xxx',数据)
-
It is best
PubSub.unsubscribe(pid)
to .
-
nextTick
-
grammar:
this.$nextTick(回调函数)
-
Function: Execute the specified callback after the next DOM update.
-
When to use: When the data is changed and some operations are to be performed based on the updated new DOM, it must be executed in the callback function specified by nextTick.
Transition and animation of Vue package
-
Function: When inserting, updating or removing DOM elements, add a style class name to the element at the appropriate time.
-
Graphic:
-
Writing:
-
Ready to style:
-
Elements come in styles:
-
v-enter: the starting point of entry
-
v-enter-active: in the process of entering
-
v-enter-to: the end point of entry
-
-
Styles for element leaving:
-
v-leave: the starting point of leaving
-
v-leave-active: in the process of leaving
-
v-leave-to: the end point of leaving
-
-
-
Use
<transition>
the element to be wrapped and configure the name attribute:<transition name="hello"> <h1 v-show="isShow">Hello! </h1> </transition>
-
Remarks: If there are multiple elements that need to be transitioned, you need to use:
<transition-group>
, and each element must specifykey
a value.
-
Vue scaffolding configuration proxy
method one
Add the following configuration in vue.config.js:
devServer:{ proxy:"http://localhost:5000" }
illustrate:
-
Advantages: The configuration is simple, and it can be sent directly to the front end (8080) when requesting resources.
-
Disadvantages: Multiple proxies cannot be configured, and it is not possible to flexibly control whether requests go through proxies.
-
Working method: If the proxy is configured as above, when a resource that does not exist in the front-end is requested, the request will be forwarded to the server (matching front-end resources first)
Method Two
Write vue.config.js to configure specific proxy rules:
module.exports = { devServer: { proxy: { '/api1': {// Match all request paths starting with '/api1' target: 'http://localhost:5000', // base path of proxy target changeOrigin: true, pathRewrite: {'^/api1': ''} }, '/api2': {// Match all request paths starting with '/api2' target: 'http://localhost:5001', // base path of proxy target changeOrigin: true, pathRewrite: {'^/api2': ''} } } } } /* When changeOrigin is set to true, the host in the request header received by the server is: localhost:5000 When changeOrigin is set to false, the host in the request header received by the server is: localhost:8080 changeOrigin default value is true */
illustrate:
-
Advantages: Multiple proxies can be configured, and it is possible to flexibly control whether requests go through proxies.
-
Disadvantages: The configuration is slightly cumbersome, and a prefix must be added when requesting resources.
slot
-
Function: Allow the parent component to insert the html structure to the specified position of the child component, and it is also a way of communication between components, which is suitable for parent components ===> child components .
-
Categories: default slots, named slots, scoped slots
-
How to use:
-
Default slot:
In the parent component: <Category> <div>html structure 1</div> </Category> In the subcomponent: <template> <div> <!-- Define slots --> <slot>Slot default content...</slot> </div> </template>
-
Named slots:
In the parent component: <Category> <template slot="center"> <div>html structure 1</div> </template> <template v-slot:footer> <div>html structure 2</div> </template> </Category> In the subcomponent: <template> <div> <!-- Define slots --> <slot name="center">Slot default content...</slot> <slot name="footer">Slot default content...</slot> </div> </template>
-
Scoped slots:
-
Understanding: The data is in the component itself, but the structure generated according to the data needs to be determined by the user of the component. (The games data is in the Category component, but the structure traversed by using the data is determined by the App component)
-
Specific encoding:
In the parent component: <Category> <template scope="scopeData"> <!-- The ul list is generated --> <ul> <li v-for="g in scopeData.games" :key="g">{ {g}}</li> </ul> </template> </Category> <Category> <template slot-scope="scopeData"> <!-- The h4 title is generated --> <h4 v-for="g in scopeData.games" :key="g">{ {g}}</h4> </template> </Category> In the subcomponent: <template> <div> <slot :games="games"></slot> </div> </template> <script> export default { name:'Category', props:['title'], //The data is in the child component itself data() { return { games:['Red Alert','Cross Fire','Audition','Super Mario'] } }, } </script>
-
-
Vuex
1. Concept
A Vue plug-in that implements centralized state (data) management in Vue, and performs centralized management (read/write) on the shared state of multiple components in the Vue application. It is also a way of communication between components, and it is suitable for any Communication between components.
2. When to use it?
When multiple components need to share data
3. Build the vuex environment
-
Create a file:
src/store/index.js
//Introduce the Vue core library import View from 'view' //Introduce Vuex import Vuex from 'vuex' //Apply the Vuex plugin Vue.use(Vuex) //Prepare the actions object - respond to the user's actions in the component const actions = {} //Prepare the mutations object - modify the data in the state const mutations = {} //Prepare the state object - save specific data const state = {} //Create and expose store export default new Vuex.Store({ actions, mutations, state })
-
Pass in configuration items
main.js
when creating a vm instore
...... //Introduce store import store from './store' ...... //create vm new View({ the:'#app', render: h => h(App), store })
4. Basic use
-
Initialize data, configure
actions
, configuremutations
, manipulate filesstore.js
//Introduce the Vue core library import View from 'view' //Introduce Vuex import Vuex from 'vuex' //reference Vuex Vue.use(Vuex) const actions = { //Response to the action added in the component jia(context,value){ // console.log('jia in actions has been called', miniStore, value) context.commit('JIA',value) }, } const mutations = { //Execute plus JIA(state,value){ // console.log('JIA in mutations is called', state, value) state.sum += value } } //Initialization data const state = { sum:0 } //Create and expose store export default new Vuex.Store({ actions, mutations, state, })
-
Read the data in vuex in the component:
$store.state.sum
-
Modify the data in vuex in the component:
$store.dispatch('action中的方法名',数据)
or$store.commit('mutations中的方法名',数据)
Remarks: If there is no network request or other business logic, actions can also be skipped in the component, that is, do not write
dispatch
, write directlycommit
5. Use of getters
-
Concept: When the data in the state needs to be processed before use, getters can be used for processing.
-
store.js
Appendgetters
configuration in...... const getters = { bigSum(state){ return state.sum * 10 } } //Create and expose store export default new Vuex.Store({ ...... getters })
-
Read data in the component:
$store.getters.bigSum
6. The use of four map methods
-
mapState method: used to help us map
state
the data into computed propertiescomputed: { //Generate calculated properties with mapState: sum, school, subject (object writing) ...mapState({sum:'sum',school:'school',subject:'subject'}), //Generate calculated properties with mapState: sum, school, subject (array writing) ...mapState(['sum','school','subject']), },
-
mapGetters method: used to help us map
getters
the data into computed propertiescomputed: { //Generate calculated properties with mapGetters: bigSum (object writing) ...mapGetters({bigSum:'bigSum'}), //Generate calculated properties with mapGetters: bigSum (array writing) ...mapGetters(['bigSum']) },
-
mapActions method: the method used to help us generate and
actions
dialogue, namely: the included$store.dispatch(xxx)
functionmethods:{ // Generated by mapActions: incrementOdd, incrementWait (object form) ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}) // Generated by mapActions: incrementOdd, incrementWait (array form) ...mapActions(['jiaOdd','jiaWait']) }
-
mapMutations method: the method used to help us generate and
mutations
dialogue, namely:$store.commit(xxx)
the function containedmethods:{ // Generated by mapActions: increment, decrement (object form) ...mapMutations({increment:'JIA',decrement:'JIAN'}), // Generated by mapMutations: JIA, JIAN (object form) ...mapMutations(['JIA','JIAN']), }
Remarks: When using mapActions and mapMutations, if you need to pass parameters, you need to pass the parameters when binding the event in the template, otherwise the parameters are event objects.
7. Modularity + Namespace
-
Purpose: Make the code easier to maintain, and make the classification of various data more clear.
-
Revise
store.js
const countAbout = { namespaced:true,//Open the namespace state:{x:1}, mutations: { ... }, actions: { ... }, getters: { bigSum(state){ return state.sum * 10 } } } const personAbout = { namespaced:true,//Open the namespace state:{ ... }, mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { countAbout, personAbout } })
-
After the namespace is enabled, the state data is read in the component:
//Method 1: read directly by yourself this.$store.state.personAbout.list //Method 2: Read with mapState: ...mapState('countAbout',['sum','school','subject']),
-
After the namespace is enabled, getters data is read in the component:
//Method 1: read directly by yourself this.$store.getters['personAbout/firstPersonName'] //Method 2: Read with mapGetters: ...mapGetters('countAbout',['bigSum'])
-
After the namespace is enabled, dispatch is called in the component
//Method 1: Dispatch directly by yourself this.$store.dispatch('personAbout/addPersonWang',person) //Method 2: With mapActions: ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
-
After the namespace is enabled, commit is called in the component
//Method 1: commit directly by yourself this.$store.commit('personAbout/ADD_PERSON',person) //Method 2: With mapMutations: ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
routing
-
Understanding: A route is a set of mapping relationships (key-value), and multiple routes need to be managed by a router.
-
Front-end routing: the key is the path, and the value is the component.
1. Basic use
-
Install vue-router, command:
npm i vue-router
-
Apply plugin:
Vue.use(VueRouter)
-
Write router configuration items:
//Introduce VueRouter import VueRouter from 'vue-router' //Import Luyou component import About from '../components/About' import Home from '../components/Home' //Create a router instance object to manage a group of routing rules const router = new VueRouter({ routes:[ { path:'/about', component:About }, { path:'/home', component:Home } ] }) //expose router export default router
-
Implement switching (active-class can configure highlighting style)
<router-link active-class="active" to="/about">About</router-link>
-
target placements
<router-view></router-view>
2. A few points for attention
-
Routing components are usually stored in
pages
folders, and general components are usually stored incomponents
folders. -
By switching, the "hidden" routing components are destroyed by default, and then mounted when needed.
-
Each component has its own
$route
properties, which store its own routing information. -
The entire application has only one router, which can
$router
be obtained through the properties of the component.
3. Multi-level routing (multi-level routing)
-
To configure routing rules, use the children configuration item:
routes:[ { path:'/about', component:About, }, { path:'/home', component:Home, children:[ //Configure sub-level routing through children { path:'news', //Do not write here: /news component:News }, { path:'message',//must not write here: /message component:Message } ] } ]
-
Jump (to write the full path):
<router-link to="/home/news">News</router-link>
4. The query parameter of the route
-
pass parameters
<!-- Jump and carry the query parameter, the string writing of to --> <router-link :to="/home/message/detail?id=666&title=Hello">Jump</router-link> <!-- Jump and carry the query parameter, the object writing method of to --> <router-link :to="{ path:'/home/message/detail', query:{ id:666, title:'Hello' } }" >Jump</router-link>
-
Receive parameters:
$route.query.id $route.query.title
5. Naming Routes
-
Function: It can simplify the routing jump.
-
how to use
-
Give the route a name:
{ path:'/demo', component:Demo, children:[ { path:'test', component:Test, children:[ { name:'hello' //Name the route path:'welcome', component:Hello, } ] } ] }
-
Simplified jump:
<!--Before simplification, you need to write the complete path --> <router-link to="/demo/test/welcome">跳转</router-link> <!--After simplification, jump directly through the name--> <router-link :to="{name:'hello'}">跳转</router-link> <!-- Simplified writing with passing parameters --> <router-link :to="{ name:'hello', query:{ id:666, title:'Hello' } }" >Jump</router-link>
-
6. The params parameter of the route
-
Configure routing, declare to receive params parameters
{ path:'/home', component:Home, children:[ { path:'news', component:News }, { component:Message, children:[ { name:'xiangqing', path:'detail/:id/:title', //use placeholder declaration to receive params parameter component:Detail } ] } ] }
-
pass parameters
<!-- Jump and carry the params parameter, the string writing method of to --> <router-link :to="/home/message/detail/666/Hello">Jump</router-link> <!-- Jump and carry params parameters, the object writing method of to --> <router-link :to="{ name:'xiangqing', params:{ id:666, title:'Hello' } }" >Jump</router-link>
Special attention: When the route carries params parameters, if you use the object writing method of to, you cannot use the path configuration item, you must use the name configuration!
-
Receive parameters:
$route.params.id $route.params.title
7. Routing props configuration
Role: Make it easier for routing components to receive parameters
{ name:'xiangqing', path:'detail/:id', component:Detail, //The first way of writing: the props value is an object, and all key-value combinations in the object will eventually be passed to the Detail component through props // props:{a:900} //The second way of writing: the props value is a Boolean value, and the Boolean value is true, then pass all the params parameters received by the route to the Detail component through props // props:true //The third way of writing: the props value is a function, and each set of key-values in the object returned by the function will be passed to the Detail component through props props(route){ return { id:route.query.id, title:route.query.title } } }
8. <router-link>
The replace attribute
-
Role: control the mode of operating browser history when routing jumps
-
There are two ways to write the history of the browser:
push
and respectivelyreplace
,push
which is to append the history record, andreplace
is to replace the current record. When the route jumps, the default ispush
-
How to turn on
replace
the mode:<router-link replace .......>News</router-link>
9. Programmatic Routing Navigation
-
<router-link>
Function: Make routing jumps more flexible without the help of routing jumps -
Specific encoding:
//Two APIs of $router this.$router.push({ name:'xiangqing', params:{ id:xxx, title:xxx } }) this.$router.replace({ name:'xiangqing', params:{ id:xxx, title:xxx } }) this.$router.forward() //forward this.$router.back() //Back this.$router.go() // can go forward or back
10. Cache Routing Components
-
Function: keep the routing components that are not displayed mounted and not destroyed.
-
Specific encoding:
<keep-alive include="News"> <router-view></router-view> </keep-alive>
11. Two new lifecycle hooks
-
Function: Two hooks unique to routing components, used to capture the activation status of routing components.
-
specific name:
-
activated
Fired when the routing component is activated. -
deactivated
Triggered when the routing component is deactivated.
-
12. Route Guard
-
Role: to control the authority of the route
-
Category: global guard, exclusive guard, component guard
-
Global Guard:
//Global pre-guard: executed at initialization, executed before each routing switch router.beforeEach((to,from,next)=>{ console.log('beforeEach',to,from) if(to.meta.isAuth){ //Determine whether the current route needs permission control if(localStorage.getItem('school') === 'jiyun'){ //Specific rules for permission control next() // release }else{ alert('Temporarily no permission to view') // next({name:'guanyu'}) } }else{ next() // release } }) //Global post guard: execute at initialization, execute after each routing switch router.afterEach((to,from)=>{ console.log('afterEach',to,from) if(to.meta.title){ document.title = to.meta.title //Modify the title of the web page }else{ document.title = 'vue_test' } })
-
Exclusive Guard:
beforeEnter(to,from,next){ console.log('beforeEnter',to,from) if(to.meta.isAuth){ //Determine whether the current route needs permission control if(localStorage.getItem('school') === 'jiyun'){ next() }else{ alert('Temporarily no permission to view') // next({name:'guanyu'}) } }else{ next() } }
-
Guards inside the component:
//Enter the guard: through the routing rules, it is called when entering the component beforeRouteEnter (to, from, next) { }, //Leave the guard: Called when leaving the component through routing rules beforeRouteLeave (to, from, next) { }
13. Two working modes of the router
-
For a url, what is the hash value? —— # and the content after it is the hash value.
-
The hash value will not be included in the HTTP request, that is: the hash value will not be brought to the server.
-
hash mode:
-
There is always a # sign in the address, which is not beautiful.
-
If the address is shared through a third-party mobile app in the future, if the app verification is strict, the address will be marked as illegal.
-
Compatibility is better.
-
-
history mode:
-
The address is clean and beautiful.
-
Compatibility is slightly worse than hash mode.
-
When the application is deployed and launched, it needs the support of the back-end personnel to solve the problem of refreshing the page server 404.
-