Vue – A progressive JavaScript framework
introduce
- Vue Chinese website
- vue github
- Vue.js is a set of progressive JavaScript frameworks for building user interfaces (UIs)
The difference between libraries and frameworks
- What’s the difference between a front-end framework and a library?
Library
A library is essentially a collection of functions. Each time you call a function, you implement a particular function, and then you call it
control
Give to user
- Rep: the jQuery
- The core of jQuery library: DOM manipulation, namely: encapsulate DOM manipulation, simplify DOM manipulation
Framework
Framework, is a complete set of solutions, the use of framework, you need to put your code in the framework of the appropriate place, the framework will call your code at the appropriate time
- The framework defines its own way of programming and is a complete solution
- When we use a framework, the framework controls everything and we just write code according to the rules
The main difference
- You call Library, Framework calls you
-
Core point: Who takes the lead (Inversion of control)
- Within the framework, it is the framework that controls the whole process
- With libraries, it’s up to the developer to decide how to invoke methods provided in the library (helper)
- The Hollywood principle: Don’t call us, we’ll call you.
- Frames are very intrusive (from start to finish)
The introduction of MVVM
- MVVM, a better UI pattern solution
- From Script to Code Blocks, Code Behind to MVC, MVP, MVVM-popular science
MVC
- M: Model Data Model (specialized for manipulating data, CRUD of data)
- V: View View (for the front end, pages)
- C: Controller Controller (a bridge between view and data model, used to process business logic)
An MVVM
- MVVM ===> M / V / VM
- M: Model Data model
- V: view View
- VM: ViewModel
Advantages compared to
- The MVC pattern, which divides the application into three parts, enables separation of responsibilities
- In the front end often through THE JS code to carry out some logical operations, and finally put the results of these logical operations in the page. That is, you need to manipulate the DOM frequently
-
MVVM enables automatic bidirectional data synchronization through bidirectional data binding
- V (modify data) -> M
- M (modify data) -> V
- Data is the core
- Vue, an MVVM-style framework, does not recommend manual manipulation of the DOM by developers
The Vue MVVM
While not entirely following the MVVM model, the design of Vue was undoubtedly inspired by it. Therefore, the variable name VM (short for ViewModel) is often used to represent Vue instances in documentation
To learn Vue, you need to change your mind
- Don’t think about manipulating DOM, think about manipulating data!!
Start – Hello Vue
- Installation:
npm i -S vue
<! <div id="app">{{MSG}}</div> <! -- introduction of vue. Js - > < script SRC = "vue. Js" > < / script > <! <script> var vm = new vue ({// el: provide an existing DOM element on the page as the mount target of the vue instance el: Data: {MSG: 'Hello Vue'}}) </script>Copy the code
Vue instance
- Note 1: Declare data in data before using it
- Note 2: Yes
vm.$data
Access all properties in data, orvm.msg
Var vm = new Vue({data: {MSG: 'hello... ' } }) vm.$data.msg === vm.msg // trueCopy the code
Data binding
- The most common way:
Mustache
, that is,{{}}
grammar - Explanation:
{{}}
Slave data objectdata
To obtain data from - Note: The value of the property of the data object has changed, and the content of the interpolation will be updated
- Description:
{{}}
Can only appear in JavaScript expressions and cannot parse JS statements - Note that Mustache syntax does not work on attributes of HTML elements
<h1>Hello, {{ msg }}.</h1> <p>{{ 1 + 2 }}</p> <p>{{ isOk ? 'yes': 'no' }}</p> <! -!!!!!! Wrong demonstration!! --> <h1 title="{{ err }}"></h1>Copy the code
Vue Two way Data Binding
-
Bidirectional data binding: Binding DOM and Vue instance data together to interact with each other
- Changes to the data cause changes to the DOM
- DOM changes also cause data changes
-
How it works: Get and set methods in Object.defineProperty
-
getter
andsetter
: the visitor - Role: Specify
Read or set
Object property value
-
- Vue – Deep responsive principle
- MDN – Object.defineProperty()
*/ var obj = {} object.defineProperty (obj, 'MSG ', Set: function (newVal, oldVal) {}, // set obj. MSG = "1" set: function (newVal, oldVal) {} function ( newVal, oldVal ) {} })Copy the code
A minimalist implementation of Vue bidirectional binding
- Analysis of Vue principle & implementation of bidirectional binding MVVM
<! <span id="sp"></span> <script> var TXT = document.getelementbyid (' TXT '), Sp = document.getelementById ('sp'), obj = {} DefineProperty (obj, 'MSG ', {// Set obj. MSG the set method will be called when obj. MSG is changed: Value = newVal sp.innertext = newVal}}) function (newVal) {// Obj.msg is set to input/span txt.value = newVal sp.innertext = newVal}} Obj.msg txt.adDeventListener ('keyup', function (event) {obj.msg = event.target.value}) </script>Copy the code
Notes for adding data dynamically
- Note: Only
data
Data added dynamically is non-responsive by default -
You can implement responsiveness to dynamically add data in the following ways
- 1
Vue.set(object, key, value)
– Suitable for adding a single attribute - 2
Object.assign()
– Suitable for adding multiple attributes
- 1
var vm = new Vue({ data: { stu: { name: 'jack', age: 19 } } }) /* Vue.set */ Vue.set(vm.stu, 'gender', */ vm.stu = object.assign ({}, vm.stu, {gender: gender: 'female', height: 180 })Copy the code
Asynchronous DOM update
- Vue performs DOM updates asynchronously, monitors all data changes, and updates the DOM once
- Advantages: The ability to remove duplicate data is important for avoiding unnecessary calculations and avoiding duplicate DOM operations
-
NextTick (callback) : After a DOM update, perform an operation (a DOM operation).
- The instance
vm.$nextTick(function () {})
- The instance
methods: {fn() {this. MSG = 'change' this.$nextTick(function () {console.log('$nextTick: ', this.$el.children[0]. }) console.log(' print directly: ', this.$el.children[0].innertext); }}Copy the code
instruction
- Directives are carried
v-
Special attributes of the prefix - Action: When the value of an expression changes, the resultant effects are applied to the DOM in a responsive manner
v-text
- Update the textContent of the DOM object
<h1 v-text="msg"></h1>Copy the code
v-html
- Update the innerHTML of a DOM object
<h1 v-html="msg"></h1>Copy the code
v-bind
- Action: When the value of an expression changes, the resultant effects are applied to the DOM in a responsive manner
- Grammar:
v-bind:title="msg"
- Abbreviations:
:title="msg"
<! <a v-bind:href="url"></a> <! <a :href="url"></a>Copy the code
v-on
- Function: Bind events
- Grammar:
v-on:click="say"
orV-on :click="say(' parameter ', $event)"
- Abbreviations:
@click="say"
- Note: Bound events are defined in
methods
<! <a v-on:click="doSomething"></a> <! <a @click="doSomething"></a>Copy the code
Event modifier
-
.stop
To stop bubbling, call Event.stopPropagation () -
.prevent
To preventDefault behavior, call event.preventdefault () -
.capture
Use events when adding event listenerscapture
model -
.self
Events are emitted only if the event is emitted within the element itself, such as if it is not a child element -
.once
The event is triggered only once
v-model
- Action: Creates a two-way data binding on a form element
- Note: Listen for user input events to update data
- Case study: Calculator
<input type="text" v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>Copy the code
v-for
- Function: Render an element or template block multiple times based on the source data
<! - 1 basic usage - > < div v - for = "item in the items" > {{item. Text}} < / div > <! - the item for the current item, the index for the index - > < p v - for = "(item, index) in the list" > {{item}} - {{index}} < / p > <! -- item = value, key = key Index for the index - > < p v - for = "(item, the key index) in obj" > {{item}}, {{key}} < / p > < p v - for = "item in 10" > {{item}} < / p >Copy the code
The key attribute
- Recommended: Use
v-for
When offeredkey
Property to get a performance boost. - Note: With keys, VUE rearranges elements based on key changes and removes elements where the key does not exist.
- vue key
- Description of vue key attributes
<div v-for="item in items" :key="item.id"> <! </div>Copy the code
Style handling -class and style
- Usage:
v-bind:class="expression"
or:class="expression"
- Types of expressions: string, array, object (emphasis)
- Grammar:
<! 1 - - - > < div v - bind: class = "{active: true}" > < / div > = = = > parsed < div class = "active" > < / div > <! 2 - - - > < div: class = "[' active ', 'text - danger']" > < / div > = = = > parsed < div class = "active text - danger" > < / div > <! -- 3 --> <div v-bind:class="[{ active: True}, errorClass] "> < / div > = = = > parsed < div class =" active text - danger "> < / div > - style -- -- -- <! -- 1 --> <div v-bind:style="{ color: activeColor, 'font-size': fontSize + 'px' }"></div> <! -- 2 Apply multiple style objects to an element --> <! <div v-bind:style="[baseStyles, overridingStyles]"></div>Copy the code
V – if and v – show
- Conditions apply colours to a drawing
-
v-if
: Destroys or rebuilds elements based on whether the value of an expression is true or false -
v-show
: Toggles the element’s display CSS property based on the expression’s true or false value
<p v-show="isShow"> Is this element displayed?? </p> <p v-if="isShow"> This element, in HTML structure?? </p>Copy the code
Improved performance: V-Pre
- Note: Vue skips compilation of this element and its children. You can use it to display the original Mustache tag. Skipping a large number of nodes without instructions speeds up compilation.
<span v-pre>{{ this will not be compiled }}</span>Copy the code
Performance improvement: V-once
- Note: Vue renders elements and components only once. In subsequent re-rendering, the element/component and all its child nodes are treated as static and skipped. This can be used to optimize update performance.
<span v-once>This will never change: {{msg}}</span>Copy the code
Filter filter
- Function: Format text data
- Filters can be used in two places:
{{}}
And the V-bind expression - There are two types of filters: 1 global filter 2 local filter
Global filter
- Note: Filters created globally can be used in any VUE instance
- Note: When using a global filter, you need to create a global filter before creating a Vue instance
- What is displayed is determined by the return value of the filter
Vue. Filter ('filterName', function (value) {// value indicates what to filter})Copy the code
- Example:
<div>{{ dateStr | date }}</div> <div>{{ dateStr | date('YYYY-MM-DD hh:mm:ss') }}</div> <script> Vue.filter('date', Function (value, format) {// value Specifies the contents of a string to filter, e.g. DateStr // format specifies the parameters to filter, e.g. 'YYYY-MM-DD hh: MM :ss'}) </script>Copy the code
Local filter
- Note: Local filters are created in the content of a vUE instance and only work in the current instance
Filters filters: {filterName: function(value, format) {}}Copy the code
Key value modifier
- Note: When listening for keyboard events, Vue allows
v-on
Add key modifiers when listening for keyboard events - Keyboard event – key value modifier
- Others: Modifier keys (.ctrl, etc.), mouse button modifier (.left, etc.)
Submit () @keyup.13="submit" // Use the global keyalias @keyup.Enter ="add" -- // through global config.keycodes F2 = 113 // Use @keyup.enter. F2 ="add"Copy the code
Monitor data changes – Watch
- Summary:
watch
Is an object, the key is the expression to observe, and the value is the corresponding callback function - Function: When the value of the expression changes, the corresponding callback function is called to complete the monitoring operation of the response
- VUE $watch
new Vue({ data: { a: 1, b: { age: 10 } }, watch: { a: Function (val, oldVal) {function(val, oldVal) {console.log(' current value: '+ val,' oldVal: '+ oldVal)}, { handler: function (val, oldVal) { /* ... 'user.age': function (val, oldVal) {},}})Copy the code
Calculate attribute
- Note: Computed properties are cached based on their dependencies and are reevaluated only if its dependencies change
- Note: Don’t put too much logic into Mustache syntax ({{}}) because it will make your template too heavy, difficult to understand and maintain
- Note: Attributes in computed cannot have the same name as attributes in data, otherwise an error will be reported
- Principle of Vue computed attributes
var vm = new Vue({
el: '#app',
data: {
firstname: 'jack',
lastname: 'rose'
},
computed: {
fullname() {
return this.firstname + '.' + this.lastname
}
}
})Copy the code
Instance life cycle
- All Vue components are Vue instances and accept the same option object (except for some root instance specific options).
- The instance life cycle is also called the component life cycle
Life Cycle Introduction
- Vue lifecycle hook functions
- To put it simply: the life cycle of a component is the states that a component goes through from start to end
The three phases of a component’s life cycle hook function are always accompanied by various component events, which are collectively referred to as component life cycle functions.
- Note: Vue is called automatically during execution
Lifecycle hook functions
We just need to provide these hook functions - Note: The names of hook functions are specified in Vue!
Hook function -beforecreate ()
- Description: After instance initialization, data Observer and Event/Watcher events are called before configuration
- Note: The data in data and methods in methods cannot be obtained
Hook function –created()
- Note: This is a common lifecycle where you can call methods in Methods and change data in data
- Vue instance life cycle Reference 1
- Vue instance Lifecycle Reference 2
- Usage scenario: Send a request to obtain data
Hook function – beforeMounted()
- Description: called before the mount begins
Hook function –mounted()
- Note: At this point, the VUE instance has been mounted to the page, you can obtain DOM elements in el, DOM operations
Hook function – beforeUpdated()
- Description: Called when data is updated, which occurs before the virtual DOM is re-rendered and patched. You can further change the state in this hook without triggering additional rerendering.
- Note: The data retrieved here is the updated data, but the DOM elements in the retrieved page are the ones before the update
Hook function – Updated ()
- Note: The component DOM has been updated, so you can now perform DOM-dependent operations.
Hook function – beforeDestroy()
- Description: called before instance destruction. At this step, the instance is still fully available.
- Usage scenario: Before instance destruction, perform clearing tasks, such as clearing timers
Hook function – Destroyed ()
- Call after Vue instance is destroyed. When called, everything indicated by the Vue instance is unbound, all event listeners are removed, and all subinstances are destroyed.
axios
-
Promise based HTTP client for the browser and node.js
- Promise based HTTP client for: browsers and Node.js
- Encapsulate Ajax for sending requests and retrieving data asynchronously
- Installation:
npm i -S axios
- axios
// 在浏览器中使用,直接引入js文件使用下面的GET/POST请求方式即可
// 1 引入 axios.js
// 2 直接调用axios提供的API发送请求
created: function () {
axios.get(url)
.then(function(resp) {})
}
---
// 配合 webpack 使用方式如下:
import Vue from 'vue'
import axios from 'axios'
// 将 axios 添加到 Vue.prototype 中
Vue.prototype.$axios = axios
---
// 在组件中使用:
methods: {
getData() {
this.$axios.get('url')
.then(res => {})
.catch(err => {})
}
}
---
// API使用方式:
axios.get(url[, config])
axios.post(url[, data[, config]])
axios(url[, config])
axios(config)Copy the code
A Get request
Const url = "http://vue.studyit.io/api/getnewslist" / / url with query parameters axios. Get ('/user? id=89') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); Get ('/user', {params: {id: 12345}})Copy the code
A Post request
- Handle POST requests in different environments
- By default, AXIos serializes JS objects into JSON objects. In order to use
application/x-www-form-urlencoded
Format the request to send, we can do this:
// var qs = require('qs') import qs from 'qs' qs.stringify({'bar': 123}) = = = > "bar = 123" axios. Post ('/foo, qs stringify ({" bar ": 123})) / / or: axios. Post ('/foo ', 'the bar = 123 & age = 19)Copy the code
Const url = "http://vue.studyit.io/api/postcomment/17" axios. Post (url, 'the content = point a great however) axios. Post ('/user', qs.stringify({ firstName: 'Fred', lastName: 'Flintstone' })) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });Copy the code
Global configuration
// Set the request public path: axios.defaults.baseURL = 'http://vue.studyit.io'Copy the code
The interceptor
- The interceptor intercepts every request that is sent and executes it before it is sent
request
Is executed after the request is sentresponse
The function in
/ / request interceptor axios. Interceptors. Request. Use (function (config) {/ / all requests are to be executed before the return operation config. }, function (error) {return promise.reject (error); }); / / response interceptor axios. Interceptors. Response. Use (function (response) {/ / all request is completed to perform operations return response; }, function (error) {return promise.reject (error); });Copy the code
Custom instruction
- Function: Perform DOM operations
- Use scenarios: Perform low-level operations on pure DOM elements, such as text boxes to get focus
- Vue custom instruction usage instance
- There are two kinds of instructions: 1 global instruction 2 local instruction
Global custom instruction
// First argument: directive name Directive ('directiveName', {// Bind can only perform DOM operations on the element itself, not on its parent element. // Only call once when the directive is first bound to the element. This is where you can perform one-time initialization Settings. Bind (el, binding, vnode) {bind(el, binding, vnode) { // Binding: an object containing the following attributes: // name: directive name, excluding the v- prefix. // value: the binding value of the directive, the value after the equals sign. // oldValue: The previous value of the directive binding, available only in update and componentUpdated hooks. Available regardless of whether the value changes. // expression: string expression after the equal sign // arg: parameter passed to the instruction, optional. For example, v-my-directive:foo, the parameter is "foo". // modifiers: directive modifiers For example, in v-directive.foo.bar, the modifier object is {foo: true, bar: true}. // vnode: virtual node generated by Vue compilation. // oldVnode: the last virtual node, available only in update and componentUpdated hooks. Inserted (el, binding, vnode) {}, // update(el, Binding, vnode,oldVnode) {}, componentUpdated (EL, binding, vnode,oldVnode) {}, Unbind (el) {// The element on which the instruction is attached disappears from the page, triggering}}) // Short if you want to trigger the same behavior with bind and update, regardless of the other hooks: Function (el, binding) {}} Vue.directive('color', function(el, <p v-color="'red'"></p> </p> </p>Copy the code
Local custom instructions
var vm = new Vue({
el : "#app",
directives: {
directiveName: { }
}
})Copy the code
- Vue analysis of VUE principle & implementation of bidirectional binding MVVM
component
Component systems are another important concept for Vue because it is an abstraction that allows us to build large applications from small, independent, and often reusable components. If you think about it, almost any type of application interface can be abstracted into a tree of components
- There are two ways to create a component: 1 Global component 2 local component
Global components
- Note: Global components are available in all VUE instances
- Note: Register the component before initializing the root instance
Vue.com ('my-component', {// template can only have one root element template: '<p>A custom Component! </p>', // the 'data' in the component must be a function and the return value of the function must be the object data() {return {MSG: 'Note: the data in the component must be a function!! '}}}) // 2 <div id="example"> <my-component></ my-Component ></ div> // =====> Render result <div id="example"> <p>A custom element component! </p> </div> // 3 The value of the template attribute can be: -1 template string -2 template ID template: '#tpl' <script type="text/x-template" id="tpl"> <p>A custom component! </p> </script>Copy the code
-
extend
: Using the base Vue constructor, create a “subclass”. The parameter is an object that contains component options.
Vue.component('my-component', vue.extend ({/*... */})) // Register the component, pass in an option object (automatically call vue.extend) Vue.component('my-component', {/*... */ }) var Home = Vue.extend({ template: '', data() {} }) Vue.component('home', Home)Copy the code
Local components
- Note: Local components, defined in a specific VUE instance, can only be used in this VUE instance
var Child = { template: '<div>A custom component! </div>'} new Vue({// {// <my-component> will only be used in the current vue instance // my-component for component name value for configuration object 'my-component': {template: ``, data () { return { } }, props : [] } } })Copy the code
Is characteristic
Only specified tables can exist in certain tags such as ul > Li. For browsers to parse properly, is is required
<! <ul id="app"> <! - can't identify - > < my - li > < / my - li > normal recognition < li is = "my - li" > < / li > < / ul > < script > var = new vm Vue ({el: "# app," components: {myLi: {template: ` < li > content < / li > `}}}) < / script >Copy the code
Component communication
Parent component to child component
- How: Through child components
props
Property to pass data props is an array - Note: The value of the property must pass through the component
props
Property display specified, otherwise, does not take effect - Description: passed over
props
The use of attributes anddata
Attributes are used the same way
<div id="app"> <! <hello v-bind: MSG ="info"></hello> <! - if the transfer is literal Then write directly - > < hello my - MSG = "ABC" > < / hello > < / div > <! -- js --> <script> new Vue({el: "#app", data: {info: 15}, components: {hello: {// Create props and pass it to props: [' MSG ', 'myMsg], the template:' < h1 > hello is this component, this is the message: {{MSG}} - {{myMsg}} < / h1 > '}}}) < / script >Copy the code
Child component to parent component
Mode: The parent passes a function to the child, which calls the function
- Description: With custom events in VUE (V-ON :cunstomFn=”fn”)
Steps:
- 1. Define method parentFn in parent component
- Custom event name =” method in parent component “==> @pfn=”parentFn”
- 3. Pass in subcomponents
$emit()
Emit the custom event event this.$emit(PFN, parameter list…)
<hello @click=" parentFn"></hello> <script> Vue.component('hello', {template: '<button @click="fn"> button </button>'), methods: $emit() {this.$emit(' PFN ', 'this is the data that the child sent to the parent ')}}}) new Vue({methods: ParentFn (data) {console.log(' Parent component: ', data)}}}) </script>Copy the code
Non-parent component communication
In simple scenarios, an empty Vue instance can be used as the event bus
-
$on()
: Binds custom events
Bus.$on('id-selected', function (id) {//... Bus.$emit('id-selected', 1)Copy the code
- Example: Component A –> component B
<! -- Component A: --> <com-a></com-a> <! Var vm = new Vue({el: '#app', components:) var vm = new Vue({el: '#app', components: {comB: {template: '< p > component A, tell me: {{MSG}} < / p >', the data () {return {MSG: $on('tellComB', (MSG) => {this. MSG = MSG})}}, comA: {template: '<button @click="emitFn"> </button> {emitFn() {// Trigger a custom event in the intermediate component bus.$emit('tellComB', 'Potato potato I am pumpkin ')}}}}}) </script>Copy the code
Content distribution
- Specify the content display area with the
tag
Case study:
<! <div id="app"> <hello> <! <p slot=" slot name "> I am extra content </p> </hello> </div>Copy the code
New vue({el: "#app", Components: {hello: {template: ` < div > < p > I am a child in the component content < / p > < slot name = "name" > < / slot > < / div > `}}})Copy the code
Get component (or element) -refs
- Description:
vm.$refs
An object that holds all the child components (or HTML elements) that have registered a REF - Use: In an HTML element, add
ref
Property, which is then passed in JSVm. $refs. Properties
In order to get - Note: If you are retrieving a child component, you can retrieve data and methods from the child by ref
<div id="app"> <div ref="dv"></div> <my res="my"></my> </div> <! -- js --> <script> new Vue({el: "#app", mounted() {this.$refs.my // echo // echo // echo // echo // echo // echo // echo), components: { my : { template: `<a>sss</a>` } } }) </script>Copy the code
SPA – Single page application
SPA: Single Page Application
A single Page Web application (SPA) is a single Web page application that loads a single HTML page and dynamically updates the page as the user interacts with the application.Copy the code
-
Single-page applications:
- Only the first time the page loads, and every subsequent request just gets the necessary data. Then, the data obtained by the JS parsing in the page is displayed in the page
-
Traditional multi-page applications:
- For traditional multi-page applications, the server returns a complete page each time it requests it
advantage
- 1 reduces the request volume, speeds up the page response speed, and reduces the pressure on the server
- 2 better user experience, so that users can feel the smoothness of native APP in Web App
Realization of ideas and technical points
- 1 ajax
- 2 Use of anchor points (window.location.hash #)
- Window.addeventlistener (“hashchange”,function () {})
- 4 Monitor the event of anchor point value change and request corresponding data according to different anchor point value
- 5 is used to jump inside the page, locate and display the corresponding content
routing
- Routing is the rule between the hash value (# hash) in the browser and the display view content (template)
- The route in vUE is the mapping between hash and Component
In a Web app, a single page is used to display and manage the functionality of the entire application. SPA is often a complex application, in order to effectively manage all view content, front-end routing came into being! In simple terms, routing is a set of mapping rules (one-to-one correspondence rules) that are set by the developer. When the hash value (# hash) in the URL changes, the route will display the corresponding view content according to the specified rules
The basic use
- Install: NPM I-S VUe-router
<div id="app"> <! <router-link to="/home" </router-link> <router-link to="/login"> </router-link> <! <router-view></router-view> </div> <! -- 1 import vue. Js - > < script SRC = ". / vue. Js "> < / script > <! /node_modules/vue-router/dist/vue-router.js"></script> <script> // 3 Create two components const Home = Vue.component('home', {template: '<h1> This is the home component </h1>'}) const Login = Vue.component(' Login ', {template: Const router = new VueRouter({routes: [// routes:] {path: '/home', component: Home}, {path: '/login', Component: login}]}) var vm = new Vue({el: '#app', // 6 mount router to Vue instance router})Copy the code
redirect
// Redirect {path: '/', redirect: '/home'}Copy the code
Other Routing Configurations
-
Route navigation highlights
- Note: The router-link-exact-active router-link-active class is automatically added to the current matching navigation links
- Configuration: linkActiveClass
-
Matching Routing Mode
- Configuration: mode
new Router({ routers:[], mode: "Hash", / / the default hash | can achieve hidden address bar history hash value | the abstract, if found no browser API is forced into the linkActiveClass: "Now" // navigation links that currently match will be automatically added to the now class})Copy the code
Routing parameters
- Note: We often need to map all the routes matched by a pattern to the same component. In this case, we can use route parameters to handle this
- Grammar: / user / : id
- Use: When a route is matched, the parameter value is set to this.$route.params
- $route.query query parameters in the URL
{{$router-params. id}}</router-link> // Router-link </ /router-link </ /router-link </ :to="{path:'/user',query:{name:'jack',age:18}}"> User </router > <script> [/ / a note/user / 1001 this form can only be matched/user | / user / | / user / 1001 / / / can be matching by $router in the future. The params gain parameter is {id: 1001} {path: '/user/:id', Component: user}, // mode 2 {path: "user", Component: user}]}) // User component: const user = {template: `<div>User {{ $route.params.id }}</div>` } </script> <! $router.params - $router.params -> <! -- {{$router.query}} -->Copy the code
Nested routines by – child routes
- Routes can be nested, that is, routes contain child routes
- Rule: The parent component contains router-view, and children is configured in the routing rule
// parent: const User = Vue.component(' User ', {template: '<div class="user"> <h2>User Center</h2> <router-link to="/user/profile"> personal profile </router-link> <router-link To ="/user/posts"> </router-link> <! <router-view></router-view> </div> '}) // subcomponent [short] const UserProfile = {template: '<h3> </h3>'} const UserPosts = {template: '< H3 > post: FE</h3>'} [{path: '/user', Component: user, // Children: [{// If /user/profile matches successfully, // UserProfile will be rendered in user's <router-view> path: 'profile', Component: UserProfile}, {// When /user/posts match successfully // UserPosts will be rendered in user <router-view> path: 'posts', component: UserPosts } ] } ] })Copy the code
Front-end modularization
Why modularity is needed
- Js was originally designed to implement client-side validation and some simple effects
- 2. Later, JS gets more and more attention, and its application is more and more widely, and the complexity of front-end development is higher and higher
- Module content is not provided in the old version of JS
Module concept
- In JS, a module is a file that implements a specific function (js file)
- Follow the module mechanic and load whatever functionality you want
- Modular development needs to follow specifications
Modularity solves problems
- 1 Naming Conflict
- 2 File dependencies (Loading files)
- 3 Module reuse
- 4 unified specification and development mode
JS to achieve modular specifications
-
AMD Browser
- requirejs
-
CommonJS nodejs
- Load the module: require()
- Exports: module.exports = {} / exports = {}
- Import/export in ES6
-
CMD browser side
- -> Seajs
- UMD common modular specification, compatible with AMD, CommonJS, browser does not have modular specification syntax
The use of AMD
Asynchronous Module Definition Asynchronous Module Definition Asynchronous Module Definition Asynchronous Module Definition
1. Define modules
// Define (name, dependencies? , factory); < span style = "box-sizing: border-box; color: RGB (74, 74, 74); line-height: 20px; font-size: 14px! Important; word-break: inherit! Important;" Some functions to be performed by the current module, Is a function // define object module define({}) // Define method module define(function() {return {}}) // Define module define(['js/a'], function() {})Copy the code
2. Load the module
// - Note: The first argument to require(['a', 'js/b'], function(a, B) {// use the code in module A and module B})Copy the code
3. Path lookup configuration
- Requirejs uses baseUrl+ Paths by default
-
You can circumvent this setting by:
- 1 ends with.js
- 2 Starts with /
- 3 Protocol: https:// or http://
// config example // note that the configuration should require. Config ({baseUrl: }) require(['a']) // find./js/a.js // require. Config ({baseUrl: '. / js', / / configure a can, directly through the path name (template | | jquery) module loading paths: {template: 'assets/artTemplate/template - native, jquery: 'assets/jquery/jquery.min'}}) // load jquery template module require(['jquery', 'template'])Copy the code
4. Modularity and dependency support
- 1. Add dependent modules of modules to ensure loading sequence (DEPS)
- 2. Turn non-modular modules into modular (exports)
// Example require.config({baseUrl: './js', paths: {// Configure noModule: 'assets/demo/noModule'}, // Configure invalid module item shim: {// module name noModule: {deps: [], // exports of dependencies: 'sayHi' // exports of functions or variables that exist in modules}}}); // If the module name is specified, Define ('moduleA', function() {}) // Import require.config({paths: {// Module name here: moduleA moduleA: 'Assets /demo/moduleA'}})Copy the code
5. Path loading rules
-
Path configuration priority:
- 1 Search for the IP address using the config rule
- 2 Search for the data using the path specified by data-main
- 3 Use the path of the page where RequireJS is imported
<! <script SRC ="js/require.js" SRC ="js/require.js" data-main="js/main"></script>Copy the code
Webpack
- Webpack website
- bundle
[ˈ b ʌ NDL]
Bind, gather, gather, gather into
1 Webpack packs modules with dependencies into independent files that can be recognized by browsers. 2 Webpack merges and parses modules with dependenciesCopy the code
An overview of the
Webpack is a module wrapper for modern JavaScript applications (features Module, Bundler)
Webpack is a
Modular solution (precompiled)
Webpack takes the modules that have dependencies and generates static resources that represent them
- Four core concepts: Entry, output, loader, and plugins
Compare modular solutions: Webpack and Requirejs (code front-end functionality, Browserify is a modular packaging tool similar to WebPack that is precompiled by WebPack (modularity is processed through WebPack during development and eventually the project goes live, Compile on webPack's RequireJS line (code runs on requirejs)Copy the code
Webpack origin
-
Webpack addresses two pain points of existing module packagers:
- 1 Code Spliting – Code separation loads on demand
- 2 Modular solution for handling static resources
Webpack and module
- Front-end module system evolution
- In WebPack’s view, all static resources are modules
- The WebPack module can recognize dependencies between modules in the following forms:
-
JS modular specification:
- ES2015
import
export
- CommonJS
require()
module.exports
- AMD
define
和require
- ES2015
-
Non-static resources such as JS:
- CSS/SASS/LESS file
@import
- Image links, such as styles
url(...)
Or HTML<img src=... >
- Font etc.
- CSS/SASS/LESS file
Webpack documentation and resources
- Webpack Chinese website
- Webpack 1.0
- webpack 2.x+
- Getting started with Webpack is enough
Install webpack
-
Global installation: NPM I-G Webpack
- Purpose: To use in any directory through the CLI
webpack
This command
- Purpose: To use in any directory through the CLI
-
Project installation: NPM I-D Webpack
- Purpose: To perform a build of the current project
Basic use of Webpack
- Installation:
npm i -D webpack
- Webpack can be used in two ways: 1 command line 2 configuration file (
webpack.config.js
)
Command line demo – Case: interlaced color change
- 1 the use of
npm init -y
Initial package.json, using NPM to manage packages in the project - 2 new
index.html
andindex.js
, realize interlaced color change function - 3 run
webpack src/js/index.js dist/bundle.js
The syntax for the package build is:Webpack entry file output file
- 4 Note: the path of the output file needs to be introduced in the page (this step can be removed by configuring webpack).
Const $lis = $('#ulList').find('li') // 3 $lis.filter(':odd').css('background-color', $lis.filter(':odd'). '#def') $lis.filter(':even').css('background-color', 'Skyblue ') // Command line run' webpack SRC /js/index.js dist/bundle.js directory generated in command line run directory /* Run process: 1. Webpack finds the entry file based on the entry file. 2. Analyze the modular syntax in JSCopy the code
Webpack dev – server configuration
Package. json configuration mode
- Installation:
npm i -D webpack-dev-server
- Functions: Cooperate with Webpack, create development environment (start server, monitor file changes, automatically compile, refresh browser, etc.), improve development efficiency
- Note: Cannot be executed directly on a terminal
webpack-dev-server
, need to passpackage.json
的scripts
implementation - Usage:
npm run dev
// --open Automatically opens the browser // --contentBase./ Specifies the index. HTML file in the path of the default page that the browser opens./ / --open Automatically opens the browser // --port 8080 port number // --hot update, load only the changed files (load the changed content as needed) instead of loading all "scripts": {"dev": "webpack-dev-server --open --contentBase ./ --port 8080 --hot" }Copy the code
Webpack.config.js configuration (recommended)
Var path = require('path') module.exports = {// entry: path.join(__dirname, 'SRC /js/index.js'), // output: {path: path.join(__dirname, 'dist'), // Output file path filename: }} const webpack = require('webpack') devServer: {// Tell the server where to serve content from // https://webpack.js.org/configuration/dev-server/#devserver-contentbase contentBase: Path. The join (__dirname, '/'), / / open the browser automatically open: true, / / port port: 8888, / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1 hot update -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- hot: True}, plugins: / / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - 2 enable hot update plug-in -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - new webpack. HotModuleReplacementPlugin ()]Copy the code
-
HTML – webpack – plugin plug-in
- Installation:
npm i -D html-webpack-plugin
- Function: Automatically generate HTML page according to template
- Advantage: Pages are stored in memory and imported automatically
bundle.js
,css
And other documents
- Installation:
/* webpack.config.js */ const htmlWebpackPlugin = require('html-webpack-plugin') plugins: [new htmlWebpackPlugin({// template page path template: Path.join (__dirname, './index.html'), // Generate the page path in memory, default: index.html filename: 'index.html'})]Copy the code
Loaders
- webpack – Loaders
- Webpack – Example of managing resources
webpack enables use of loaders to preprocess files. This allows you to bundle any static resource way beyond JavaScript.
- Webpack can only handle JavaScript resources
- Webpack handles non-javascript static resources through loaders
1. CSS packaging
- Installation:
npm i -D style-loader css-loader
- Note: the order of modules in use cannot be reversed. The loading order is: from right to left
/* Import CSS file in index.js */ import './ CSS /app.css' /* webpack.config.js config.loaders for various resource files */ module: {// Configure matching rules. {test: /\.css$/, use: ['style-loader', 'css-loader']},]} {test: /\.css$/, use: ['style-loader', 'css-loader']}Copy the code
2. Use Webpack to package sass files
- Installation:
npm i -D sass-loader node-sass
- Note:
sass-loader
Depends on thenode-sass
The module
/ * webpack. Config. Reference: js * / / / https://webpack.js.org/loaders/sass-loader/#examples / / "style - loader" : // "CSS-loader" : creates style nodes from JS strings Translates CSS into CommonJS // "sas-loader" : Compiles Sass to CSS to compile Sass module for CSS: {rules: [{test: / \. (SCSS | Sass) $/, use: ['style-loader', 'css-loader', 'sass-loader']}, ] }Copy the code
3. Pack images and fonts
- Installation:
npm i -D url-loader file-loader
-
file-loader
: Load and rename files (images, fonts, etc.) -
url-loader
: Converts an image or font to a base64 encoded string, embedded in a style file
/ * webpack. Config. Js * / module: {rules: [/ / packaging image file {test: / \. (JPG | PNG | | GIF jpeg) $/, use: 'url - loader'}, / / packaged font file {test: / \. (woff | woff2 | eot | the vera.ttf | otf) $/, use: 'file - loader'}]}Copy the code
Picture packaging details
-
The limit parameter is used in bytes.
- When the image file size (bytes)
Less than
When limit is specified, the image is converted to base64 encoding format - When the image file size (bytes)
Greater than or equal to
When the limit is specified, the image is renamed to load as a URL pathfile-loader
To load the image)
- When the image file size (bytes)
- Image files are renamed to ensure that the same file is not loaded more than once. For example, copy one image (A.jpg) to one copy (B.jpg), and import both images. The rename will only load once, because the two images are the same
- After the file is renamed, the name of the file is calculated using MD5 encryption
/* webpack.config.js */
module: {
rules: [
// {test: /\.(jpg|png|gif|jpeg)$/, use: 'url-loader?limit=100'},
{
test: /\.(jpg|png|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
]
}Copy the code
Font file packaging instructions
- The processing method is the same as the picture, you can use:
file-loader
orurl-loader
babel
- babel
- es2015-loose
- Babel buckets
- Installation:
npm i -D babel-core babel-loader
- Installation:
npm i -D babel-preset-env
Basic Use (two steps)
- The first step:
/* webpack.config.js */ module: {rules: [// exclude: 'babel-loader', use: 'babel-loader', exclude: /node_modules/} ] }Copy the code
- Step 2: Create a new one in the project root directory
.babelrc
The configuration file
{"presets": ["env"]} {"env" : ["env"]}}Copy the code
The specification of Babel
-
What Babel does:
- 1 Syntax conversion: Convert the new ES syntax to a browser-recognized syntax (babel-preset-*)
- Polyfill browser compatibility: Make older browsers compatible with the latest ES API
babel-preset-*
Babel supports the latest version of JavaScript syntax with a syntax converter
Babel-preset -* specifies what version of JS code we are writing
- What it does: Converts the new ES syntax into ES5 code that browsers can recognize
-
The approval process for ES6 syntax proposals
- ES2015 is ES6, and the next version is ES7. There are five stages between ES6 and ES7
- Babel-preset – ES2015 converts es6 syntax
- Babel-preset -stage-0 converts to a newer syntax than ES6
Stage 1: What is your Proposal? Stage 2: What is your Proposal? Stage 3: What is your Candidate Stage 0 is "I've got a crazy idea", Stage 1 is" This idea might not be stupid", stage 2 is "let's use polyfills and transpilers to play with it", stage 3 is "let's let browsers implement it and see how it goes", stage 4 is "now it's javascript".Copy the code
Babel – polyfill and transform – runtime
-
Purpose: to achieve browser compatibility with unsupported apis (compatibility with older environments, fill)
- Use advanced ES6 or ES7 methods or functions in older browsers, such as:
'abc'.padStart(10)
- Use advanced ES6 or ES7 methods or functions in older browsers, such as:
- Methods a polyfill
- Way 2 transform – runtime
- A:
npm i -S babel-polyfill
-
NPM i-d babel-plugin-transform-Runtime and NPM i-s babel-runtime
- Note: the code in the babel-Runtime package is packaged into your code (-s).
All compatibility problems can be solved by using polyfill (including instance methods), contaminating the global environment runtime All compatibility problems can be solved without contaminating the global environment except instance methods ` Promise `), static methods (such as: ` Object. The assign `) or * * * * instance methods (such as: ` String. The prototype. PadStart `) and so on, you will need to use ` Babel - polyfill ` Babel - runtime: Const Promise = require('babel-runtime/core-js/ Promise ') const Promise = require('babel-runtime/core-js/ Promise ') 1 Manual import is too cumbersome 2 The same helper (definition) is imported for multiple files, causing code duplication and increasing code volume. 2. Babel-runtime provides the definition of a helper. Transform Runtime: add a plugins configuration item to the.bablerc file. "plugins": [ "transform-runtime" ]Copy the code
/* Babel-polyfill: // / require("babel-polyfill") var s = 'ABC '. PadStart (4) console.log(s) // 2 webpack.config.js configuration module.exports = { entry: ['babel-polyfill', './js/main.js'] }Copy the code
conclusion
Babel-core babel-loader is used to parse JS files and preset-* New ES syntax for parsing and conversion transform-Runtime/babel-polyfill compatible with older browsers, // Check whether the browser is compatible with the padStart API. String. The prototype. PadStart) {/ / if not compatible, Is the realization of the function of the simulation padStart himself a String. The prototype. PadStart = function padStart (targetLength padString) {}}Copy the code
Vue single file component
- vue-loader
- Single-file Components
- Suffix:
.vue
The file needs to be precompiled before it can be used in the browser - Note: Single-file components rely on two packages vue-loader/vue-template-Compiler
- Installation:
npm i -D vue-loader vue-template-compiler
<! Vue example code: --> <template> <div> <h1>VUE single-file component example -- app. VUE </h1> <p> This is the logical code export in the template content </p> </div> </template> <script> // component Default {} </script> <style> /* Components */ h1 {color: red; } </style>Copy the code
// webpack.config.js configuration: {rules: [{test: /\.vue$/, loader: 'vue-loader'}]}Copy the code
Use single-file components
/* main.js */ import Vue from 'Vue' // import App from 'Vue' // app.vue 'const vm = new Vue({el: Render: c => c(app)})Copy the code
Steps for using single file components
- 1 installation:
npm i -D vue-loader vue-template-compiler
-
2 Configure the loader for the. Vue file in webpack.config.js
{ test: /\.vue$/, use: 'vue-loader' }
- 3 to create
App.vue
Single file component, note: App can be any name - 4 in
main.js
Import file, importvue
和App.vue
Component, which uses Render to attach the component to the instance
Single file component + routing
- vue – Vue.use
- Vue. Use and routing
Import the Vue from 'Vue' import App from '. / App. Vue '/ / -- -- -- -- -- -- -- -- -- -- -- -- -- the Vue routing configuration start -- -- -- -- -- -- -- -- -- -- -- -- -- -- the import Home from '/ components/home/home. Vue' import Login from '. / components/Login/Login. Vue '/ / 1 import routing module import VueRouter the from Router = new VueRouter({routes: [{path:]) const router = new VueRouter({routes: [{routes:]) '/home', component: Home }, { path: '/login', component: The Login}]}) / / -- -- -- -- -- -- -- -- -- -- -- -- -- end of vue routing configuration -- -- -- -- -- -- -- -- -- -- -- -- -- -- const vm = new vue ({el: '# app, render: C => c(App), // 4 mount router to vue instance}Copy the code
Mint-UI
- Vue. Js based mobile component library
- Mint-UI
Quick start
- Installation:
npm i -S mint-ui
Import MintUI from 'mint-ui' import mint-ui from 'mint-ui' import mint-ui from 'mint-ui' import mint-ui from 'mint-ui' import mint-ui from 'mint-ui' import mint-ui from 'mint-ui'Copy the code
MUI
- MUI
- MUI is also a MOBILE UI library
- Use: Download the package from Github, go to the dist folder, and just import the styles
/ / you just need to import the MUI style, according to the example of MUI, using HTML results can be directly / / import style import '. / lib/s/CSS/MUI. Min. CSS 'Copy the code
ElementUI
- This is the PC UI component library
- Installation:
npm i -S element-ui
- Are you hungry? – ElementUI
{
"presets": [
["es2015", { "modules": false }], "stage-0"
],
"plugins": [
["component", [
{
"libraryName": "mint-ui",
"style": true
},
{
"libraryName": "element-ui",
"styleLibraryName": "theme-default"
}
]]
]
}Copy the code
Webpack publishes projects
- Webpack packs various pits
-
webpack
The dist directory command generates the dist directory to disk, and finally, the packaged code is deployed to the server -
webpack-dev-server
Files that are only generated in memory are not written to disk, so they can only be used during development
Create a project publishing profile
- Configuration files during development:
webpack.config.js
- Project release profile:
webpack.prod.js
(The file name is not fixed.) - Command:
webpack --config webpack.prod.js
Run WebPack with a configuration file name - Parameters:
--display-error-details
Used to display error messages for Webpack packaging
/* package.json */
"scripts": {
"build": "webpack --config webpack.prod.js"
}Copy the code
1 Create the webpack.prod.js file in the project root directory. 2 Configure a script in package.json. 3 Package the project using NPM run build in the terminalCopy the code
Packaging process
1 Delete configuration items related to devServer 2 Output pictures and font files to the specified folder 3 Automatically delete dist directory 4 Separate third-party packages (extract third-party packages such as Vue from vender.js) 5 Compress confused JS and specify the generation environment 6 Extract and compress CSS files. 7 Compress HTML pages. 8 Implement the on-demand loading function together with vUE asynchronous componentsCopy the code
Processing image path
- Note: If
limit
Less than is greater than the picture, then the picture will be converted tobase64
Coding format - Name Parameter Description
/ * webpack. Prod. Js * / / / handle the URL path loader {test: / \. (JPG | PNG | | GIF BMP | jpeg) $/, use: {loader: 'URL - loader, the options: { limit: 8192, name: 'images/[hash:7].[ext]' // Action: To export images to the images folder using a 7-bit hash (MD5) file name and keep the original image file extension // name: specify the file output path and output file command rule // [hash:7] : Name: 'imgs/img-[hash:7].[ext]'}}},Copy the code
Automatically delete the dist directory
- Installation:
npm i -D clean-webpack-plugin
- Effect: Before each packing, delete the last packing dist directory
/* webpack.prod.js */ const cleanWebpackPlugin = require('clean-webpack-plugin') plugins: New cleanWebpackPlugin(['./dist'])Copy the code
Separate third-party packages
-
Purpose: To separate common third-party packages into a separate package file, so as to prevent double packaging!
- For example, vUE is introduced in main.js, Router, and vuex. Without separation, vUE is packaged three times
- After the extraction, the VUE file is packaged only once and used only for references
/* webpack.prod.js */ / 1 entry -- pack file entry: {// project code entry app: Path. Join (__dirname, '. / SRC/js/main. Js'), / / third-party packages entrance vendor: [' vue ', 'vue - the router', 'axios]}, the output: {// 2 Modify the output file path and naming rules filename: 'js/[name].[chunkhash].js',}, plugins: [/ / 3 (third-party packages new webpack.optimize.Com monsChunkPlugin {/ / will be specified in the entry [' vue ', 'vue - the router, 'axios'] package to js file named vendor // third-party package entry name, corresponding vendor attribute name in entry: 'vendor',}),]Copy the code
Compressing obfuscated JS
- Note: Uglifyjs cannot compress ES6 code
plugins: New code / / https://github.com/webpack-contrib/uglifyjs-webpack-plugin/tree/v0.4.6 / / / optimization Webpack. Optimize. UglifyJsPlugin ({/ / compression compress: {/ / remove the warning warnings: False}}), // Specify production environment: vue will use this to enable the compressed vue file new webpack.defineplugin ({'process.env': {'NODE_ENV': JSON.stringify('production') } }) ]Copy the code
Extract and compress CSS files
- Installation: Pull away
npm i -D extract-text-webpack-plugin
- Installation: compression
npm i -D optimize-css-assets-webpack-plugin
- Webpack extracts CSS documents
- Compress and extract the CSS
Error processing file: CSS /style. CSS postcss-svgo: Error in parsing SVG: parsing parsing parsing parsing parsing parsing parsing parsing parsing parsing Unquoted attribute value Cause: Only SVG is allowed to use double quotes in the plug-in that compresses and extracts CSSCopy the code
/* webpack.prod.js */ // extract CSS into a separate file const ExtractTextPlugin = require("extract-text-webpack-plugin"); Const OptimizeCssAssetsPlugin = require('optimize- CSS-assets-webpack-plugin ') Output: {//... output: {//... / / https://doc.webpack-china.org/configuration/output/#output-publicpath / / set the path publicPath: '/',}, the module: {rules: [ { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" }) }, { test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: ['css-loader', 'sass-loader'] }) }, ] }, plugins: New ExtractTextPlugin(" CSS /style.css"), // New OptimizeCssAssetsPlugin()]Copy the code
Compress HTML pages
- For details, see html-minifier
New htmlWebpackPlugin({// template page template: path.join(__dirname, './index.html'), // Compress HTML minify: CollapseWhitespace: true, // Collapse comment removeComments: true, // Remove double quotes from attribute removeAttributeQuotes: true}}),Copy the code
Vue works with Webpack to load routes on demand
- Vue routes are loaded lazily
- Vue asynchronous components
- Analysis of lazy loading of Vue components
- [Vue. Js routing lazy loading [translate]] (www.jianshu.com/p/abb0…
steps
- 1 Change the reference mode of the component
// require. Ensure () const NewsList => require. Ensure ([], () => r(require('.. / components/news/newslist. Vue '), 'news') / / 2: import () - recommend / / note: / * webpackChunkName: "Newsinfo" */ is a special syntax for generating js files const newsinfo = () => import(/* webpackChunkName: "newsinfo" */ '.. /components/news/newsinfo.vue')Copy the code
- 2 Modify the output of the Webpack configuration file
Output: {/ / -- -- -- -- -- - add chunkFilename, specify the output js file name -- -- -- -- -- - chunkFilename: 'js / [name] [chunkhash] js',},Copy the code