This is the fourth day of my participation in Gwen Challenge

The filter

Vue.js allows you to customize filters that can be used for some common text formatting. Filters can be used in two places: double curly brace interpolation and v-bind expressions (the latter supported as of 2.1.0+). Filters should be added to the end of JavaScript expressions, indicated by the “pipe” symbol:

Types of filters:

  • Global filters: Define filters globally before creating Vue instances
  • Local filters: Defines local filters in a component’s options

Tip: If the global filter and the local filter have the same name, the local filter is used.

Global filter

Vue.filter('Filter name'.function (value[,param1,...] ) {  
// Logical code
})
Copy the code

Define local filters

new Vue({       
  filters: {      
     'Filter name': function (value[,param1,...] ) { 
         // Logical code}}})Copy the code

Application filter

{{expression | filter name}}Copy the code

Case study:

<body>
  <div id="myDiv">
    <p>Not using filters: {{birthday}}</p>
    <p>{{birthday | dataFormat}}</p>
    <p>Filter not used: {{message}}</p>
    <p>Bell will replace as wang: {{message | messageFormat}}</p>
    <p>Don't preach, default to liu: {{message | paramFormat}}</p>
    <p>Ginseng, using parameters: {{message | paramFormat (" ROM ")}}</p>
  </div>
  <script src="./js/vue.js"></script>
  <script src="./js/moment.js"></script>
  <script type="text/javascript">
    Vue.filter("dataFormat".(value) = > {
      return moment(value).format("YYYY-MM-DD HH:mm:ss");
    });
    Vue.filter("messageFormat".(value) = > {
      return value.replace('clock'."The king")});const app = new Vue({
      el: "#myDiv".data: {
        birthday: new Date(),
        message: 'Mr. Chung is going to make his mark.'
      },
      filters: {
        'paramFormat': (value, param = "Liu") = > {
          return value.replace("Clock", param)
        }
      }
    })
  </script>
</body>
Copy the code

The listener

While computing properties is more appropriate in most cases, sometimes a custom listener is required. That’s why Vue provides a more generic way to respond to changes in data with the Watch option. This approach is most useful when asynchronous or expensive operations need to be performed when data changes.

Watch allows us to monitor changes in a value. And react accordingly.

<body>
  <div id="app">
    <input type="text" v-model='message'>
  </div>
  <script src="./js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app'.data: {
        message: 'Hello World',},watch: {
        message(newMessage, oldMessage) {
          console.log('New value' + newMessage);
          console.log('Old value'+ oldMessage); }}})</script>
</body>
Copy the code

The depth of the monitor

If you monitor an object, you need to perform in-depth monitoring to monitor the property changes of the object.

When you defined the monitor, person was a function. Now it’s an object and you specify two properties:

  • deep: represents in-depth monitoring, which monitors not only person changes, but also property changes in person
  • handler: Monitor handler function
<body>
  <div id="app">
    <input type="text" v-model="person.name"><br>
    <input type="text" v-model="person.age">
    <button @click="person.age++">+</button>
    <h2>The name is {{person.name}}; {{person. Age}}</h2>
  </div>
  <script src="./js/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app'.data: {
        person: {}},watch: {
        person: {
          deep: true.handler(obj) {
            console.log("name = " + obj.name + ", age="+ obj.age); }}}})</script>
</body>
Copy the code

componentization

Global components

In large application development, pages can be divided into many parts. Often different pages will have the same part. For example, you might have the same header navigation. So we split different parts of the page into separate components that can then be shared across different pages to avoid duplication of development.

  • A component is actually a Vue instance, so it also receives: Data, methods, lifecycle functions, and so on when it is defined
  • The difference is that the component is not bound to the elements of the page, otherwise it cannot be reused, so there is no EL attribute
  • However, the component rendering requires an HTML template, so the template attribute is added, and the value is the HTML template
  • Once the global component is defined, any VUE instance can use the component name directly in HTML
  • A component’s data option must be a function, so each instance can maintain a separate copy of the returned object
  • Components can be reused multiple times
<div id="app">
  <! -- Use defined global components -->
  <counter></counter>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script type="text/javascript">
  // Define the global component with two parameters: 1, component name. 2. Component parameters
  Vue.component("counter", {template:.data(){
      return {
        count:0}}})var app = new Vue({
    el:"#app"
  })
</script>
Copy the code

Local components

Once registered globally, this means that even if you don’t use the component in the future, it will still be loaded as the Vue loads.

Therefore, for some components that are not frequently used, we use local registration.

