As the company's front-end began to turn to Vuejs, recently began to use the framework for development, encountered some problems recorded, for later use.
Mainly write some official manuals do not write, but the actual development will encounter problems, need a certain knowledge base.
Technology stack involved
- Cli:vue-cli
- Ui:element
- Html:pug (Jade)
- Css:less
- Javascript:es6
Polyfill and Transform-runtime
First of all, vue-cli for us to automatically add babel-plugin-transform-runtime this plugin, the plug-in in most cases is working normally, you can convert most of the ES6 syntax.
However, there are two issues:
1. Polyfill code redundancy is generated when components are loaded asynchronously
2, does not support the global function and the instance method Polyfill
Both of these problems are attributed to the fact that Babel-plugin-transform-runtime uses a sandbox mechanism to compile our code (that is, the built-in objects that do not modify the hosting environment).
Since the asynchronous component will eventually be compiled into a separate file, even if the same new feature is used in multiple components (for example: Object.keys ()), there will be a copy of the new feature's Polyfill in each compiled file. If the project is small you can consider not using asynchronous loading, but the pressure on the first screen will be larger.
does not support global functions (such as: Promise, set, map), set and map of the two data structures should be used by everyone, not much, the impact is small. But the impact of Promise may be bigger.
Instance methods are not supported (e.g. ' ABC '. Include (' B '), [' 1 ', ' 2 ', ' 3 '].find ((n) = n < 2), and so on), and this restriction almost wastes the new features of most strings and about half of the array.
In
General, Babel-plugin-transform-runtime can meet most of the requirements, when the need is not met, it is recommended to use the full babel-polyfill.
Replace Babel-polyfill
First, remove the babel-plugin-transform-runtime from the project
Uninstall this dependency:
npm un babel-plugin-transform-runtime -D
Modifying the Babel configuration file
// .babelrc{ //... "plugins": [ // - "transform-runtime" ] //...}
Then, install Babel-polyfill dependencies:
npm i babel-polyfill -D
Finally, import in the portal file
// src/main.jsimport ‘babel-polyfill‘
ES6 Import Reference Issue
In ES6, the import and export of the module system is a reference export and import (non-simple data type), that is, if an object is defined in a module and exported, when imported in other modules, the import is actually a variable reference (pointer), if you modify the properties in the object, affect the use of other modules.
Normally, when the system volume is small, we can use Json.parse (json.stringify (str)) to simply and rudely generate a completely new, deep copy of the data object. However, when the components are large and the data objects are highly multiplexed, there is a noticeable performance problem, and we can consider using Immutable.js.
for this reason, when you export a complex data type, you need to be aware of the problems that may arise when multiple components import the same data object when you modify the data. In addition, when a module defines a variable or function, even with let instead of a const, it becomes read-only when imported and cannot be re-assigned, and the effect is equivalent to declaring with a const.
Using Pug and less in Vue
Installation dependencies
Vue uses Vue-loader to automatically determine the required loader based on the lang attribute, so there is no need to configure loader, but it requires a manual installation of dependent dependencies:
npm i pug -Dnpm i less-loader -D
It is also quite handy to add loader without manually modifying the Webpack configuration file to use the
using Pug or Pug-loader? Sass How to set up the loader of two kinds of grammar? ---Please refer to the preprocessor · Vue-loader
Use
<!-- xxx.vue --><style lang="less"> .action { color: #ddd; ul { overflow: hidden; li { float: left; } } }</style><template lang="pug"> .action(v-if=‘hasRight‘) ul li 编辑 li 删除</template><script> export default { data () { return { hasRight: true } } }</script>
Defining global functions or variables
Many times we need to define a number of global functions or variables to handle a number of frequent operations (here is an example of how to handle AJAX exceptions). But in Vue, each single-file component has a separate context (this). Usually in exception handling, need to be reflected in the view, this time we need to access the this object, but the context of the global function is usually a window, then need some special processing.
Simple rough Type
The simplest way is to define a global method directly on the Window object, using Bind, call, or apply to change the context when used within the component.
Define a global exception handling method:
// errHandler.jswindow.errHandler = function () { // 不能使用箭头函数 if (err.code && err.code !== 200) { this.$store.commit(‘err‘, true) } else { // ... }}
Import in the Portal file:
// src/main.jsimport ‘errHandler.js‘ 在组件中使用:// xxx.vueexport default { created () { this.errHandler = window.errHandler.bind(this) }, method: { getXXX () { this.$http.get(‘xxx/xx‘).then(({ body: result }) => { if (result.code === 200) { // ... } else { this.errHandler(result) } }).catch(this.errHandler) } }}
Elegant safety Type
In a large multi-person collaborative project, it is still not appropriate to contaminate the Window object. In particular, some of the more personal features of the global approach (which may be used almost everywhere in the components you write, but may not be necessary for others). At this time, it is recommended to write a module, more elegant and safe, but also more natural, the only disadvantage is that each need to use the function or method of the component needs to be imported.
The use of the same method is similar to the previous one, not much to introduce.  ̄
Custom Path aliases
Some people may have noticed that this syntax was used when importing components in a template generated by VUE-CLI:
import Index from ‘@/components/Index‘
What's this @? Later, when the configuration file was changed, this is one of the configuration options for Webpack: path alias.
We can also add our own path aliases in the base configuration file, such as the following to set the ~ to the alias of Path src/components:
// build/webpack.base.js{ resolve: { extensions: [‘.js‘, ‘.vue‘, ‘.json‘], alias: { ‘vue$‘: ‘vue/dist/vue.esm.js‘, ‘@‘: resolve(‘src‘), ‘~‘: resolve(‘src/components‘) } }}
Then we can write this when we import the components:
// import YourComponent from ‘YourComponent‘// import YourComponent from ‘./YourComponent‘// import YourComponent from ‘../YourComponent‘// import YourComponent from ‘/src/components/YourComponent‘import YourComponent from ‘~/YourComponent‘
Not only solves the problem of long path, but also solves the trouble of relative path, convenient many!
CSS Scopes and modules
In-component styles
Typically, the styles in the labels in the component are global, and when you use a third-party UI library (such as Element), the global style is likely to affect the style of the UI library. We can make the style in the style only work on the current component by adding the scoped property:
<style lang="less" scoped> @import ‘other.less‘; .title { font-size: 1.2rem; }</style>
importing other styles within the style tag with the scoped attribute is also limited to the scope, which becomes the style within the component. A highly reusable style is not recommended for this use. In addition, you should avoid using element selectors within a component's style, because performance is greatly reduced when the element selector is combined with the property selector. ---Test of two combination selectors: Classes selector,elements selector
Import Style
Sometimes we also need to add some global styles, relative to the style used in the scoped property when using the style. Of course we can write a global style with a style that doesn't have a scoped property. However, the following wording is more recommended:
/* 单独的全局样式文件 *//* style-global.less */body { font-size: 10px;}.title { font-size: 1.4rem; font-weight: bolder;}
Then, import the global style in the Portal file:
// src/main.jsimport ‘style-global.less‘
Get form control values
Usually we can bind the form control to the data directly using V-model, but sometimes we also need to get the current value when the user enters it (such as verifying the validity of the current input control content in real time).
At this point we can bind our own handlers with @input or @change events and pass in the $event object to get the input values of the current control:
<input type=‘text‘ @change=‘change($event)‘>
change (e) { let curVal = e.target.value if (/^\d+$/.test(curVal)) { this.num = +curVal } else { console.error(‘%s is not a number!‘, curVal) }}
Of course, if the UI framework takes Element is simpler, its event callbacks pass directly to the current value.
Tips for using v-for
The v-for directive is powerful, and it can be used not only to iterate over arrays, objects, or even to traverse a number or string.
The basic grammar is not spoken, here is a little tips:
Index value
When you use V-for to generate the DOM from an object or an array, you sometimes need to know the current index. We can do this:
<ul> <li v-for=‘(item, key) in items‘ :key=‘key‘> {{ key }} - {{ item }}</ul>
However, when traversing a number, it is important to note that the value of the number starts at 1 and the key starts at 0:
<ul> <li v-for=‘(v, k) in 3‘ :key=‘k‘> {{ k }}-{{ v }} <!-- output to be 0-1, 1-2, 2-3 --></ul>
In
the 2.2.0+ version, key is now required when v-for is used in the component.
Unique root node of the template
As with JSX, a template in a component can have only one root node, which is the wrong way to do this:
<template>
We need to wrap him up with a block-level element:
<template> <div>
reason reference: react-: Component Development Considerations # Unique root node
Project Path ConfigurationSince the VUE-CLI configuration project provides a built-in static server, there is basically no problem during the development phase. However, when we put the code on the server, we often encounter static resource reference errors, resulting in a blank interface problem.
This is because the VUE-CLI default configuration of Webpack is a file referenced at the site root, but sometimes we may need to deploy the project to subdirectories.
We can modify the relative path of a file reference by Config/index.js:
build.assetsSubDirectory: ‘static‘ build.assetsPublicPath: ‘/‘ dev.assetsSubDirectory: ‘static‘ dev.assetsPublicPath: ‘/‘
We can see that both the build and dev in the exported object have both Assetssubdirectory and Assetspublicpath properties.
Where assetssubdirectory refers to the static resource folder, that is, the packaging of JS, CSS, pictures and other files placed in the folder, the default is generally no problem.
Assetspublicpath refers to the reference path of a static resource, the default configuration is/, the Web site root directory, and the assetssubdirectory combination is the complete static resource reference path/static.
It is obvious that the solution is here, as long as you change the root directory to a relative directory:
build.assetsSubDirectory: ‘static‘ build.assetsPublicPath: ‘./‘
That's right! is a. The problem.
The article is still in perfect, welcome to discuss some problems in the development of Vue.js, HA/
Say the collection is many, you are sure the collection will remember to see _
When you read the development, there will be at least one impression, and a good punch card.
Original: Vuejs Development FAQ Collection
https://blog.beard.ink/javascript/vuejs-Development FAQ Highlights/
Vuejs Development FAQ Highlights