Note: this article was originally provided to the company’s development reading, some places do not have to refer to

Understand the project structure

Detailed look atJuejin. Cn/post / 684490…(Includes project structure and Webpack)

If you have vUE basics please skip to the next section

A brief introduction to VUE (core: a system that uses concise template syntax to declaratively render data into the DOM)

Let’s start with an example

<! -- Specify the vUE management content area (within the tag id of app), Everything that needs to be displayed by vUE goes into this element, which is usually called a boundary. The data is only parsed inside the boundary --> <template> <div id="app">{{MSG}}</div> </template> <script> export default { name:'app', data() { return { msg:'hello vue' } }, mounted() { console.log(this.msg) } } </script>Copy the code
  • Declare data in data before using data
    • Data must be defined as a function return value so that the reusable component returns a new copy of data
    • One change makes all changes if you use object form (object is reference type)
  • Data can be accessed through this. MSG in other properties or hook functions

All of the following statements are based on the example above

  • Template syntax (ways to bind data in a page)

    1. V – text = ‘MSG’ or {{MSG}}
      1. How it works: Update the DOM’s textContent
    2. v-html
      1. Do not use V-HTML for input text, which can lead to XSS attacks
      2. How it works: Updates the innerHtml of the DOM
    3. Can use js in the template syntax expression, such as {{MSG. The split (‘ ‘). The reverse () join (‘ ‘)}}
      1. Can only use a single expression, not a JS statement (const a = ‘1’ this is a JS statement)
      2. It is not recommended to use JS expressions in vue files. It is recommended to write to computed properties
  • Attributes bind

    • V-bind :(colon)
    • Use to bind all attributes of the HTML tag (for example :title=’ MSG ‘)
    • Use V-bind to pass values to components (examples in components)
    • The DOM is reacted to when the bound data or expression value changes
    • If the object is bound, it reads the value returned by the object’s toString() method. If the method is not overridden, the binding value is [object object] (Example 1).
    • A colon is a bound variable or variable expression when a property is bound, and an uncolon is a bound string (so colons are also required when passing number and Boolean constants) (Example 2)

Case 1

<script> data() { return { obj:{ name:'yangf' } } } mounted() { obj.toString = function() { return obj.name; } } </script> <template> <! <div :title='obj'></div> <! <div title=[object object]></div> <! Yangf </div> </template>Copy the code

Case 2

<script> data() { return { msg:'hello', num: 5 } } </script> <template> <! <div :title=' MSG ':data='num'></div> <! -- TAB for component --> <! < TAB :num='5' :title="'hello'"></ TAB ></ template>Copy the code
  • Binding approach

    • V-on, grammar sugar @
    • For adding events, bound events are written to the Methods object
    • V-on :click=’clickBtn’ or V-on :click=’clickBtn(‘ parameter ‘,$event)’ or @click=’clickBtn’
    • V-on can listen for multiple methods
    <input type="text" v-on="{input:onInput,focus:onFocus}">
    Copy the code
    • You can add the keyboard event @keyup.13=”submit” the same as @keyup.enter=”submit”
    • Event modifier
      • .stop to stop bubbling, call event.stopPropagation()
      • .prevent prevents default behavior, call event.preventDefault()
      • .capture Uses event capture mode when adding event listeners
      • .self Events are emitted only if the event is emitted within the element itself (for example, not a child element)
      • The. Once event is triggered only once
      • Modifier keys (.ctrl, etc.), mouse button modifier (.left, etc.)
  • v-model

    • Create two-way data bindings on form elements (input, Textarea, etc.) (listen for input events to change the data)
    • For languages that require input methods, they are not updated while the input method combines text
    • Decorator:
      • .lazy is converted to update data after executing the change event using this modifier
      • .number Automatically converts user input values to numeric types
      • . Trim Automatically filters the first and last Spaces entered by users

V-models are just syntactic sugar, with different input elements using different properties and throwing different events

  1. Text and Textarea elements use value property and input events
  2. Checkbox and Radio use checked Property and change events
  3. The SELECT field takes value as prop and change as an event
<input v-bind:value=" MSG "v-on:input=" MSG = $event.target.value" />Copy the code
  • v-for

    • Loop over arrays or objects
    • You are advised to add the key attribute
      • Vue defaults to the “update in place” principle and reuses existing elements. If the order of data items changes, VUE will not move DOM elements to match the order of data items
      • With keys, VUE rearranges elements based on key changes and removes elements where the key does not exist.
      • The sameNode function a. keey === B. Keey can be compared with the sameNode function a. keey === B
      • Faster: Using the uniqueness of keys to generate map objects to obtain corresponding nodes, faster than traversal
  • V – if and v – show

    • V-if destroys or rebuilds elements based on whether the value of the expression is true or false. Higher switching overhead; An expression with an initial value of false will not render the tag
    • V-show: Toggles the display CSS property of an element based on whether the expression is true or false. There is a higher initial rendering overhead and the expression is initially rendered regardless of whether it is true or false
  • Style handling -class and style

    • v-bind:class=”expression” or :class=”expression”
    • Expression is a string, array, or object
<! -- 1 --> <div v-bind:class="{ active: true }"></div> <! <div class="active"></div> <! -- 2 --> <div :class="['active', 'text-danger']"></div> <! - resolved -- > < div class = "active text - danger" > < / div > <! -- 3 --> <div v-bind:class="[{ active: true }, errorClass]"></div> <! <div class="active text-danger"></div>Copy the code
  • Listener and compute properties

    • watch
      • Watch is usually written as an object, where the key is the expression to be observed and the value is the corresponding callback function
      • No cache. When the value of the expression changes, the corresponding callback function will be called to complete the monitoring operation of the response
      • Watch supports asynchrony;
      • The function takes two arguments, the first being the latest value; The second argument is the value before input;
      • The listening data must be the data declared in data or passed in props by the parent component
        • The data in props passed by the parent component is not allowed to change
      • It is best not to listen for the entire object, but for a property within the object
