Vue Day One, Day Two

Posted by Negligence on Sun, 19 May 2019 00:55:34 +0200

I. What is Vue.js

Vue.js: A progressive framework for building user interfaces. The core library of Vue focuses only on the view layer.

Installation: Vue.js provides an official command-line tool that can be used to quickly build large single-page applications. The tool provides out-of-the-box configuration of building tools, bringing modern front-end development processes. It takes only a few minutes to create and start a project with hot overload, save-time static checks, and build configurations that can be used in production environments:

 

# Global Installation vue-cli Global installation vue-cli
$ npm install -g vue-clinpm install -g vue-cli
# Create a new project based on Web pack template Create a base on webpack New project of template
$ vue init webpack my-projectvue init webpack my-project
# Installation Dependency, Go You Installation Dependency, Go You
$ cd my-projectcd my-project
$ npm installnpm install
$ npm run devnpm run dev

Declarative Rendering

 

<div id="app">div id="app">
        {{message}}message}}
    </div></div>
<script>script>
        var app = new Vue({var app = new Vue({
            el:'#app',el:'#app',
            data:{data:{
                message:'Helle Vue'+new Date()message:'Helle Vue'+new Date()
            }
        })
</script>/script>

Be careful:

1. Although the MVVM pattern is not fully followed, the design of Vue is undoubtedly inspired by it. Therefore, the variable name vm (ViewModel abbreviation) is often used to represent Vue instances.

2. Each Vue instance proxies all the attributes in its data object; only those attributes that are proxied are responsive. If new attributes are added to the instance after the instance is created, it does not trigger view updates.

3. Do not use arrow functions in instance attributes or callback functions (such as vm. $watch ('a', newVal => this.myMethod ()). Because the arrow function binds the parent context, this is not a Vue instance as expected, but this.myMethod is undefined.

4. Expressions: They are parsed as JavaScript in the data scope of the Vue instance they belong to. One limitation is that each binding can contain only a single expression.

 

<! - This is a statement, not an expression - > This is a statement, not an expression - >.
{{ var a = 1 }}var a = 1 }}
Flow control will not work either. Please use ternary expression - > Flow control will not work either. Please use ternary expression - > Flow control will not work either.
{{ if (ok) { return message } }}if (ok) { return message } }}

Directives

1. v-text: Update the entire text content of the element. If you want to update part of the content, use the expression {text} to update it.

 

<span v-text="msg"></span>span v-text="msg"></span>
<! - The same as the following - > ____________
<span>{{msg}}</span>span>{{msg}}</span>

 

2,v-html: Update element innerHTML . Note: The content is normal. HTML insert - Not act as Vue Template compilation .


 
  1. <div v-html="html"></div>

3,v-show: Switch elements based on the true or false value of an expression Of display Attribute. This command triggers the transition effect when conditions change.

 

<h1 v-show="ok">Hello!</h1>h1 v-show="ok">Hello!</h1>

4,v-if: Destruction based on the true or false value of the value of the expression/Reconstruction.

5,v-else: No expression required, restriction: the previous sibling element must have v-if or v-else-if

 

<div>div>
    <div v-if="Math.random() > 0.5"><div v-if="Math.random() > 0.5">
      Now you see me
    </div></div>
    <div v-else><div v-else>
      Now you don't
    </div></div>
</div>div>

6,v-else-if: limit: The former sibling element must have v-if or v-else-if. Express v-if " else if Block ". It can be called in a chain.

 

<div v-if="type === 'A'">div v-if="type === 'A'">
  A
</div>div>
<div v-else-if="type === 'B'">div v-else-if="type === 'B'">
  B
</div>div>
<div v-else-if="type === 'C'">div v-else-if="type === 'C'">
  C
</div>div>
<div v-else>div v-else>
  Not A/B/C
</div>div>

7,v-for: Rendering elements or template blocks multiple times based on source data

 

<div v-for="item in items">div v-for="item in items">
  {{ item.text }}
</div>div>

