Learn Vue step by step (x)


This article talks about component communication, parent-child component communication, the previous blog has been explained, vue also recommends props in, event out; brother node communication how to do it? The official implementation is actually given, so let's take the following scenario and implement it.

In the above figure, the following functionality is implemented: the search form component, which contains various search criteria, loads data into the list component to render when the search button is clicked.

Three implementations will be given here, not for suitability or not, just for demonstration purposes.

1、Use the parent component for wrapping, move all operations to the parent component

2, the search component, trigger an event to the parent component, the parent component listens to the event occurs, it performs a query operation, passing props to the list component, which is also the way we have implemented before, here simply write a demo.

First define our components: SearchComponent , AppComponent , ListComponent

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>demo4</title>
    <script src="https://cdn.bootcss.com/vue/2.4.1/vue.js"></script>

</head>

<body>
    <div id="app">
        <app></app>
    </div>
    <script>
        var SearchComponent = {
            template:`
            <div class="toolbar">
                <input type="text" placeholder="keyword"  v-model="keyword"/>
                <input type="text" placeholder="description" v-model="desc"/>
                <input type="button" value="search" @click="search()" />
             </div>
            `,
            data:function(){
                return {
                    keyword:'',
                    desc:''
                }
            },
            methods:{
                search:function(){
                    this.$emit('onsearch',{keyword:this.keyword,desc:this.desc});
                }
            }
        }

        var ListComponent = {
            template:`
            <div class="list" >
                {{list}}
            </div>
            `,
            props:['list']
        }

        var AppComponent={
            template:`
            <div class="container">
                <search @onsearch="search($event)" ></search>
                <list :list="datas" ></list>
            </div>
            `,
            components:{
                'list':ListComponent,
                'search':SearchComponent
            },
            methods:{
                search:function($e){
                    this.datas=JSON.stringify({
                        data:[],
                        info:'info'
                    });
                }
            },
            data:function(){
                return {
                    datas:null
                }
            }
        }

        var app=new Vue({
            el:'#app',
            components:{
                'app':AppComponent
            }
        });
    </script>
</body>

</html>

Click on the search button and it runs as follows.

The above example is very simple and the code written is described in the previous blog post, so I won't go into detail here, where the data flow flows as follows.

1、Click the button, the data flows from the search component to the parent component

2, the parent component listens to onsearch, listens to the event, processing and assigning values to the list, at this time the data flow from the parent component to the list component

The role of the parent component here is that of a staging area, providing a kind of transit function for the data flow. So if there is no parent component, can we achieve the above function? After all, we can't create a redundant parent component every time a sibling component communicates, so if the number of nested layers is too much is also a big problem, for the problem of sibling component communication, the official also mentioned the implementation method called event bus, the following we will realize the second option, based on event bus.

Modify our code as follows.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>demo4</title>
    <script src="https://cdn.bootcss.com/vue/2.4.1/vue.js"></script>

</head>

<body>
    <div id="app">
        <search></search>
        <list></list>
    </div>
    <script>
        var eventBus = new Vue();

        var SearchComponent = {
            template: `
            <div class="toolbar">
                <input type="text" placeholder="keyword"  v-model="keyword"/>
                <input type="text" placeholder="description" v-model="desc"/>
                <input type="button" value="search" @click="search()" />
             </div>
            `,
            data: function () {
                return {
                    keyword: '',
                    desc: ''
                }
            },
            methods: {
                search: function () {
                    // this.$emit('onsearch',{keyword:this.keyword,desc:this.desc});
                    eventBus.$emit('onsearch', { keyword: this.keyword, desc: this.desc });
                }
            }
        }

        var ListComponent = {
            template: `
            <div class="list" >
                {{list}}
            </div>
            `,

            data: function () {
                return {
                    list: null
                }

            },
            created: function () {
                var self = this;
                eventBus.$on('onsearch', function ($e) {
                    console.log($e);
                    self.list = JSON.stringify($e);
                })
            }
        }



        var app = new Vue({
            el: '#app',
            components: {
                // 'app':AppComponent
                'list': ListComponent,
                'search': SearchComponent
            }
        });
    </script>
</body>

</html>

Here with the help of a global vue empty instance to achieve a global eventbus, of course, we can also use or achieve their own eventbus, this is relatively simple, (the general idea is: define a callback list array, define two methods, an on an exit, on that is to the callback array push key and the corresponding function, exit is to trigger the function corresponding to the key) interested can simply do a little, save and run.