We start by defining an object externally with the same structure as the second argument passed when creating the component:

const counter = {
  template:.data(){
    return {
      count: 0}}};Copy the code

Used in vUE pages

var app = new Vue({
  el:"#app".components: {counter: counter // Register defined objects as components}})Copy the code
  • Components is the current collection of Vue object subcomponents.
  • The effect is similar to the global registration, except that the Counter component can only be used in the current Vue instance

Components by value

We define a child component and accept complex data:

const myList = {
  template: '<ul><li v-for="item in items" :key="item.id"> {{item.id}} : {{item.name}} </li></ul>'.props: {
    items: {
      type: Array.default: [].required: true}}};Copy the code

This child component iterates over items and outputs them to the page.

Props: Defines the properties to be received from the parent component

Items: is the name of the property to receive

  • Type: Specifies that the parent component must pass in an array
  • Default: indicates the default value
  • Required: Is it necessary
<div id="app">
  <! Class class class class class class class class class class class class class class class class class class class class class class class
  <my-list :items="lessons"/>
</div>
<script>
  var app = new Vue({
    el: "#app".components:{
      myList 
    },
    data: {
      lessons:[
        {id:1.name: 'java'},
        {id:2.name: 'python'},
        {id:3.name: 'ui'},]}})</script>
Copy the code

Here’s another example:

<div id="app">
    <h2>num: {{num}} </h2><! When using a child component, pass num to the child component.<counter :num="num"></counter>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
  // Defines two buttons that add or subtract the number num when clicked
  Vue.component("counter", {
  	template:'\ < div > \ < button @ click = "num++" > add < / button > \ < button @ click = "num - > reduction < / button > \ < / div >'.props: ['num']// Count is obtained from the parent component.
  })
  var app = new Vue({
    el:"#app".data: {
      num: 0}})</script>
Copy the code

Num in H2 cannot be changed. Why? The child component is not allowed to modify the parent component properties after receiving them by default. This is explained in the official documentation. Cn.vuejs.org/v2/guide/co…

Only the parent component can modify, so the addition and subtraction operations must be placed in the parent component:

var app = new Vue({
  el:"#app".data: {num: 0
  },
  methods: {// The parent component defines the method to operate num
    increment(){
      this.num++;
    },
    decrement(){
      this.num--; }}})Copy the code

We can bind a parent component’s function to a child component with the V-ON directive:

<div id="app">
  <h2>num: {{num}}</h2>
  <counter :count="num" @inc="increment" @dec="decrement"></counter>
</div>
Copy the code

Functions are defined in child components, whose concrete implementation calls the implementation of the parent component and calls these functions in child components. When a button in a child component is clicked, the bound function is called:

Vue.component("counter", {
  template:'\ < div > \ < button @ click = "plus" > add < / button > \ < button @ click = "reduce" > reduction < / button > \ < / div >'.props: ['count'].methods: {plus(){
      this.$emit("inc");
    },
    reduce(){
      this.$emit("dec"); }}})Copy the code

That is: Vue provides a built-in this.$emit() function that calls the functions bound by the parent component

routing

Use case

Now let’s implement such a function: a page, including login and registration, click different buttons, realize the login and registration page switch.

First we need to create two components, namely login and registration

login.js

const loginForm = {
  template:'\ < div > \ < h2 > < / h2 > login page \ username: < input type = "text" > < br / > \ password: < input type = "password" > < br / > \ < / div > \'
}
Copy the code

register.js

const registerForm = {
  template:'\ 
      
\

Registration page

\ use   Door & ensp;

\ emsp;   Code: < input type = "password" > < br / > \ confirm password: < input type = "password" > < br / > \ < / div > \ '
} Copy the code

Introduce them separately on the home page

index.html

<body>
  <div id="app" style="text-align: center; font-size: 120%;">
    <! --router-link -->
    <span>
      <router-link to="/login">The login</router-link>
    </span>
    <span>
      <router-link to="/register">registered</router-link>
    </span>
    <hr />
    <div>
      <! -- Vue-router anchor point -->
      <router-view></router-view>
    </div>
  </div>
  <script src=".. /js/vue.js"></script>
  <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
  <script src="./login.js"></script>
  <script src="./register.js"></script>
  <script type="text/javascript">
    // Define a route
    const routes = [{
        path: '/login'.component: loginForm
      },
      {
        path: '/register'.component: registerForm
      }
    ]
    // Create a router instance and pass the Routes configuration
    const router = new VueRouter({
      routes // routes: routes
    })
    var vm = new Vue({
      el: "#app",
      router
    })
  </script>
</body>
Copy the code
  • Router-link specifies a forward link. When clicked, vue-Router will trigger the routing function.

  • Router-view is used to specify an anchor point. When the route path matches, vue-Router will automatically place the corresponding component at the anchor point for rendering.

  • Create the VueRouter object and specify the route parameters

  • Routes: array of routing rules. Multiple objects can be specified. Each object is a routing rule and contains the following attributes:

    • Path: indicates the route path
    • Component: component name

Dynamic routing

Often, dynamic routing configuration is required when things like /user/foo and /user/bar, /user/100 and /user/101 are mapped to the same component. Simple, we can use:

A “path parameter” uses the colon: notation. When a route is matched, the parameter value is set to this.$route.params, which can be used within each component.

routes: [
  // Dynamic path parameters start with a colon
  { path: '/user/:id'.component: User }
]
Copy the code
<div>{{ $route.params.id }}</div>
Copy the code
model Matching path $route.params
/user/:username /user/evan { username: 'evan' }
/user/:username/post/:post_id /user/evan/post/123 { username: 'evan', post_id: '123' }

In addition to $route.params, the $route object provides other useful information, such as $route.query (if the URL has query parameters), $route.hash, and so on.

Embedded routines by

const router = new VueRouter({
  routes: [{path: '/user/:id'.component: User,
     children: [{// If /user/:id/profile matches successfully,
         // The UserProfile will be rendered in User's 
      
         path: 'profile'.component: UserProfile
       },
       {
         // when /user/:id/posts matches successfully
         // UserPosts will be rendered in User's 
      
         path: 'posts'.component: UserPosts
       }
     ]
    }
  ]
})
Copy the code

After routing

You can set the name of a route in the Routes configuration when creating the Router instance.

const router = new VueRouter({
  routes: [{path: '/user/:userId'.name: 'user'.component: User
    }
  ]
})
Copy the code

To link to a named route, pass an object to router-link’s to property:

<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
Copy the code

This is the same thing as code calling router.push(), more on that later.

router.push({ name: 'user'.params: { userId: 123 }})
Copy the code

Programmatic routing

router.push()

Instead of using

to create an A tag to define navigation links, we can use the router instance method to write code to do so.

declarative programmatic
<router-link :to="..." > router.push(...)

Inside the Vue instance, you can pass$routerAccess the routing instance. So you can callthis.$router.push.

To navigate to different urls, use the router.push method. This method adds a new record to the history stack, so when the user clicks the browser back button, it returns to the previous URL.

/ / string
router.push('home')

/ / object
router.push({ path: 'home' })

// Named route, (name -> params)
router.push({ name: 'user'.params: { userId: '123' }})

// With query parameters, change to /register? plan=private (path -> query)
router.push({ path: 'register'.query: { plan: 'private' }})
Copy the code

If providedpath.paramsWill be ignored.

const userId = '123'
router.push({ name: 'user'.params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// Params does not work here
router.push({ path: '/user'.params: { userId }}) // -> /user
Copy the code

router.replace()

Much like router.push, the only difference is that it does not add a new record to history, but replaces the current history record with its method name.

declarative programmatic
<router-link :to="..." replace> router.replace(...)

router.go(n)

This method takes an integer that means how many steps forward or backward in the history, similar to window.history.go(n).

example

// Further forward in the browser record, equivalent to history.forward()
router.go(1)

// Step back to record, equivalent to history.back()
router.go(-1)

// Forward 3 steps record
router.go(3)

// If history is not enough, fail silently
router.go(-100)
router.go(100)
Copy the code

State management

Vuex is a state management mode developed specifically for vue.js applications.

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})
Copy the code

Now you can retrieve state objects via store.state and trigger state changes via the store.mit method:

store.commit('increment')
console.log(store.state.count) / / - > 1
Copy the code

To access this.$Store property in a Vue component, you need to provide a created store for the Vue instance. Vuex provides a mechanism to “inject” the store from the root component to all child components in the form of store options:

new Vue({
  el: '#app',
  store,
  methods: {
    increment() {
      this.$store.commit('increment')
      console.log(this.$store.state.count)
    }
  }
})
Copy the code

Note: We committed mutation rather than changing store.state.count directly because we wanted to track state changes more explicitly.

The resources

router.vuejs.org/zh/

vuex.vuejs.org/zh/

Mp.weixin.qq.com/s/KrkEpUjWo…