You can also specify an alias for an array index (or a key for an object):

 

<div v-for="(item, index) in items"></div>div v-for="(item, index) in items"></div>
<div v-for="(val, key) in object"></div>div v-for="(val, key) in object"></div>
<div v-for="(val, key, index) in object"></div>div v-for="(val, key, index) in object"></div>

The v-for default behavior tries not to change the whole, but to replace elements. To force elements to reorder, you need to provide a special attribute of key:

 

<div v-for="item in items" :key="item.id">div v-for="item in items" :key="item.id">
  {{ item.text }}
</div>div>

 

8. v-on: Binding event listener, abbreviated as:@

Parameters: Some instructions can accept a "parameter" which is indicated by a colon after the instruction. _

Modifier: A special suffix specified by a half-corner period to indicate that an instruction should be bound in a special way.

  • stop - Calls event.stopPropagation().
  • prevent - Call event.preventDefault().
  • Capture - Use capture mode when adding event listeners.
  • self - Triggers a callback only if the event is triggered from the element itself bound by the listener.
  • {keyCode | keyAlias} - The callback is triggered only when the event is triggered from a particular key.
  • Native - listens for native events of component root elements.
  • once - Triggers only one callback.
  • Left - Triggered only when the left mouse button is clicked.
  • Right - Triggered only when the right mouse button is clicked.
  • Middle - Triggered only when the middle mouse button is clicked.

 

<! - Method Processor - >
<button v-on:click="doThis"></button>button v-on:click="doThis"></button>
<!-- Inline statement -->
<button v-on:click="doThat('hello', $event)"></button>button v-on:click="doThat('hello', $event)"></button>
<!-- Abbreviation -->
<button @click="doThis"></button>button @click="doThis"></button>
<!-- Stop bubbling -->
<button @click.stop="doThis"></button>button @click.stop="doThis"></button>
<!-- Prevent default behavior -->
<button @click.prevent="doThis"></button>button @click.prevent="doThis"></button>
<!-- Prevent default behavior, no expression -->
<form @submit.prevent></form>form @submit.prevent></form>
<!--  Series modifier -->
<button @click.stop.prevent="doThis"></button>button @click.stop.prevent="doThis"></button>
<!-- Key modifier, key alias -->
<input @keyup.enter="onEnter">input @keyup.enter="onEnter">
<!-- Key modifier, key code -->
<input @keyup.13="onEnter">input @keyup.13="onEnter">
<! - Click the callback to trigger only once - >
<button v-on:click.once="doThis"></button>button v-on:click.once="doThis"></button>

9. v-bind: Dynamic binding of one or more features, abbreviated as:

Parameters: Some instructions can accept a "parameter" which is indicated by a colon after the instruction.

 

<! - Bind an attribute - >.
<img v-bind:src="imageSrc">img v-bind:src="imageSrc">
<!-- Abbreviation -->
<img :src="imageSrc">img :src="imageSrc">
<!-- with inline string concatenation -->
<img :src="'/path/to/images/' + fileName">img :src="'/path/to/images/' + fileName">
<!-- class binding -->
<div :class="{ red: isRed }"></div>div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">div :class="[classA, { classB: isB, classC: isC }]">
<!-- style binding -->
<div :style="{ fontSize: size + 'px' }"></div>div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>div :style="[styleObjectA, styleObjectB]"></div>
<!-- Binding an object with attributes -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
<!-- adopt prop Modifier binding DOM attribute -->
<div v-bind:text-content.prop="text"></div>div v-bind:text-content.prop="text"></div>
<!-- prop binding. "prop" Must be my-component China statement. -->
<my-component :prop="someThing"></my-component>my-component :prop="someThing"></my-component>

10. v-model: Create bidirectional bindings on form controls or components.

Modifier:

Lazy: By default, the v-model synchronizes the values and data of the input box in the input event (except for the IME section above), but you can add a modifier lazy, which translates to synchronization in the change event:

 