For simple sibling component communication, in fact, this scheme or the first scheme has been satisfied, but if there are too many sibling nodes or the component hierarchy is very deep, using the first scheme we must pass almost duplicate code layer by layer, using the second scheme all components and all depend on the global vue instance or global eventbus, is there a better state management scheme? Can we make state management independent, which is what we'll talk about next with vuex.

Vuex is a state management pattern developed specifically for Vue.js applications. It uses centralized storage to manage the state of all components of the application with corresponding rules to ensure that the state changes in a predictable way. Vuex is also integrated into Vue's official debugging tool, devtools extension, which provides advanced debugging features such as zero-configuration time-travel debugging, state snapshot import and export, etc. If you open the official website, you'll see this paragraph above.

It's all such a mess that it may be hard to understand, and although it looks very forced, it's really just made to be a little more advanced than our eventbus:

each of Vuex The core of the application is store( warehouse)。"store" It's basically a container, It contains most of the state in your app(state)。Vuex differs from a simple global object in two ways:

  1. Vuex's state storage is responsive. When a Vue component reads state from the store, if the state in the store changes, the corresponding component will be updated efficiently accordingly.
  2. You can't change the state in the store directly. The only way to change the state in a store is to explicitly commit mutations. This makes it easy to track every change in state, thus allowing us to implement tools to help us better understand our applications.

There are many concepts and conventions included in vuex, so let's start experiencing them today, and without further ado, the same functionality refactored based on vuex at

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>demo4</title>
    <script src="https://cdn.bootcss.com/vue/2.4.1/vue.js"></script>
    <script src="https://cdn.bootcss.com/vuex/2.3.1/vuex.js"></script>

</head>

<body>
    <div id="app">
        <search></search>
        <list></list>
    </div>
    <script>
        // var eventBus = new Vue();
        var store = new Vuex.Store({
            state: {
                list: null
            },
            mutations: {
                search: function (state, payload) {
                    state.list = JSON.stringify(payload);
                }
            }
        })

        var SearchComponent = {
            template: `
            <div class="toolbar">
                <input type="text" placeholder="keyword"  v-model="keyword"/>
                <input type="text" placeholder="description" v-model="desc"/>
                <input type="button" value="search" @click="search()" />
             </div>
            `,
            data: function () {
                return {
                    keyword: '',
                    desc: ''
                }
            },
            methods: {
                search: function () {
                   this.$store.commit("search",{ keyword: this.keyword, desc: this.desc })
                    //eventBus.$emit('onsearch', { keyword: this.keyword, desc: this.desc });
                }
            }
        }

        var ListComponent = {
            template: `
            <div class="list" >
                {{list}}
            </div>
            `,
            computed:{
                list:function(){
                    return this.$store.state.list;
                }
            }
           
        }



        var app = new Vue({
            el: '#app',
            store:store,
            components: {
                // 'app':AppComponent
                'list': ListComponent,
                'search': SearchComponent
            }
        });
    </script>
</body>

</html>

Here we create a global store, store is unique, which holds all the state (this state is recommended to be global or shared, we assume here that the state in the list component belongs to the shared, we do not take it seriously, and the state in the search belongs to the component itself state), we make the following agreement: do not modify the state directly, to modify the state by submitting mutations, mutations are equivalent to using setState in react to modify the state as well. Direct modification will run-time exceptions.

In response to the code above, the main points of knowledge included are as follows.

1, vuex instantiation: directly new Vuex.Store , create a global unique store, through the configuration parameters, set the state (shared globally), mutations (only supports synchronous operations)

2, vuex and vue connection, through the new Vue instance, inject store, here and the injection of router similar to the previous article, after injection, in any child components, you can access the store through this.$store

3, store in the state is responsive, so it is recommended to define as a component to calculate the property, each time through mutations to submit changes, then you can directly drive the view changes.

This section mainly introduces vuex, which is considered the opening chapter of vuex, not to introduce too much content, so that we have a simple understanding, the next will be to introduce vue-router as well, and slowly dive into other aspects. Stay tuned.


Recommended>>
1、vSport Bai Qiang World Cup blockchain betting and baller coin issuance are nonsense and there should be no kneejerking in the industry
2、Empty hand jerking high speed free Shadowsocks account
3、Im a regular user why cant I borrow money
4、New Nokia Phoenix phone reveal powered by Snapdragon 710
5、How many people will lose their jobs in the auto industry in the age of smart cars

    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号