data() { return { a:1, person:{ age:18 } } }, watch:{ a: Function (val, oldVal) {console.log(' current value: '+ val,' old value: ') {function(val, oldVal) {console.log(' current value: '+ val,' old value: ' }, // add this listener to all attributes of the object, but the performance overhead is too high // Any modification of any attribute in obj will trigger handler person in this listener: Immediate: true, handler: function (val, oldVal) {/*... 'person. Age ': {immediate: true, handler: function (val, oldVal) {/*... * /}}}Copy the code
  • computed

    • Computed properties are cached based on their dependencies and reevaluated only if its dependencies change
    • Do not put too much logic into the template syntax, which will make the template too heavy, difficult to understand, and maintain
    • Attributes in computed cannot have the same name as attributes in data, or an error will be reported
  • Components by value

    • Parent component to child component
      • Passed through the props property of the subcomponent
        • Props can be an array (specifying the name of the property passed in)
        • It can also be an object (a property passed in can specify a default value, whether it is required, etc.)
      • Component property values passed in from the parent must be specified in the component via the PROPS property display
      • The use of the props property passed is the same as the use of the data property
      • Parent values use the V-bind binding property
    • Child components pass values to parent components
      • Custom events are emitted via $emit() in the child component
      • The parent receiver uses the V-ON binding method
    • A V-Model on a component makes use of a prop named Value and an event named Input by default
      • Because of the bidirectional binding, no additional events need to be bound on the parent page

      • But input controls like checkboxes, checkboxes, and so on May use value for different purposes

      • Use model options in the component to avoid such conflicts

      • The following (first method) and (second method) are used for example

      • You can attach attrs to the middle layer component without adding props and attrs to the middle layer component, without adding props and attrs to the middle layer component, and without adding props and emit to the middle layer component

    <router-view  v-bind="$attrs"/>
    Copy the code

Examples (there are many ways to pass values to components, these two are the most commonly used, so just props and emit are listed)

Export default {name: 'component-tab ', // to implement bidirectional binding model: {prop: 'checked', event: 'change'}, // Subcomponents need to receive parameters :{props:{// name of prop in model checked: Boolean,// (second method) dataList:{type: Array, default: function () { return []; }, required: true }, changeType:{ type:String, default:'scree' }, activeItem:{ type:Object, default:function () { return {}; }}, // In the parent component using v-model, in the child component can use value (the first method) value: {type:String, default: ""}}, // Need to change to define, Do not need to change can directly use props the value of the data () {return {langTabData: enclosing dataList, curActiveItem: enclosing activeItem, tabBtn: false, // Index activeIndex of the currently selected item :0}; }, methods: {// In the parent component passed with v-model, ChangeBtn () {this.$emit('input', this.activeIndex)}; // The name of the event value in the model, ChangeBtn1 () {this.$emit('change', this.activeIndex)}}}; <div class="fd-page-box"> <lang-tab class="fd-tab-box" :dataList="dataList" :activeItem="activeItem" @click="clickTab"></lang-tab> <span v-text="activeItem.key"></span> </div> </template> import tab from "./components/common/tab/index.vue"; export default { name: 'page-tab', components: {TAB}, data() {return {dataList:[{label:' sqycjhxx1', key:'sqycjhxx2'}], ActiveItem :{label:' clickTab(item){this. ActiveItem = item; }}};Copy the code

Vue Tips:

  • Only data in data is responsive; dynamically added data is non-responsive
    • $set(); add attributes to object.assign ();
<script> export default {name:'app', data() {return {obj:{name:' yiyang '}}}, mounted() {obj. Age = '18'; $set(this.obj,'age','18'); // Add multiple attributes using this.obj = object.assign ({}, vm.stu, {age: '18'}); } } </script>Copy the code
  • How to use $nextTick
    • Vue updates the DOM asynchronously to remove duplicate data and avoid unnecessary calculations and repeated DOM operations, so you need to use $nextTick to get the updated DOM data
methods: { getInnerText() { this.msg = 'change'; This.$nextTick(() =>{console.log(' nextTick prints: ', this.$el.children[0]. InnerText); }) console.log(' print directly: ', this.$el.children[0].innertext); }}Copy the code
  • Vue is a one-way data flow. Data is always passed from the parent to the child. The child cannot modify the value passed by the parent, but can only request the parent to modify the original value
    • Using the V-model in a child component to bind the props values passed by the parent component is a non-canonical warning
    • If you want to change the props value of the parent component, you need to define a variable in data. The initial value is the props value
  • Use V-show for frequent switching; Use V-if if conditions rarely change at run time
  • V-if and V-for are not recommended together
    • Vue2.0 resolves V-for first and then V-IF
    • Even if we render only a small number of elements that meet the criteria, we have to traverse the entire list every time we re-render, regardless of whether the criteria have changed

Rerender traverses the entire list, regardless of whether the data that meets the criteria has changed: Vnode (virtual DOM) will be generated after the rander function is executed. When the data changes, Watcher will be triggered to execute the update method, and the render method will be re-executed to generate a new Vnode. Therefore, data need to be traversed again in VUe2. Notify the component which data changes to the component, which node should be updated, need to be compared with the previously generated vNodes (using the diff algorithm)