<! - Update in the "change" rather than "input" event - > ____________.
<input v-model.lazy="msg" >input v-model.lazy="msg" >

.number: Automatically convert user input values to Number Type (if the conversion result of the original value is NaN Returns the original value:

 

<input v-model.number="age" type="number">input v-model.number="age" type="number">

.trim: Filter the first and last blanks of user input:

 

<input v-model.trim="msg">input v-model.trim="msg">

11,v-pre: Skip the compilation of this element and its children

 

<span v-pre>{{ this will not be compiled }}</span>span v-pre>{{ this will not be compiled }}</span>

12,v-cloak: Keep on the element until the associated instance is compiled

 

CSS:
[v-cloak] {
  display: none;
}
HTML:
<div v-cloak>div v-cloak>
  {{ message }}
</div>div>

13. v-once: Render only once.

 

<! - Single element - >
<span v-once>This will never change: {{msg}}</span>span v-once>This will never change: {{msg}}</span>
<!-- Child element -->
<div v-once>div v-once>
  <h1>comment</h1><h1>comment</h1>
  <p>{{msg}}</p><p>{{msg}}</p>
</div>div>
<!-- assembly -->
<my-component v-once :comment="msg"></my-component>my-component v-once :comment="msg"></my-component>
<!-- v-for instructions-->
<ul>ul>
  <li v-for="i in list" v-once>{{i}}</li><li v-for="i in list" v-once>{{i}}</li>
</ul>ul>

IV. FILTERS

Filters can be used in two places: expression interpolation and v-bind expressions, and computational attributes are used if more complex data transformations are to be implemented in other instructions.

 

{{ message | capitalize }}message | capitalize }}
<div v-bind:id="rawId | formatId"></div>div v-bind:id="rawId | formatId"></div>

The filter function always accepts the value of the expression as the first parameter:

 

