Source: making a qualified intermediate front-end engineers need to acquire skills | o stars ✨ | give a ❤ ️ attention, ❤ ️ thumb up, ❤ ️ encourages the author
Hello everyone, I’m Nezha. Nice to meet you ~~
Nezha’s life creed: If you like what you learn, there will be strong motivation to support it.
Learn programming every day, so that you can get a step away from your dream. Thank you for not living up to every programmer who loves programming. No matter how strange the knowledge point is, work with me to calm down the wandering heart and keep going. Welcome to follow me vx:xiaoda0423, welcome to like, favorites and comments
Don’t be afraid to dream, but don’t just dream. Be a doer, not a talker.
preface
If this article is helpful to you, give ❤️ a follow, ❤️ like, ❤️ encourage the author, accept the challenge? Article public account launch, concern programmer Doraemon first time access to the latest article
How to implement lazy route loading
{ path: '/login', component: () => import('@/views/login/index'), hidden: true },
Copy the code
Route lazy load magic comment
You can customize the name of this file by specifying webpackChunkName in the comment.
components = () => import(/* webpackChunkName:"login"*/ ".. /component/Login.vue")Copy the code
Set up the Vue development environment in Windows
Set the nodeJS prefix (global) and cache (cache) paths
In the nodeJS installation directory, create the node_global and node_cache folders
- Setting the cache folder
npm config set cache "D:\vueProject\nodejs\node_cache"
Copy the code
- Set the global module storage path
npm config set prefix "D:\vueProject\nodejs\node_global"
Copy the code
Install CNPM based on Node.js (Taobao Image)
npm install -g cnpm --registry=https://registry.npm.taobao.org
Copy the code
Setting environment variables enables you to run CNPM and vue commands in any directory without entering the full path
// System environment variables... Nodejs node_global // User variable... \nodejs\node_modulesCopy the code
Install the Vue
cnpm install vue -g
Copy the code
Vue – cli scaffold
cnpm install vue-cli -g
Copy the code
Create a new project from the template
vue init webpack-simple mytest
Copy the code
- Build, where the final release code is stored
- Config, the configuration directory, including the port number
- Node_modules, which is generated when NPM install is executed, contains node.js and NPM dependent files, as well as third-party components or third-party functions installed later
- SRC, where files related to the development page are stored
- Assets, place some pictures
- Components, which holds the component files
- App.vue is the project entry file
- Main.js, the core file of the project
- Router indicates the route of the project
- Static: Stores static resources, such as images and fonts
- Babelrc file, used to set transcoding rules and plug-ins, generally do not need to set
Test to see if the project works properly
cnpm run dev
Copy the code
Bidirectional binding of Prop
When the parent component communicates with the parent component, the child component does not directly modify the prop passed by the parent component. The parent component always listens for an event on the child component, and then the child component triggers it, so that the parent component receives the payload to change the state.
The v-model directive and the.sync modifier on a custom component solve the problem of child components changing the parent component state
By default, a V-Model on a component makes use of a prop named Value and an event named Input
Effect of bidirectional binding:
<template>
<child-component :val="val" />
</template>
<script>
export default {
data() {
return {
val: 100
}
}
}
</script>
Copy the code
<template>
<div>
<div>{{val}}</div>
<button @click="handleClick">click</button>
</div>
</template>
Copy the code
Through the v – model
The parent component passes val via the V-model:
<template>
<child-component v-model="val" />
</template>
Copy the code
The prop is unbound with the model option in the child component:
Export default {model: {prop: 'anyKey', // Need not be value event: 'anyEventName' // need not be input}, props: {anyKey: { type: Number } }, methods: { handleClick() { this.$emit('anyEventName', this.anyKey+2) } } }Copy the code
Through the.sync modifier
The parent component passes val via the.sync modifier:
<template>
<child-component :val.sync="val" />
</template>
Copy the code
The child component, vue internally helps us bind an event such as Update :myPropName
export default {
props: {
val: {
type: Number
}
},
methods: {
handleClick() {
this.$emit('update:val', this.val+2)
}
}
}
Copy the code
V-bind. sync= “{title: doc.title}”, a binding literal object, modifiers will not work properly
The use of the PropSync
import { Vue, Component, PropSync } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { @PropSync('name', { type: String }) syncedName! : string }Copy the code
The above code is equivalent to:
export default {
props: {
name: {
type: String,
},
},
computed: {
syncedName: {
get() {
return this.name
},
set(value) {
this.$emit('update:name', value)
},
},
},
}
Copy the code
< / / parent component template > < div class = "PropSync" > < h1 > parent component < / h1 > < h2 > {{name}} < / h2 > < Child: name. Sync = "name" > < / Child > < / div > </template> <script lang='ts'> import { Vue, Component } from 'vue-property-decorator'; import Child from './Child.vue'; @Component({components: {Parent}}) export default class ParentPage extends Vue {private name = 'Parent '; </script> // child component <template> <div class="child"> <h1> Child component :</h1> <h2>syncedName:{{syncedName}}</h2> <button @click="changeName"> </button> </div> </template> <script lang="ts"> import {Component, Vue, PropSync} from 'vue-property-decorator'; @Component export default class ChildComponent extends Vue { @PropSync('name', { type: String }) syncedName! : string; ChangeName (): void {this.syncedName = 'syncedName! '; // Bidirectional binding, changing syncedName changes the name of the parent component}} </script>Copy the code
@ the role of the Model
@Model(event? : string, the options: (PropOptions | Constructor [] | Constructor) = {}) @ Model decorator allows us to custom on a component v - Model, takes two parameters: the event: String indicates the event name. Options: PropOptions | Constructor [] | Constructor are consistent with the first parameter of the @ Prop;Copy the code
@Component export default class YourComponent extends Vue { @Model('change', { type: Boolean }) readonly checked! : boolean }Copy the code
Equivalent to the following code:
export default {
model: {
prop: 'checked',
event: 'change',
},
props: {
checked: {
type: Boolean,
},
},
}
Copy the code
The use of the ModelSync
@ModelSync(propName: string, event? : string, the options: (PropOptions | Constructor [] | Constructor) = {}) @ ModelSync decorators can accept three parameters: propName: string type, type names; Event: indicates the name of an event. Options: PropOptions | Constructor [] | Constructor are consistent with the first parameter of the @ Prop;Copy the code
Look at the following example:
import { Vue, Component, ModelSync } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { @ModelSync('checked', 'change', { type: Boolean }) readonly checkedValue! : boolean }Copy the code
The above code is equivalent to:
export default {
model: {
prop: 'checked',
event: 'change',
},
props: {
checked: {
type: Boolean,
},
},
computed: {
checkedValue: {
get() {
return this.checked
},
set(value) {
this.$emit('change', value)
},
},
},
}
Copy the code
@Provide
import { Component, Inject, Provide, Vue } from 'vue-property-decorator' const symbol = Symbol('baz') @Component export class MyComponent extends Vue { @Inject() readonly foo! : string @Inject('bar') readonly bar! : string @Inject({ from: 'optional', default: 'default' }) readonly optional! : string @Inject(symbol) readonly baz! : string @Provide() foo = 'foo' @Provide('bar') baz = 'bar' }Copy the code
Is equal to:
const symbol = Symbol('baz')
export const MyComponent = Vue.extend({
inject: {
foo: 'foo',
bar: 'bar',
optional: { from: 'optional', default: 'default' },
baz: symbol,
},
data() {
return {
foo: 'foo',
baz: 'bar',
}
},
provide() {
return {
foo: this.foo,
bar: this.baz,
}
},
})
Copy the code
@ ProvideReactive and @ InjectReactive
These decorators are reactive versions of @provide and @Inject. If the parent component modifies the supplied value, the child component can capture the change.
const key = Symbol() @Component class ParentComponent extends Vue { @ProvideReactive() one = 'value' @ProvideReactive(key) two = 'value' } @Component class ChildComponent extends Vue { @InjectReactive() one! : string @InjectReactive(key) two! : string }Copy the code
@Emit(event? : string)
decorator
import { Vue, Component, Emit } from 'vue-property-decorator'
@Component
export default class YourComponent extends Vue {
count = 0
@Emit()
addToCount(n: number) {
this.count += n
}
@Emit('reset')
resetCount() {
this.count = 0
}
@Emit()
returnValue() {
return 10
}
@Emit()
onInputChange(e) {
return e.target.value
}
@Emit()
promise() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(20)
}, 0)
})
}
}
Copy the code
Is equivalent to
export default {
data() {
return {
count: 0,
}
},
methods: {
addToCount(n) {
this.count += n
this.$emit('add-to-count', n)
},
resetCount() {
this.count = 0
this.$emit('reset')
},
returnValue() {
this.$emit('return-value', 10)
},
onInputChange(e) {
this.$emit('on-input-change', e.target.value, e)
},
promise() {
const promise = new Promise((resolve) => {
setTimeout(() => {
resolve(20)
}, 0)
})
promise.then((value) => {
this.$emit('promise', value)
})
},
},
}
Copy the code
@Ref(refKey? : string) decorator
import { Vue, Component, Ref } from 'vue-property-decorator' import AnotherComponent from '@/path/to/another-component.vue' @Component export default class YourComponent extends Vue { @Ref() readonly anotherComponent! : AnotherComponent @Ref('aButton') readonly button! : HTMLButtonElement }Copy the code
Is equal to:
export default {
computed() {
anotherComponent: {
cache: false,
get() {
return this.$refs.anotherComponent as AnotherComponent
}
},
button: {
cache: false,
get() {
return this.$refs.aButton as HTMLButtonElement
}
}
}
}
Copy the code
@VModel(propsArgs? : PropOptions)
decorator
import { Vue, Component, VModel } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { @VModel({ type: String }) name! : string }Copy the code
Is equal to:
export default {
props: {
value: {
type: String,
},
},
computed: {
name: {
get() {
return this.value
},
set(value) {
this.$emit('input', value)
},
},
},
}
Copy the code
Rule out packaging
Vue.config. js, add the externals item
configureWebpack: {
externals: {
'vue': 'Vue',
'element-ui': 'ElementUI',
'xlsx': 'XLSX'
},
resolve: {
alias: {
'@': resolve('src')
}
},
}
Copy the code
Referencing Network Resources
- Refer to the CDN:
- Reduce the size of the packages your app packs
- Speed up access to static resources
- Take advantage of the browser cache, the file does not change the long-term cache
Vue-cli3.0 development environment construction
Vue – cli installation
(1) If vuE-CLI (1.x or 2.x) has been installed globally, uninstall it first
npm uninstall vue-cli -g
Copy the code
(2) Install VUE-CLI3.0 globally
npm install -g @vue/cli
Copy the code
(3) Create a project
Vue create Project nameCopy the code
>(*) Babel () TypeScript () Progressive Web App (PWA) Support // Support for Progressive Web applications (Router // routing manager (Vuex) // CSS pre-processors // CSS pre-processors (*) Linter/Formatter // Unit Testing // Unit Testing () E2E Testing // end-to-end TestingCopy the code
Start the project
// 2. Run NPM run serveCopy the code
Single page
Front-end routing mode hash
“#” represents a location on the web page, and the character on the right is the location information.
“#” means that it doesn’t affect the request URL any way it changes, meaning it’s browser-specific.
Any character that appears after the first # is interpreted by the browser as a location identifier. This means that none of these characters are sent to the server side. If you need to send, you need to transcode first.
The “#” means simply changing the part after the #, the browser will simply scroll to the corresponding position, not reload the page.
Changing # alters the browser’s access history
The window.location.hash property is readable and writable. When reading, it can be used to judge whether the state of the web page has changed; When it is written, it creates an access history without reloading the page.
Routing Mode History
(1) history.length (read only) Returns an integer representing the number of elements in the session History, including the currently loaded page.
(2) history. state (read-only) Returns a value representing the state at the top of the History stack
(3) History. ScrollRestoration allows Web application in the navigation on the History of the explicitly set the default scroll recovery behavior.
Vue Element Input limits the number of decimal points after the input number
onkeyup="if(isNaN(value)) {value = null } if(value.indexOf('.')>0) { value = value.slice(0, value.indexOf('.')+5) }"
Copy the code
Vue audio progress drag playback and drag playback problem solved
According to preliminary analysis, the cause of this problem is that audio’s timeUpdate method is triggered about once every second, js code is not processed when audio is playing. This method keeps modifying the model value of slider. When the slider is dragged to the target position (the process is more than 1s) and released, The actual value of the slider has been changed to currentTime by timeUpdate, so releasing the slider will immediately return to the currentTime value.
As long as the timeUpdate method does not change the slider’s model value while dragging the slider without releasing it, add a flag to the slider and set the mouse events mouseDown and mouseup to true. Mouse release (drag ends) flag is false, and the timeUpdate event will only change the model value of slider if flag is false.
<div @mousedown="audio.isDraging = true" @mouseup="audio.isDraging = false"> <el-slider v-model="sliderTime" :show-tooltip="false" class="audio-content-slider" @change="changeCurrentTime" /> </div> private audio: Any = {// Current audio playback duration currentTime: 0, // Maximum audio playback duration maxTime: 0, // Muted: false, speed: 1, waiting: true, preload: 'auto', isDraging: false } timeupdateFunc(e){ if(! this.isDraging){ this.playProcess = (e.target.currentTime)/this.totalTimes*100; this.currentTime = e.target.currentTime; }},Copy the code
git fetch vs git pull
Git fetch is just a local pull. Git pull is not only a local pull but also a merge into a local branch. So git pull is a combination of Git fetch and Git merge.
npm config list
$ npm config list
; "builtin" config from c:\vue\node_global\node_modules\npm\npmrc
; prefix = "C:\\Users\\da\\AppData\\Roaming\\npm" ; overridden by user
; "user" config from C:\Users\da\.npmrc
ca = [""]
cache = "C:\\vue\\node_cache"
get = "registry"
prefix = "c:\\vue\\node_global"
registry = "https://registry.npmjs.org/"
strict-ssl = true
; node bin location = C:\vue\node.exe
; cwd = C:\HBuilderProjects
; HOME = C:\Users\da
; Run `npm config ls -l` to show all defaults.
Copy the code
npm config set registry https://registry.npmjs.org npm config set registry https://registry.npm.taobao.org Temporary solution: Disable SSL NPM config set strict-ssl falseCopy the code
$ npm get registry
https://registry.npmjs.org/
Copy the code
$ npm uninstall -g vue-cli
npm ERR! code EPERM
npm ERR! syscall mkdir
npm ERR! path c:\vue\node_global\node_modules\.vue-cli-SVGezKmI
npm ERR! errno -4048
npm ERR! Error: EPERM: operation not permitted, mkdir 'c:\vue\node_global\node_modules\.vue-cli-SVGezKmI'
npm ERR! [Error: EPERM: operation not permitted, mkdir 'c:\vue\node_global\node_modules\.vue-cli-SVGezKmI'] {
npm ERR! errno: -4048,
npm ERR! code: 'EPERM',
npm ERR! syscall: 'mkdir',
npm ERR! path: 'c:\\vue\\node_global\\node_modules\\.vue-cli-SVGezKmI'
npm ERR! }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It's possible that the file was already in use (by a text editor or antivirus),
npm ERR! or that you lack permissions to access it.
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.
Copy the code
$node -v v14.17.3 $vue -v 2.9.6 $NPM -v 7.20.1 $vue -v @vue/ CLI 4.5.13Copy the code
Is it necessary to install Progressive Web App(PWA)Support for a VUE creation project
A brief introduction: First, add some WebApp support to the project, such as sending ICONS to the desktop on the mobile end. According to different platforms and browsers, try to remove the address bar and bottom bar of the browser to achieve full-screen experience, which is mainly visual and experiential, without any practical functions. The manifest. Json is generated when pWA support is checked, and can be configured in the manifest. You don’t have to use PWA to go offline. There are other ways. Offline is, for example, your project is not necessarily the whole network to achieve the function, as long as the user has visited your website once, even if there is no network when entering the next time, your project will not be white screen, but as usual, or open part of the function, or give a hint of disconnection and so on. Useful for functional sites such as online calculators, online tax widgets, etc. To register the implementation of serviceworker by configuring registerServiceworker.js generated by the project, the specific operation is still very complex, details baidu.
The main features of PWA include the following three points:
- Reliable – Loads and displays instantly, even in an unstable network environment
- Experience – Fast response and smooth animation in response to user actions
- Engagement – Like native apps on devices, with an immersive user experience that users can add to the desktop
PWA has the following characteristics:
- Progressive – Works with all browsers because it was developed with progressive enhancement in mind
- Connection independence – Can be accessed offline or on a poor network with the help of the Service Worker
- Similar application – developed on the basis of App Shell model, it should have the interaction and navigation of Native App to give users the experience of Native App
- Continuous updates – always up to date, no version or update issues
- Security – Provides services over the HTTPS protocol, preventing snooping and ensuring that content is not tampered with
- Indexable – Application manifest files and Service workers can be indexed by search engines to recognize them as “applications”
- Engagement – Users can return via push offline notifications, etc
- Installable – Users can add common WebApps to their desktop without having to download them from the app store
- Linkable – Share content through links without downloading and installing
Manifest is designed to install Web applications on the device’s home screen, providing faster access and a richer experience for users.
To do this, we need to add a manifest.json file and declare it in the index.html file
The pWA-manifest-webpack-plugin allows us to generate files at application build time:
npm i pwa-manifest-webpack-plugin --save
Copy the code
We can then by editing the build/webpack dev. Conf., js and build/webpack. Prod. Conf., js to update the build process.
Introduce the PWA-manifest-webpack-plugin at the top:
const manifestPlugin = require('pwa-manifest-webpack-plugin')
Copy the code
Add it to the plug-in:
Short_name: [new manifestPlugin({name: 'programmer ', // Title specifies the name of the Web App. The short title short_name is actually a short form of the application. Generally, the system uses this short_name when there is not enough space to show the name of the application. 'programmer ', // This field is simply a description of the application. Display: Standalone: // fullscreen display, which takes up as much of the display area as possible Standalone App mode, which opens an App with its own launch icon and does not have the browser address bar, so it looks more like a Native App; minimal-UI: compared to standalone, the App has an address bar; browser: In general, this will open in the same style as normal browser use. "/", // This attribute specifies the URL to load when the user opens the Web App. The relative URL is relative to the manifest. 'portrait-primary', // Controls the orientation of the Web App. Setting certain values will have a screen-lock effect (no rotation), such as in the example of portrait-primary. Any, natural, landscape, landscape-primary, landscape-secondary, portrait, portrait-primary, portrait-secondary. {// ICONS themselves are an array and each element contains three attributes: // // sizes: the sizes of ICONS. By specifying the sizes, the system selects the most appropriate ICONS to display in their respective locations. // SRC: the file path of ICONS. SRC: path.resolve(' SRC /assets/logo.png'), sizes: [200]}, background_color: '# 2d8CF0 ', // Background_color is the default background before the applied style resource is loaded, so it will be displayed in the open screen. Together with the ICONS we have just defined, background_color forms the "open screen" when the Web App is opened. theme_color: '# 2d8CF0 '// defines the default theme color for the application. This can sometimes affect how the operating system displays the application (for example, on Android's task switcher, theme colors surround the application). <meta name="theme-color" content="#5eace0"/>})]Copy the code
Declare manifest.json in index.html:
<link rel="manifest" href="./manifest.json"> <! <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes" <meta name="apple-mobile-web-app-status-bar-style" content="default"> <meta name="apple-mobile-web-app-title" content=" programmers "> <link rel="apple-touch-icon" href="./static/images/logo.png"> <! --end--> <! /> <meta name=" msApplication-tilecolor "content="#222"> <meta name=" msApplication-tilecolor" content="#222" name="msapplication-square70x70logo" content="./static/images/logo.png" /> <meta name="msapplication-square150x150logo" content="./static/images/logo.png" /> <meta name="msapplication-square310x310logo" content="./static/images/logo.png" /> <! --end-->Copy the code
After configuring the above steps, you may want to restart NPM run dev
Service worker is a WEB API, which is an implementation of WEB Workers. It can intercept and process requests and store resources locally in conjunction with CacheStorage apis to achieve offline access.
The life cycle of service workers is as follows:
- Install the install
- Activate the activate
Create a new file service-worker.js
How to adapt a VUE project to support PWA (Chapter 2: Adding service-Workers)
Mixins
Mixins are a bit like functions or macros. When a CSS is often used in more than one element, you can define a Mixin for those shared CSS, and then only call the Mixin where you need to reference those CSS.
Mixins can be used in SASS to define snippets of code that can be passed as parameters for later invocation on demand. For example with cSS3 browser prefixes:
@mixin error($borderWidth: 2px) { border: $borderWidth solid #F00; color: #F00; } .generic-error { padding: 20px; margin: 4px; @ include error(); // Call the default border: 2px solid #F00; } .login-error { left: 12px; position: absolute; top: 20px; @ include error(5px); // Call border:5px solid #F00; }Copy the code
Conditional statements are also supported in SASS:
@if can be used with a single condition, or with @else in combination with multiple conditionsCopy the code
The code is as follows:
$lte7: true; $type: monster; .ib{ display:inline-block; @if $lte7 { *display:inline; *zoom:1; } } p { @if $type == ocean { color: blue; } @else if $type == matador { color: red; } @else if $type == monster { color: green; } @else { color: black; }}Copy the code
The difference between
- Node-sass is a compilation of sass using Node (calling libsass written by CPP); Dart-sass uses the DRAT VM to compile SASS.
- Node-sass is automatically compiled in real time. Dart-sass takes effect only after it is saved. It is recommended that Dart-Sass has better performance (it is also used by SASS officially), and Node-Sass is often not installed due to national conditions
ESLint with error prevention only
- Configure only the recommended rules using the ESLint official website
- These rules add link descriptions here
ESLint + Airbnb config
- Use the rules recommended by ESLint + Airbnb third-party configuration
- Airbnb rules add link descriptions here
ESLint + Standard config
- Use rules recommended by ESLint + Standard third-party configuration
- Standard’s rules add link descriptions here
ESLint + Prettier
- Use the rule + Prettier recommended by ESLint the third-party configuration where Prettier is used
- Prettier usually does the same thing. Code formatting tool
? Pick a unit testing solution: (Use arrow keys) > Mocha + Chai // Mocha is flexible and only provides simple testing structure, if other functions need to add other libraries/plug-ins to complete. Jest must be installed in a global environment. Built Istanbul, you can see test coverage compared to Mocha: simple configuration, simple test code, easy integration with Babel, and rich expect built inCopy the code
$ yarn config get registry
https://registry.yarnpkg.com
$ npm config get registry
https://registry.npmjs.org/
$ yarn config get registry
https://registry.npm.taobao.org
$ cnpm config get registry
https://registry.nlark.com/
Copy the code
[click.left&contextmenu&click.middle]
<div id="ask"><! Vue has no control over body and HTML tags. - the left mouse button - > < div: style = "left_style" @ click. Left = "mouseclick (' left ')" > < / div > <! - the middle mouse button - > < div: style = "middle_style" @ click. Middle = "mouseclick (', ')" > < / div > <! -- right mouse button --> <! <div :style="right_style" @contextmenu ="mouseclick(' right ')"></div> </div>Copy the code
Installation:
npm install -g @vue/cli
# OR
yarn global add @vue/cli
Copy the code
Create a project:
vue create my-project
# OR
vue ui
Copy the code
$NPM install -g vue-cli Create a vUE project of your own $vue init webpack vuedemo vue cli 2 NPM install -g @vue/cli-init # 'vue init' will run the same as' [email protected] 'vue init webpack my-projectCopy the code
$ yarn config get registry https://registry.npm.taobao.org $ yarn config set registry https://registry.npmjs.org - global yarn config v1.22.11 success Set "registry" to "https://registry.npmjs.org". Done in 0.06 s. $CNPM config the get registry https://registry.nlark.com/Copy the code
@ vue - cli3 create project ERROR: ERROR command failed: NPM install - loglevel ERROR - registry=https://registry.npm.taobao.org - di
{
"useTaobaoRegistry": false,
"presets": {
"jeskson": {
"useConfigFiles": true,
"plugins": {
"@vue/cli-plugin-babel": {},
"@vue/cli-plugin-typescript": {
"classComponent": true,
"useTsWithBabel": true
},
"@vue/cli-plugin-router": {
"historyMode": true
},
"@vue/cli-plugin-vuex": {},
"@vue/cli-plugin-eslint": {
"config": "base",
"lintOn": [
"save"
]
},
"@vue/cli-plugin-unit-mocha": {},
"@vue/cli-plugin-e2e-cypress": {}
},
"vueVersion": "2",
"cssPreprocessor": "dart-sass"
}
},
"packageManager": "yarn"
}
Copy the code
[Error: unable to get local issuer certificate while running yarn command]
Yarn config set "strict-ssl" false -g $yarn config list yarn config v1.22.11 info yarn config {'version-tag-prefix': 'v', 'version-git-tag': true, 'version-commit-hooks': true, 'version-git-sign': false, 'version-git-message': 'v % s',' init - version ':' 1.0.0 ', 'init - license' : 'MIT', 'save - the prefix' : '^', 'bin - links: true,' ignore - scripts: false, 'ignore-optional': false, registry: 'https://registry.npm.taobao.org', 'strict-ssl': false, 'user-agent': 'yarn/ 1.22.11npm /? Node /v14.17.3 win32 x64', lastUpdateCheck: 1632822666163} info NPM config {cache: 'C:\\vue\\node_cache', prefix: 'c:\\vue\\node_global', ca: [ '' ], 'strict-ssl': false, registry: 'https://registry.npm.taobao.org/', a get: 'registry'} the Done in 0.16 s.Copy the code
npm config set registry https://registry.npm.taobao.org
$ yarn config get registry
https://registry.npmjs.org
Copy the code
NPM I options -global, -save, -save-dev
-global: short -g NPM I express-g Indicates the global installation. In this case, you can directly use the express command. Otherwise, the system displays a message indicating that the Express command is not an internal or external command. -save-dev: -d to add devDependencies to the package.json dependencies field, so that you do not need to manually modify package.jsonCopy the code
~ and ^ versions
"DevDependencies ": {"vue": "~2.2.2", "vue": {"vue": "~2.2.2"; "^2.2.0" // latest large version, all 2.x.x but not 3.0.0, equivalent to 2.0.0 <= version < 3.0.0}Copy the code
NPM usage and parameter configuration are introduced in detail
Javascript.ruanyifeng.com/nodejs/npm….
Vue-cli-service serve starts a development server (based on [webpack-dev-server]) with hot-module-replacement out of the box.
Use the [devServer] field in vue.config.js to configure the development server.
Vue-cli-service build will produce a production-ready package in the dist/ directory, with JS/CSS/HTML compression, and automatic Vendor Chunk splitting for better caching. Its Chunk manifest will be inline in HTML.
@vue/cli-plugin-eslint injects the vue-cli-service lint command
Caching and parallel processing
cache-loader
Vue/Babel/TypeScript compilation is enabled by default. The file will be cachednode_modules/.cache
If you run into compilation problems, delete the cache directory first and try again.thread-loader
Turns on Babel/TypeScript translation on machines with multi-core cpus.
Git Hook
After installation, @vue/cli-service will also install [Yorkie], which lets you easily specify Git hooks in the Package. json gitHooks field:
{
"gitHooks": {
"pre-commit": "lint-staged"
},
"lint-staged": {
"*.{js,vue}": [
"vue-cli-service lint",
"git add"
]
}
}
Copy the code
Browser compatibility
browserslist
You’ll find a browserslist field in package.json (or a separate.browserslistrc file) that specifies the scope of the project’s target browser. This value is used by [@babel/preset-env] and [Autoprefixer] to identify JavaScript features to be translated and CSS browser prefixes to be added.
Polyfill
useBuiltIns: ‘usage’
A default Vue CLI project uses [@vue/babel-preset-app], which uses the @babel/preset-env and browserslist configurations to determine which polyfill the project needs.
By default, it passes [useBuiltIns: ‘usage’] to @babel/preset-env so that it automatically detects needed polyfills based on language features present in the source code. This ensures that the number of polyfills in the final bag is minimized. However, this also means that if one of the dependencies requires a special polyfill, Babel cannot detect it by default.
If you have dependencies that need polyfill, you have several options:
-
If the dependency is written based on a version of ES not supported by the target environment: add it to the [transpileDependencies] option in vue. Config.js. This will both enable syntactic conversion for the dependency and detect polyfill based on usage.
-
If the dependency delivers ES5 code and explicitly lists the required polyfills: you can pre-include the required polyfills using the [polyfills] option of @vue/babel-preset-app. Note that es. Promises will be included by default, because it is now quite common for libraries to rely on promises.
// babel.config.js
module.exports = {
presets: [
['@vue/app', {
polyfills: [
'es.promise',
'es.symbol'
]
}]
]
}
Copy the code
- If the dependency delivers ES5 code but uses ES6+ features and does not explicitly list the required polyfill (e.g. Vuetify) : Use useBuiltIns: ‘entry’ then add import ‘core-js/stable’ to the entry file; import ‘regenerator-runtime/runtime’; . This imports all polyfills based on the Browserslist target, so you don’t have to worry about dependent polyfills anymore, but the final package size may increase because you include some unused polyfills.
Polyfills when building libraries or Web components
When using the Vue CLI to [build a library or Web Component], it is recommended to pass useBuiltIns: false to @vue/babel-preset-app. This ensures that your libraries or components do not contain unnecessary polyfills. In general, packing polyfills should be the responsibility of the application that ultimately uses your library.
Modern mode
With Babel we can take care of all the latest ES2015+ language features, but it also means we need to deliver translated and polyfilled packages to support older browsers. These translated packages are generally wordier and slower than native ES2015+ code. Most modern browsers now support native ES2015, so it’s a waste of time to deliver clunky code to support older browsers.
Vue CLI provides a “modern mode” to help you solve this problem. Build in the production environment using the following command:
vue-cli-service build --modern
Copy the code
Vue CLI produces two versions of the application: a modern package for modern browsers that support [ES Modules], and an older package for older browsers that don’t.
- The modern version of the package will pass
<script type="module">
Loading in supported browsers; They’ll still be used<link rel="modulepreload">
Preloading. - Older packages will pass
<script nomodule>
Load, and is ignored by browsers that support ES Modules. - One for Safari 10
<script nomodule>
The fixes are automatically injected.
The modern package is 16% smaller for a Hello World application. In production environments, modern packages typically show significant parsing speed and computation speed to improve application load performance.
HTML
The Index file
The public/index.html file is a template that is processed by [html-webpack-plugin]. During the build process, resource links are injected automatically. In addition, the Vue CLI automatically injects resource hints (preload/prefetch, manifest, and icon links (when using the PWA plug-in) as well as resource links to JavaScript and CSS files handled during the build process.
The interpolation
Since the index file is used as a template, you can insert content using the [Lodash template] syntax:
<%= VALUE %>
Used to do unescaped interpolation;<%- VALUE %>
Used to do HTML escape interpolation;<% expression %>
Used to describe JavaScript flow control.
In addition to [default values exposed by htML-webpack-plugin], all [client environment variables] can also be used directly. For example, the use of BASE_URL:
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
Copy the code
Preload
[ ] is a resource hint that specifies the resource that will be used soon after the page loads, so we want to preload the page as early as possible before the browser starts rendering the body.
By default, a Vue CLI application automatically generates preload prompts for all files required for initial rendering.
These hints are injected by [@vue/preload-webpack-plugin] and can be modified and removed via the config.plugin(‘preload’) of chainWebpack.
Prefetch
[ ] is a resource hint that tells the browser to use the idle time after the page has loaded to get what the user is likely to access in the future.
By default, a Vue CLI application will automatically generate prefetch prompts for all JavaScript files generated as Async Chunks (products of on-demand code splitting via dynamic import())).
These hints are injected by [@vue/preload-webpack-plugin] and can be modified and removed via the config.plugin(‘prefetch’) of chainWebpack.
Example:
// vue.config.js module.exports = { chainWebpack: Config => {// Remove the prefetch plugin config.plugins.delete('prefetch') // or // modify its options: config.plugin('prefetch').tap(options => { options[0].fileBlacklist = options[0].fileBlacklist || [] options[0].fileBlacklist.push(/myasyncRoute(.) +? .js$/) return options }) } }Copy the code
When prefetch is disabled, you can manually select the code blocks to fetch early via webpack inline comments:
import(/* webpackPrefetch: true */ './someAsyncComponent.vue')
Copy the code
The webPack runtime injects prefetch links after the parent block is loaded.
prompt
Prefetch links will consume bandwidth. If your application is large and has a lot of Async chunks and users are mainly on bandwith-sensitive mobile, you may need to turn off the Prefetch link and manually select the code blocks to fetch ahead of time.
Don’t generate the index
When using the Vue CLI based on an existing backend, you may not need to generate index.html so that the generated resources can be used for a server-side rendered page. To do this, add the following code to [vue.config.js] :
Exports = {var. Config.js module.exports = {var. Config.js module.exports = {var. Exports = {var. config => { config.plugins.delete('html') config.plugins.delete('preload') config.plugins.delete('prefetch') } }Copy the code
However, this is not recommended because:
- Hard-coded file names are not conducive to efficient cache control.
- Hard-coded filenames also don’t do well with code-splitting, because you can’t generate additional JavaScript files with changing filenames.
- Hard – coded file names do not work in modern mode.
You should consider using the [indexPath] option instead to use the generated HTML as a view template for a server-side framework.
Working with static Resources
Static resources can be processed in two ways:
- Is imported in JavaScript or referenced in a relative path in template/CSS. Such references are handled by Webpack.
- Placed in the
public
Directory or through an absolute path. Such resources will be copied directly without being processed by Webpack.
Import from relative paths
When you use relative paths in JavaScript, CSS, or *.vue files (must start with. When a static resource is referenced, it will be included in the dependency diagram of the Webpack. During its compilation, all such as
For example, the URL (./image.png) would be translated as require(‘./image.png’) instead:
<img src="./image.png">
Copy the code
Will compile to:
h('img', { attrs: { src: require('./image.png') }})
Copy the code
Internally, we use file-loader to determine the final file path with the version hash value and the correct common base path, and use URl-loader to inline resources less than 4KB to reduce the number of HTTP requests.
You can adjust the size limit of inline files with [chainWebpack]. For example, the following code sets its limit to 10KB:
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('images')
.use('url-loader')
.loader('url-loader')
.tap(options => Object.assign(options, { limit: 10240 }))
}
}
Copy the code
URL Translation rules
-
If the URL is an absolute path (e.g. /images/foo.png), it will be left unchanged.
-
If the URL begins with a., it is interpreted as a relative module request and resolved based on the directory structure in your file system.
-
If the URL begins with ~, anything after that will be parsed as a module request. This means you can even reference resources in Node modules:
<img src="~some-npm-package/foo.png">
Copy the code
- If the URL to
@
Initially, it will also be resolved as a module request. It is useful because the Vue CLI sets a point by default<projectRoot>/src
The alias@
.(Only used in templates)
Vue CLI projects naturally support [PostCSS], [CSS Modules] and preprocessors including [Sass], [Less], and [Stylus].
Webpack related
// vue.config.js module.exports = { configureWebpack: Config => {if (process.env.node_env === 'production') {// Modify configuration for production environment... } else {// Modify the configuration for the development environment... }}}Copy the code
Schemas are an important concept in the Vue CLI project. By default, a Vue CLI project has three modes:
development
Pattern is used tovue-cli-service serve
test
Pattern is used tovue-cli-service test:unit
production
Pattern is used tovue-cli-service build
和vue-cli-service test:e2e
Vue environment variables that exist when the CLI is started have the highest priority and are not overwritten by the. Env file.
The. Env environment file is loaded by running vue-cli-service, so if the environment file changes, you need to restart the service.
vue-cli-service build
Will load the possible.env
,.env.production
和.env.production.local
The file then builds the production application.vue-cli-service build --mode staging
Any that may exist will be loaded in staging mode.env
,.env.staging
和.env.staging.local
The file then builds the production application.
You can calculate environment variables in the vue.config.js file. They still need to start with the VUE_APP_ prefix. This can be used for version information:
process.env.VUE_APP_VERSION = require('./package.json').version
module.exports = {
// config
}
Copy the code
A variable that is valid only locally
Sometimes you may have variables that you shouldn’t commit to the repository, especially if your project is hosted in a public repository. In this case you should use an.env.local file instead. Local environment files are ignored by default and appear in.gitignore.
.local can also be added to environment files in a specified mode, such as.env.development.local will be loaded in development mode and ignored by Git.
The easiest way to build in a local preview production environment is to use a Node.js static file server
NPM install -g serve # -s install -g serve # -s install -g serve # -s install -g serve # -sCopy the code
Deploy VuePress to GitHub Pages
Initialize the local project to install VuePress as a local dependency:
My-vuepress CD my-vuepress NPM init -y # install vuepress as a local dependency yarn add -d vuepress # NPM install -d vuepress # create markdown file echo '# Hello vuepress! ' > docs/README.mdCopy the code
Next, add some scripts to package.json:
{
"scripts": {
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs",
"deploy-gh": "GH=1 yarn docs:build && bash scripts/deploy-gh.sh"
}
}
Copy the code
Run the local development environment:
Or: NPM run docs:devCopy the code
Or build an online static file:
Yarn docs:build # or NPM run docs:buildCopy the code
Configure the correct base in docs/.vuepress/config.js.
module.exports = {
title: "My Blog",
description: "This is a blog.",
base: '/blog/'
}
Copy the code
Create the my-vuepress/scripts/deploy-gh.sh script
#! /usr/bin/env sh # Make sure the script throw encountered error set -e # generate static file NPM run docs:build # enter generated folder CD docs/.vuepress/dist # if published to custom domain name # echo 'www.example.com' > CNAME git init git add -a git commit -m 'deploy' # https://<USERNAME>.github [email protected]:<USERNAME>/<USERNAME>.github. IO. Git master # If published to https://<USERNAME>.github [email protected]:<USERNAME>/<REPO>. Git master:gh-pages # replace <USERNAME> with your Github USERNAME, <REPO> with your repository name. git push -f [email protected]:wtyqer/blog.git master:gh-pages cd -Copy the code
Execute the script to deploy:
Yarn deploy-gh # or: NPM run deploy-ghCopy the code
Installation node. Js
Liverpoolfc.tv: nodejs.org/en/download…
History: nodejs.org/en/download…
Do not install node on the system disk (such as C 🙂
In the nodeJS installation directory, create the node_global and node_cache folders
Set the nodeJS prefix (global) and cache (cache) paths
$ npm config get registry https://registry.npm.taobao.org/ $ cnpm config get registry https://registry.nlark.com/ $ yarn config get registry https://registry.npm.taobao.orgCopy the code
Install CNPM based on Node.js (Taobao Image)
npm install -g cnpm --registry=https://registry.npm.taobao.org
Copy the code
Example Modify the system variable PATH
Added the system variable NODE_PATH
baseUrl
Deprecated since Vue CLI 3.3, use [publicPath]
publicPath
-
Type:
string
-
Default:
'/'
The base URL when deploying the application package.
outputDir
-
Type:
string
-
Default:
'dist'
Directory of the production environment build file generated when vue-cli-service build is run. Note that the target directory is cleared before building (passing –no-clean at build time turns this behavior off).
assetsDir
-
Type:
string
-
Default:
''
The directory (relative to outputDir) where generated static resources (JS, CSS, IMG, fonts) are placed.
indexPath
-
Type:
string
-
Default:
'index.html'
Specify the output path of the generated index.html (relative to outputDir). It could be an absolute path.
pages
Module. exports = {pages: {index: {// page entry: 'SRC /index/main.js', // template source template: 'public/index.html', // in dist/index.html output filename: 'index.html, / / when using title option, / / title of the template tag needs to be < title > < % = htmlWebpackPlugin. Options. The title % > < / title > title: 'Index Page', // Blocks contained in this Page will by default contain generic chunks and Vendor chunks extracted by //. chunks: ['chunk-vendors', 'chunk-common', 'index']}, // If entry only string formats are used, // templates are inferred to 'public/subpage.html' // and if not found, Go back to 'public/index.html'. // The output file name is derived to 'subpage.html'. subpage: 'src/subpage/main.js' } }Copy the code
lintOnSave
- Type:
boolean
|'warning'
|'default'
|'error'
- Default:
'default'
Set the browser overlay to display both warnings and errors:
// vue.config.js
module.exports = {
devServer: {
overlay: {
warnings: true,
errors: true
}
}
}
Copy the code
Eslint-loader is enabled under both development and production builds when lintOnSave is a truthy value. If you want to disable eslint-Loader for production builds, you can use the following configuration:
// vue.config.js module.exports = { lintOnSave: process.env.NODE_ENV ! == 'production' }Copy the code
transpileDependencies
-
Type:
Array<string | RegExp>
-
Default:
[]
By default, babel-loader ignores all files in node_modules. If you want to explicitly translate a dependency through Babel, you can list it in this option.
productionSourceMap
-
Type:
boolean
-
Default:
true
If you don’t need the source map for your production environment, set it to false to speed up your production build.
configureWebpack
-
Type:
Object | Function
If the value is an object, it is merged into the final configuration by [webpack-merge].
If the value is a function, the parsed configuration is accepted as an argument. This function can either modify the configuration and return nothing, or it can return a cloned or merged version of the configuration.
chainWebpack
-
Type:
Function
Is a function that takes a Webpack-chain-based ChainableConfig instance. Allows for more fine-grained changes to the internal WebPack configuration.
Devserver.proxy can be a string pointing to the development environment API server:
module.exports = {
devServer: {
proxy: 'http://localhost:4000'
}
}
Copy the code
module.exports = {
devServer: {
proxy: {
'/api': {
target: '<url>',
ws: true,
changeOrigin: true
},
'/foo': {
target: '<other_url>'
}
}
}
}
Copy the code
In a normal Webpack configuration, multiple preprocessors can be used at the same time.
module.exports = { // ... module: { rules: [{ test: /.less$/, use: ['style-loader', 'less-loader', 'less-loader', { loader: 'style-resources-loader', options: { patterns: Path. resolve(__dirname, 'path/to/ SCSS /variables/*.less'), path.resolve(__dirname, variables/*.less') 'path/to/SCSS mixins / *. Less')], injector: 'append / / if the configuration is after the style file to import and visit}}}}]], / /... }Copy the code
pluginOptions
-
Type:
Object
This is an object that does not perform any schema validation, so it can be used to pass any third-party plug-in options. Such as:
Module. Exports = {pluginOptions: {foo: {/ / plug-in can be used as a ` options. PluginOptions. Foo ` access these options. }}}Copy the code
The Style resource handler injects content into the style resource and imports CSS/sass/SCSS/less/stylus
The main role
Import common style files such as variables/mixins/functions instead of manually importing @import in each style file
The same origin policy of the browser
The two pages have the same protocol, host, and port number
Access-control-allow-origin is a cross-domain request
Cross-domain solution in VUE: configure the vue.config.js file, or create one yourself if you don’t have one
Principle:
- Send the domain name to the local server localhost:8080
- The local server then requests the real server
- Since the request is made from the server, there is no cross-domain problem
Service restart is required to modify the vue.config.js file
Module. exports = {devServer: {// cross-domain proxy: {'/ API ': {// target path: 'https://www.bilibili.com/', / / allow cross-domain changeOrigin: true, / / the path pathRewrite: {' ^ / API ':'}}}}}Copy the code
Front-end engineering, modular, componentization, automation, standardization
The so-called front-end engineering, IN my opinion, is to analyze, organize and construct front-end projects as a system engineering so as to achieve the purpose of clear project structure, clear division of labor, tacit team cooperation and improved development efficiency.
Templating is the separation of code and resources at the file level. It is to split a large file into interdependent small files, and then unified assembly and loading.
“Let the machine do the simple and repetitive work”, automation means that there are many automation tools (GLUP, Webpack) to replace us to complete, such as continuous integration, automated construction, automated deployment, automated testing and so on.
Directory structure formulation, coding specification, front and back end interface specification, documentation specification, component management, code package management (SVN, Git), COMMIT code remarks description specification, periodic codeReview, visual icon specification
If you prefer class-based apis when declaring components, you can use the officially maintained [vue-class-Component] decorator:
Import Vue from 'Vue' import Component from 'vue-class-component' // @Component modifiers indicate that this class is a Vue Component @Component({// Template: '< button@click ="onClick"> click! </button>'}) export default class MyComponent extends Vue {// The property message: string = 'Hello! '// Component methods can also be declared directly as instance methods onClick (): void {window.alert(this.message)}}Copy the code
[Enhanced type to match plugin use]
TypeScript has a feature that complements existing types called module supplement.
Declare an instance of string property $myProperty:
// 1. Make sure to import 'vue' import vue from 'vue' before declaring supplementary types // 2. Declare Module 'vue/types/vue' {// 3. Declare module 'vue/types/vue' { Interface Vue {$myProperty: string}}Copy the code
After you include the above code as a declaration file in your project (like my-property.d.ts), you can use $myProperty on Vue instances.
Var vm = new Vue() console.log(vm.$myProperty) // Will compile successfullyCopy the code
You can also declare additional property and component options:
Import Vue from 'Vue' Declare Module 'Vue /types/ Vue' {// You can use the 'VueConstructor' interface // to declare global property interfaces VueConstructor { $myGlobal: Declare Module 'vue/types/options' {interface; // ComponentOptions declare Module 'vue/types/options' {interface; // ComponentOptions declare module 'vue/types/options' {interface ComponentOptions<V extends Vue> { myOption? : string } }Copy the code
This declaration allows the following code to compile smoothly:
Var vm = new Vue({myOption: 'Hello'}) var vm = new Vue({myOption: 'Hello'})Copy the code
[Annotation return value]
Because Vue declaration files are inherently circular, TypeScript can have trouble inferring the type of a method. Therefore, you may need to label the return value on methods in Render or computed.
import Vue, { VNode } from 'vue' const Component = Vue.extend({ data () { return { msg: 'Hello' } }, methods: {// Greet (): string {return this. MSG + 'world'}}, computed: {// Greeting (): string { return this.greet() + '! '}}, // 'createElement' is derivable, but 'render' requires the type render (createElement): VNode { return createElement('div', this.greeting) } })Copy the code
If you find that type derivation or member completion is not working, annotating a method may help you solve the problem. Using the –noImplicitAny option will help you find these unlabeled methods.
[note Prop]
import Vue, { PropType } from 'vue' interface ComplexMessage { title: string, okMessage: string, cancelMessage: string } const Component = Vue.extend({ props: { name: String, success: { type: String }, callback: { type: Function as PropType<() => void> }, message: { type: Object as PropType<ComplexMessage>, required: true, validator (message: ComplexMessage) { return !! message.title; }}}})Copy the code
Jest
Jest is a JavaScript testing framework that focuses on simplicity. One unique feature is the ability to generate snapshots for tests to provide another way to validate application units.
Mocha
Mocha is a JavaScript testing framework that focuses on flexibility. Because of its flexibility, it allows you to choose different libraries to satisfy other common features such as listening (such as Sinon) and assertions (such as Chai). Another unique feature of Mocha is that it can run tests not only in Node.js, but also in the browser.
Vue Testing Library (@testing-library/vue)
The Vue Testing Library is a set of tools that focus on Testing components without relying on implementation details. Because it was designed with accessibility in mind, it also uses a solution that makes refactoring easy.
Its guiding principle is that the more tests that are used in a similar way to the software, the more credibility they provide.
Vue Test Utils
Vue Test Utils is an official low-level component Test library written to provide users with access to vUe-specific apis. If you are not familiar with Testing Vue applications, you are advised to use the Vue Testing Library, which is an abstraction of Vue Test Utils.
[End-to-end (E2E) Testing]
End-to-end testing verifies all layers in the application. This includes not only your front-end code, but all the associated back-end services and infrastructure that are more representative of the environment in which your users live. End-to-end testing is often key to improving confidence that an application is working properly by testing how user actions affect the application.
An end-to-end testing framework commonly used in the vue.js ecosystem
Cypress.io
Cypress.io is a testing framework designed to increase developer productivity by enabling developers to reliably test their applications while providing a first-class developer experience.
Nightwatch.js
Nightwatch.js is an end-to-end testing framework for testing Web applications and websites, as well as Node.js unit testing and integration testing.
Puppeteer
Puppeteer is a Node.js library that provides a high-level API to control the browser and can be paired with other test runners (such as Jest) to test applications.
TestCafe
TestCafe is an end-to-end Node.js framework designed to provide a simple setup so developers can focus on creating tests that are easy to write and reliable.
Add instance Property
You may use data/utilities in many components, but you don’t want to contaminate the global scope. In this case, you can make them available in every instance of Vue by defining them on a prototype.
Vue.prototype.$appName = 'My App'
Copy the code
This makes $appName available to all Vue instances, even before the instance is created. If we run:
new Vue({
beforeCreate: function () {
console.log(this.$appName)
}
})
Copy the code
The console will print out My App. It’s that simple!
[When not using a modular system]
Object. Freeze, which does what it does to prevent this Object from being modified in the future.
SVG icon System
Github.com/sdras/vue-s… .
[Displaying source code in a browser]
Devtool property in vue.config.js:
module.exports = {
configureWebpack: {
devtool: 'source-map'
}
}
Copy the code
[Vue Devtools]
Provides a time travel debugging experience for Vuex.
Memory leaks in Vue applications are usually not the result of the Vue itself, but occur more when other libraries are integrated into the application.
When a keep-alive component is wrapped around it, its state is preserved and therefore left in memory.
When you wrap a component with keep-alive, its state is preserved and therefore remains in memory.
<button @click="show = false">Hide</button> <keep-alive> <! -- '<my-component>' --> <my-component v-if="show"></my-component> </keep-alive>Copy the code
This technique can be used to improve the user experience.
Activated and deactivated
Deactivated: function () {// Remove any data that you don't want to keep}Copy the code
Client storage
localStorage.name = this.name;
Copy the code
Never give up
v-if
和v-for
It applies to the same element.
We tend to do this in two common situations:
- To filter items in a list (e.g
v-for="user in users" v-if="user.isActive"
). In this case, pleaseusers
Replace it with a calculated property (e.gactiveUsers
) to return the filtered list. - To avoid rendering lists that should be hidden (e.g
v-for="user in users" v-if="shouldShowUsers"
). In this case, pleasev-if
Move to a container element (e.gul
,ol
).
The component’s
data
It has to be a function.
When a data property is used in a component (anywhere but new Vue), its value must be a function that returns an object.
When the value of data is an object, it is shared between all instances of the component.
Prop definitions should be as detailed as possible.
In your submitted code, the definition of prop should be as detailed as possible, or at least specify its type.
There are two benefits:
- They specify the API of the component, so it is easy to understand how to use the component.
- In a development environment, if an ill-formed prop is supplied to a component, Vue will alert you to help you catch potential sources of error.
Always use
key
Cooperate withv-for
.
Set scope for component style
Components that should only have a single active instance should haveThe
Prefix names to show that they are unique.
components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
Copy the code
components/
|- SearchSidebar.vue
|- SearchSidebarNavigation.vue
Copy the code
<! -- In single-file components, string templates, and JSX --> <MyComponent/>Copy the code
<! <my-component></my-component>Copy the code
<! -- in single-file components and string templates --> <MyComponent/>Copy the code
<! <my-component></my-component>Copy the code
or
<! <my-component></my-component>Copy the code
Vue.component('MyComponent', {
// ...
})
Copy the code
Vue.component('my-component', {
// ...
})
Copy the code
import MyComponent from './MyComponent.vue'
Copy the code
export default {
name: 'MyComponent',
// ...
}
Copy the code
props: {
greetingText: String
}
Copy the code
<WelcomeMessage greeting-text="hi"/>
Copy the code
<img
src="https://vuejs.org/images/logo.png"
alt="Vue Logo"
>
Copy the code
<MyComponent
foo="a"
bar="b"
baz="c"
/>
Copy the code
Element selectors should be avoided in
scoped
In the.
In the Scoped style, class selectors are better than element selectors because element selectors are slow to use in large quantities.
❤️ follow + like + favorites + comments + forward ❤️, original is not easy, encourage the author to create better articles
Likes, favorites and comments
I’m Jeskson, thanks for your talent: likes, favorites and comments, and we’ll see you next time! ☞ Thank you for learning with me.
See you next time!
Star: github.com/webVueBlog/…