new Vue({ Vue({
  // ...// ...
  filters: {filters: {
    capitalize: function (value) {capitalize: function (value) {
      if (!value) return ''if (!value) return ''
      value = value.toString()value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)return value.charAt(0).toUpperCase() + value.slice(1)
    }
  }
})

The filter is a JavaScript function, so it can accept parameters:

 

{{ message | filterA('arg1', arg2) }}message | filterA('arg1', arg2) }}

Here, the string 'arg1' The filter is passed as the second parameter. arg2 The value of the expression is evaluated and passed to the filter as the third parameter.

Calculated attribute computed:

 

<div id="example">div id="example">
  <p>Original message: "{{ message }}"</p><p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p><p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>/div>

 

var vm = new Vue({ vm = new Vue({
  el: '#example',el: '#example',
  data: {data: {
    message: 'Hello'message: 'Hello'
  },
  computed: {computed: {
    // a computed getter// a computed getter
    reversedMessage: function () {reversedMessage: function () {
      // `this` points to the vm instance// `this` points to the vm instance
      return this.message.split('').reverse().join('')return this.message.split('').reverse().join('')
    }
  }
})

The value of reversedMessage depends on the value of message. Only when the message changes the reversedMessage method will it be invoked. If the message does not change, the reversedMessage method will not be invoked.

Method attribute methods:

 

<p>Reversed message: "{{ reversedMessage() }}"</p>p>Reversed message: "{{ reversedMessage() }}"</p>

 

// in component
methods: {: {
  reversedMessage: function () {reversedMessage: function () {
    return this.message.split('').reverse().join('')return this.message.split('').reverse().join('')
  }
}

Difference:

We can define the same function as a method rather than a computational property (with caching). For the final result, the two approaches are exactly the same. However, the difference is that computational attributes are cached based on their dependencies. The computed attribute is revalued only when its dependencies change. This means that as long as the message hasn't changed, multiple access to the reversedMessage computational property will immediately return the previous calculation result without having to execute the function again.

Compute setter:

By default, only getter is available, but you can also provide a setter when you need it:

 

computed: {: {
  fullName: {fullName: {
    // getter// getter
    get: function () {get: function () {
      return this.firstName + ' ' + this.lastNamereturn this.firstName + ' ' + this.lastName
    },
    // setter// setter
    set: function (newValue) {set: function (newValue) {
      var names = newValue.split(' ')var names = newValue.split(' ')
      this.firstName = names[0]this.firstName = names[0]
      this.lastName = names[names.length - 1]this.lastName = names[names.length - 1]
    }
  }
}

 

Now when vm. fullName = John Doe is running, setter is called and vm. firstName and vm. lastName are updated accordingly. When vm.fullName ='John Doe', setter is called and vm.firstName and vm.lastName are updated accordingly.

5. Component Application Construction

1. Global Components

 

 Vue.component(tagName, options);Vue.component(tagName, options);

After registration, components can be used in the module of the parent instance in the form of a custom element < my-component > </my-component >. Make sure that components are registered before initializing the root instance:

 

 Vue.component('todo-item',{Vue.component('todo-item',{
        Template: "<li> I am a todo component </li>" template: "<li> I am a todo component </li>"
})
var app = new Vue({ app = new Vue({
        el:"#app"el:"#app"
})

Now you can use it to build another component template:

 

<ol>ol>
  <!-- Create a todo-item Examples of components --><!-- Create a todo-item Examples of components -->
  <todo-item></todo-item><todo-item></todo-item>
</ol>/ol>

2,Partial registration 

 

var Child = { Child = {
  template: '<div>A custom component!</div>'template: '<div>A custom component!</div>'
}
new Vue({ Vue({
  // ...// ...
  components: {components: {
    // < my-component > will only be available in the parent template// < my-component > will only be available in the parent template
    'my-component': Child'my-component': Child
  }
})

Be careful:

(1) Some elements <ul>, <ol>, <table>, <select> limit the elements that can be wrapped by it.

Using these restricted elements in custom components can lead to problems, such as:

 

<table>table>
  <my-row>...</my-row><my-row>...</my-row>
</table>/table>

The alternative is to use special ones. is Properties:

 

<table>table>
  <tr is="my-row"></tr><tr is="my-row"></tr>
</table>/table>

The following restrictions will not apply:

  • <script type="text/x-template">
  • JavaScript Inline template string
  • .vue assembly

(2)data Must be a function

 

<ul id='app'>ul id='app'>
    <li is='simple-counter'></li><li is='simple-counter'></li>
    <li is='simple-counter'></li><li is='simple-counter'></li>
    <li is='simple-counter'></li><li is='simple-counter'></li>
    <li is='simple-counter'></li><li is='simple-counter'></li>
</ul>ul>

 

var app = new Vue({ app = new Vue({
            el:'#app',el:'#app',
            components:{components:{
                'simple-counter':{'simple-counter':{
                    template:"<span @click='add()'>{{counter}}</span>",template:"<span @click='add()'>{{counter}}</span>",
                    data:function(){data:function(){
                        return {return {
                            counter:0counter:0
                        }
                    },
                    methods:{methods:{
                        add:function(){add:function(){
                            this.counter++;this.counter++;
                        }
                    }
                }
            }
        })

3. Father-child Component Communication

(1) Transfer data from parent scope to child components:

 

<div id="app">div id="app">
  <ol><ol>
    <!-- Now we are for each todo-item Providing to-do objects    --><!-- Now we are for each todo-item Providing to-do objects    -->
    <!-- The object of the to-do item is a variable, that is, its content can be dynamic. --><!-- The object of the to-do item is a variable, that is, its content can be dynamic. -->
    <todo-item v-for="item in groceryList" v-bind:todo="item"></todo-item><todo-item v-for="item in groceryList" v-bind:todo="item"></todo-item>
  </ol></ol>
</div>div>

 

Vue.component('todo-item', {.component('todo-item', {
  // The todo-item component now accepts one// The todo-item component now accepts one
  // "prop", similar to a custom property// "prop", similar to a custom property
  // This property is called todo.// This property is called todo.
  props: ['todo'],props: ['todo'],
  template: '<li>{{ todo.text }}</li>'template: '<li>{{ todo.text }}</li>'
})
var app = new Vue({ app = new Vue({
  el: '#app',el: '#app',
  data: {data: {
    groceryList: [groceryList: [
      { text: 'Vegetables' },text: 'Vegetables' },
      { text: 'cheese' },text: 'cheese' },
      { text: 'Whoever else eats' }text: 'Whoever else eats' }
    ]
  }
})
Note: prop is unidirectionally bound: when the attributes of the parent component change, it is passed to the child component, but not vice versa.

 

(2) Pro validation:

 

Vue.component('example', {.component('example', {
  props: {props: {
    // Basic type detection (`null'means any type can be)// Basic type detection (`null'means any type can be)
    propA: Number,propA: Number,
    // Multiple types// Multiple types
    propB: [String, Number],propB: [String, Number],
    // Necessary and String// Necessary and String
    propC: {propC: {
      type: String,type: String,
      required: truerequired: true
    },
    // Numbers, with default values// Numbers, with default values
    propD: {propD: {
      type: Number,type: Number,
      default: 100default: 100
    },
    // The default value of an array/object should be returned by a factory function// The default value of an array/object should be returned by a factory function
    propE: {propE: {
      type: Object,type: Object,
      default: function () {default: function () {
        return { message: 'hello' }return { message: 'hello' }
      }
    },
    // Custom Validation Function// Custom Validation Function
    propF: {propF: {
      validator: function (value) {validator: function (value) {
        return value > 10return value > 10
      }
    }
  }
})
    //type values: String, Number, Boolean, Function, Object, Array, custom constructor//type values: String, Number, Boolean, Function, Object, Array, custom constructor

 

(3)Passing data from child components to parent components: custom events

 

Use $on(eventName) Monitoring events $on(eventName) Monitoring events
Use $emit(eventName) Trigger event $emit(eventName) Trigger event

 

 

 

<div id="counter-event-example">div id="counter-event-example">
  <p>{{ total }}</p><p>{{ total }}</p>
  <button-counter v-on:increment="incrementTotal"></button-counter><button-counter v-on:increment="incrementTotal"></button-counter>
  <button-counter v-on:increment="incrementTotal"></button-counter><button-counter v-on:increment="incrementTotal"></button-counter>
</div>/div>
Vue.component('button-counter', {.component('button-counter', {
  template: '<button v-on:click="increment">{{ counter }}</button>',template: '<button v-on:click="increment">{{ counter }}</button>',
  data: function () {data: function () {
    return {return {
      counter: 0counter: 0
    }
  },
  methods: {methods: {
    increment: function () {increment: function () {
      this.counter += 1this.counter += 1
      this.$emit('increment')this.$emit('increment')
    }
  },
})
new Vue({ Vue({
  el: '#counter-event-example',el: '#counter-event-example',
  data: {data: {
    total: 0total: 0
  },
  methods: {methods: {
    incrementTotal: function () {incrementTotal: function () {
      this.total += 1this.total += 1
    }
  }
})

 

Note: To listen for a native event on the root element of a component, use. native to modify v-on

 

<my-component v-on:click.native="doTheThing"></my-component>my-component v-on:click.native="doTheThing"></my-component>

 

 

(4)The child component changes the parent component's prop:

 

<comp :foo="bar" @update:foo="val => bar = val"></comp>comp :foo="bar" @update:foo="val => bar = val"></comp>
When subcomponents need to be updated foo When the value of _______________ foo When the value of _______________
this.$emit('update:foo', newValue).$emit('update:foo', newValue)

 

(5)slot(Similar angular Of transclude)

Suppose we have one. app-layout Component whose template is:

 

<div class="container">div class="container">
  <header><header>
    <slot name="header"></slot><slot name="header"></slot>
  </header></header>
  <main><main>
    <slot></slot><slot></slot>
  </main></main>
  <footer><footer>
    <slot name="footer"></slot><slot name="footer"></slot>
  </footer></footer>
</div>/div>

 

Parent Component Template:

 

<app-layout>app-layout>
  <h1 slot="header">Here may be a page title.</h1><h1 slot="header">Here may be a page title.</h1>
  <p>A paragraph of the main content.</p><p>A paragraph of the main content.</p>
  <p>Another main paragraph.</p><p>Another main paragraph.</p>
  <p slot="footer">Here are some contact information</p><p slot="footer">Here are some contact information</p>
</app-layout>/app-layout>

 

The rendering results are as follows:

 

<div class="container">div class="container">
  <header><header>
    <h1>Here may be a page title.</h1><h1>Here may be a page title.</h1>
  </header></header>
  <main><main>
    <p>A paragraph of the main content.</p><p>A paragraph of the main content.</p>
    <p>Another main paragraph.</p><p>Another main paragraph.</p>
  </main></main>
  <footer><footer>
    <p>Here are some contact information</p><p>Here's some contact information</p>
  </footer></footer>
</div>/div>

 

(6)Scope slot

In subcomponents, you just need to pass the data to the slot, just like you would prop The same is passed to the component:

 

<div class="child">div class="child">
  <slot text="hello from child"></slot><slot text="hello from child"></slot>
</div>/div>

 

In the parent level, it has special attributes scope Of <template> Element, indicating that it is a template for scope slots. scope The value of the value corresponds to a temporary variable name that receives the passed from the subcomponent prop Participants:

 

<div class="parent">div class="parent">
  <child><child>
    <template scope="props"><template scope="props">
      <span>hello from parent</span><span>hello from parent</span>
      <span>{{ props.text }}</span><span>{{ props.text }}</span>
    </template></template>
  </child></child>
</div>/div>

 

If we render the above results, the output will be:

 

<div class="parent">div class="parent">
  <div class="child"><div class="child">
    <span>hello from parent</span><span>hello from parent</span>
    <span>hello from child</span><span>hello from child</span>
  </div></div>
</div>/div>

 

A more representative use case for scoped slots is list components, which allow components to customize how each item of the list should be rendered:

 

<my-awesome-list :items="items">my-awesome-list :items="items">
  <!-- Scope slots can also be named --><!-- Scope slots can also be named -->
  <template slot="item" scope="props"><template slot="item" scope="props">
    <li class="my-fancy-item">{{ props.text }}</li><li class="my-fancy-item">{{ props.text }}</li>
  </template></template>
</my-awesome-list>/my-awesome-list>

 

Templates for list components:

 

<ul>ul>
  <slot name="item"<slot name="item"
    v-for="item in items"v-for="item in items"
    :text="item.text">text="item.text">
    <!-- Write standby here --><!-- Write standby here -->
  </slot></slot>
</ul>/ul>

 

(7)Dynamic components

 

By using reserved <component> Element, dynamically bound to it is Features allow multiple components to use the same mount point and switch dynamically:

 

var vm = new Vue({ vm = new Vue({
  el: '#example',el: '#example',
  data: {data: {
    currentView: 'home'currentView: 'home'
  },
  components: {components: {
    home: { /* ... */ },home: { /* ... */ },
    posts: { /* ... */ },posts: { /* ... */ },
    archive: { /* ... */ }archive: { /* ... */ }
  }
})
<component v-bind:is="currentView">component v-bind:is="currentView">
  <! - Components change when vm. current view changes! - ><! - Components change when vm. current view changes! >
</component>/component>

 

keep-alive:  

If the switched component is kept in memory, its state can be preserved or re-rendering can be avoided. To do this, you can add a keep-alive instruction parameter:

 

<keep-alive>keep-alive>
  <component :is="currentView"><component :is="currentView">
    <! - Inactive components will be cached! - ><! - Inactive components will be cached! >
  </component></component>
</keep-alive>/keep-alive>

 

5. Instance life cycle:

 

Topics: Vue Attribute npm Webpack