vue Small Case--Simple Comment Area

1. Small cases (commentary area)

1, process

(1) Analysis of static pages. (vue project creation reference https://www.cnblogs.com/l-y-h/p/11241503.html)
(2) Split static pages into components.
(3) Coding components to generate dynamic pages.

2. Static pages

Reference source: https://www.bilibili.com/video/av49099807/?P=22&t=1223

[Example:
<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <!--Here if bootstrap Select 4.3.1 Styles will be invalid for versions (not studied)-->
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/js/bootstrap.js"></script>
        <title>vue_demo</title>
    </head>

    <body>
        <div id="app">
            <div>
                <!--head-->
                <header class="site-header jumbotron">
                    <div class="container">
                        <div class="row">
                            <div class="col-xs-12">
                                <h1>Welcome to Tucao hall.</h1>
                            </div>
                        </div>
                    </div>
                </header>

                <!--Main part-->
                <!--bootstrap Divide the page into 12 panes, where it is split into 4 left panes and 8 right panes.-->
                <div class="container">
                    <div class="col-md-4">
                        <form action="form-horizontal">
                            <div class="form-group">
                                <label>User name</label>
                                <input type="text" class="form-control" placeholder="User name">
                            </div>
                            <div class="form-group">
                                <label>Content of Tucao</label>
                                <textarea type="text" class="form-control" placeholder="Content of Tucao"></textarea>
                            </div>
                            <div class="form-group">
                                <div class="col-sm-offset-2 col-sm-10">
                                    <button type="button" class="btn btn-default pull-right">Submission</button>
                                </div>
                            </div>
                        </form>
                    </div>
                    <!--md4 for Add end    -->

                    <div class="col-md-8">
                        <h3 class="reply">Tucao replies:</h3>
                        <h2>No Tucao slot, click on the left side to add Tucao!</h2>
                        <ul class="list-group">
                            <li class="list-group-item">
                                <div class="handle col-sm-offset-2 col-sm-10">
                                    <a class="pull-right">delete</a>
                                </div>
                                <p class="user"><span>Tom</span><span>say:</span></p>
                            </li>
                            <li class="list-group-item">
                                <div class="handle col-sm-offset-2 col-sm-10">
                                    <a class="pull-right">delete</a>
                                </div>
                                <p class="user"><span>Tom</span><span>say:</span></p>
                            </li>
                        </ul>
                    </div>
                    <!--md8 for List end -->
                </div>
            </div>
        </div>
        <!--app -->
    </body>

</html>

 

Screenshot of the page:

 

 

 

3. Split static pages.

Split static pages into static components.

Step1: It's a large component (App) that contains various components.

Step2: page content can be split into submitted tucking module (Comment) and Comments.

Step3: the Tucao recovery module can split each tucking slot, that is, each tuck is a component (Item).

 

 

 

The structure of the document is as follows:

 

 

 

[Main Files and Folders:]
index.html    Home page, where all component operations are services, is introduced css,js file
main.js       vue Entry file, start from here vue
App.vue       App.vue Components, entry components for projects
components      Keep all the small pieces in it.


[index.html]
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <!--All components are index.html Service, so introduce it here css,js file-->
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
    <title>vuedemo</title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but vuedemo doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>


[main.js]
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')


[App.vue]
<template>
    <div>
        <!--head-->
        <header class="site-header jumbotron">
            <div class="container">
                <div class="row">
                    <div class="col-xs-12">
                        <h1>Welcome to Tucao hall.</h1>
                    </div>
                </div>
            </div>
        </header>

        <!--Main part-->
        <!--bootstrap Divide the page into 12 panes, where it is split into 4 left panes and 8 right panes.-->
        <div class="container">
            <!--Use each component-->
            <Comment></Comment>
            <Comments></Comments>
        </div>
    </div>
    <!--App -->
</template>

<script>
    // Introducing components
    import Comment from './components/Comment.vue'
    import Comments from './components/Comments.vue'

    export default {
        name: 'app',
        // Register components
        components: {
            Comment,
            Comments
        }
    }
</script>

<style>
</style>


[Comment.vue]
<template>
    <div class="col-md-4">
        <form action="form-horizontal">
            <div class="form-group">
                <label>User name</label>
                <input type="text" class="form-control" placeholder="User name">
            </div>
            <div class="form-group">
                <label>Content of Tucao</label>
                <textarea type="text" class="form-control" placeholder="Content of Tucao"></textarea>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="button" class="btn btn-default pull-right">Submission</button>
                </div>
            </div>
        </form>
    </div>
    <!--Comment -->
</template>

<script>
    export default{
        name: 'comment'
    }
</script>

<style>

</style>


[Comments.vue]
<template>
    <div class="col-md-8">
        <h3 class="reply">Tucao replies:</h3>
        <h2>No Tucao slot, click on the left side to add Tucao!</h2>
        <ul class="list-group">
            <Item></Item>
        </ul>
    </div>
    <!--md8 for List end -->
</template>

<script>
    import Item from './Item.vue'
    
    export default{
        name: 'comments',
        components: {
            Item
        }
    }
</script>

<style>

</style>


[Item.vue]
<template>
    <!--Note that you need to use div Pack, or you'll make a mistake.-->
    <div>
        <li class="list-group-item">
            <div class="handle col-sm-offset-2 col-sm-10">
                <a class="pull-right">delete</a>
            </div>
            <p class="user"><span>Tom</span><span>say:</span></p>
        </li>
        <li class="list-group-item">
            <div class="handle col-sm-offset-2 col-sm-10">
                <a class="pull-right">delete</a>
            </div>
            <p class="user"><span>Tom</span><span>say:</span></p>
        </li>
    </div>
</template>

<script>
    export default{
        name: 'item'
    }
</script>

<style>

</style>

 

The split effect is consistent with the original static page.

 

 

 

 

4. Transfer of values between components (inter-component communication)

The content of the Tucao area on the static page is not written and generated dynamically, so how to generate it involves the transmission of values between components. Properties are declared by props, data is used to pass data (attribute values), and properties are bound by v-bind.

[Modify the above code]
App.vue              Get data and send data to Tucao area. Comments.vue)pass
Comments.vue         Receive App.vue The incoming data, each data to Item.vue pass
Item.vue             Receive Comments.vue Incoming data and display

//If you can't see it at first glance, you can download a Bcomparison software and compare the differences between the codes by yourself.

[App.vue]
<template>
    <div>
        <!--head-->
        <header class="site-header jumbotron">
            <div class="container">
                <div class="row">
                    <div class="col-xs-12">
                        <h1>Welcome to Tucao hall.</h1>
                    </div>
                </div>
            </div>
        </header>

        <!--Main part-->
        <!--bootstrap Divide the page into 12 panes, where it is split into 4 left panes and 8 right panes.-->
        <div class="container">
            <!--Use each component-->
            <Comment></Comment>
                   <!--Need to use v-bind Binding properties-->
            <Comments :contents="contents"></Comments>
        </div>
    </div>
    <!--App -->
</template>

<script>
    // Introducing components
    import Comment from './components/Comment.vue'
    import Comments from './components/Comments.vue'

    export default {
        name: 'app',
        // Register components
        components: {
            Comment,
            Comments
        },
        
        // Transmit data
        data(){
            return {
                contents:[
                    {name: 'tom', content: 'Mom, I want to have roast yam.'},
                    {name: 'jarry', content: 'Eat, eat large pieces.'},
                    {name: 'jarry', content: 'Two yuan is enough.'},
                    {name: 'tom', content: 'That's enough, Mom. Thank you, Mom.'},
                ]
            }
        }
    }
</script>

<style>
</style>


[Comments.vue]
<template>
    <div class="col-md-8">
        <h3 class="reply">Tucao replies:</h3>
        <ul class="list-group">
            <Item v-for="(content, index) in contents" :key="index" :content="content"></Item>
        </ul>
    </div>
    <!--md8 for List end -->
</template>

<script>
    import Item from './Item.vue'
    
    export default{
        name: 'comments',
        // Declare the receive property, which can be used in this component
        props: ['contents'],  // Specify only attribute names
        
        // Registration component
        components: {
            Item
        }
    }
</script>

<style>

</style>


[Item.vue]
<template>
    <!--Note that you need to use div Pack, or you'll make a mistake.-->
    <div>
        <li class="list-group-item">
            <div class="handle col-sm-offset-2 col-sm-10">
                <a class="pull-right">delete</a>
            </div>
            <p class="user"><span style="font-size: 18px;">{{content.name}}</span><span style="font-size: 18px;">say:</span>{{content.content}}</p>
        </li>
    </div>
</template>

<script>
    export default{
        name: 'item',
        props: {
            // Specify the attribute name and the type of the attribute value
            content : Object
         }
    }
</script>

<style>

</style>

The effect is as follows:

 

 

 

5. Dynamic Interaction - Add

Add Tucao operation.

Using v-on binding events, using v-model to achieve two-way data binding, the method can also use v-bind binding and component communication.

[Modify the above code]
App.vue            Define ways to add tucks and pass them as attributes. Comment.vue assembly
Comment.vue        Receive properties and define events to add data

[App.vue]
<template>
    <div>
        <!--head-->
        <header class="site-header jumbotron">
            <div class="container">
                <div class="row">
                    <div class="col-xs-12">
                        <h1>Welcome to Tucao hall.</h1>
                    </div>
                </div>
            </div>
        </header>

        <!--Main part-->
        <!--bootstrap Divide the page into 12 panes, where it is split into 4 left panes and 8 right panes.-->
        <div class="container">
            <!--Use each component-->
            <Comment :addComment="addComment"></Comment>
            <!--Need to use v-bind Binding properties-->
            <Comments :contents="contents"></Comments>
        </div>
    </div>
    <!--App -->
</template>

<script>
    // Introducing components
    import Comment from './components/Comment.vue'
    import Comments from './components/Comments.vue'

    export default {
        name: 'app',
        // Register components
        components: {
            Comment,
            Comments
        },
        
        // Transmit data
        data(){
            return {
                contents:[
                    {name: 'tom', content: 'Mom, I want to have roast yam.'},
                    {name: 'jarry', content: 'Eat, eat large pieces.'},
                    {name: 'jarry', content: 'Two yuan is enough.'},
                    {name: 'tom', content: 'That's enough, Mom. Thank you, Mom.'},
                ]
            }
        },
        
        // Methods of manipulating data
        methods: {
            addComment(comment){
                // Insert data in the header of an array
                this.contents.unshift(comment);
            }
        }
    }
</script>

<style>
</style>


[Comment.vue]
<template>
    <div class="col-md-4">
        <form action="form-horizontal">
            <div class="form-group">
                <label>User name</label>
                <input type="text" class="form-control" placeholder="User name" v-model="name">
            </div>
            <div class="form-group">
                <label>Content of Tucao</label>
                <textarea type="text" class="form-control" placeholder="Content of Tucao" v-model="content"></textarea>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="button" class="btn btn-default pull-right" @click="add">Submission</button>
                </div>
            </div>
        </form>
    </div>
    <!--Comment -->
</template>

<script>
    export default{
        name: 'comment',
        data(){
            return {
                name : '',
                content : ''
            }
        },
        props:{
            // Define attribute type, attribute value type, necessity
            addComment: { 
                type: Function,
                required: true
            }
        },
        methods: {
            add(){
                // step1: Testing the Legitimacy
                const name = this.name.trim();
                const content = this.content.trim();
                if(!name || !content){
                    alert("Input cannot be empty");
                    return;
                }
                
                // step2: take name,content Encapsulated into a single comment(Object of Tucao
                const comment = {name, content};
                
                console.log(comment);
                // step3: take comment Add to comments(Tucao District
                this.addComment(comment);
                
                // step4: Clear the input box
                this.name = '';
                this.content = '';
            }
        }
    }
</script>

<style>

</style>

Effect:

 

 

 

 

 

 

6. Dynamic Interaction -- Delete

Delete.

Similar to add operations.

[Modify the above documents]
App.vue             Define the method of deleting data and pass it as an attribute to Comments.vue
Comments.vue        As an intermediate component, pass index And deletion methods
Item.vue            Receive Comments.vue Passing properties and defining deletion events


[App.vue]
<template>
    <div>
        <!--head-->
        <header class="site-header jumbotron">
            <div class="container">
                <div class="row">
                    <div class="col-xs-12">
                        <h1>Welcome to Tucao hall.</h1>
                    </div>
                </div>
            </div>
        </header>

        <!--Main part-->
        <!--bootstrap Divide the page into 12 panes, where it is split into 4 left panes and 8 right panes.-->
        <div class="container">
            <!--Use each component-->
            <Comment :addComment="addComment"></Comment>
            <!--Need to use v-bind Binding properties-->
            <Comments :contents="contents" :deleteComment="deleteComment"></Comments>
        </div>
    </div>
    <!--App -->
</template>

<script>
    // Introducing components
    import Comment from './components/Comment.vue'
    import Comments from './components/Comments.vue'

    export default {
        name: 'app',
        // Register components
        components: {
            Comment,
            Comments
        },
        
        // Transmit data
        data(){
            return {
                contents:[
                    {name: 'tom', content: 'Mom, I want to have roast yam.'},
                    {name: 'jarry', content: 'Eat, eat large pieces.'},
                    {name: 'jarry', content: 'Two yuan is enough.'},
                    {name: 'tom', content: 'That's enough, Mom. Thank you, Mom.'},
                ]
            }
        },
        
        // Methods of manipulating data
        methods: {
            addComment(comment){
                // Insert data in the header of an array
                this.contents.unshift(comment);
            },
            deleteComment(index){
                // Delete data with specified Subscripts
                this.contents.splice(index, 1);
            }
        }
    }
</script>

<style>
</style>


[Comments.vue]
<template>
    <div class="col-md-8">
        <h3 class="reply">Tucao replies:</h3>
        <h3 v-show="contents.length === 0">No Tucao slot, click on the left side to submit Tucao!!!</h3>
        <ul class="list-group">
            <Item v-for="(content, index) in contents" :key="index" :content="content" :deleteComment="deleteComment" :index="index"></Item>
        </ul>
    </div>
    <!--md8 for List end -->
</template>

<script>
    import Item from './Item.vue'

    export default {
        name: 'comments',
        // Declare the receive property, which can be used in this component
        props: ['contents', 'deleteComment'], // Specify only attribute names

        // Registration component
        components: {
            Item
        }
    }
</script>

<style>

</style>


[Item.vue]
<template>
    <!--Note that you need to use div Pack, or you'll make a mistake.-->
    <div>
        <li class="list-group-item">
            <div class="handle col-sm-offset-2 col-sm-10">
                <a class="pull-right" @click="deleteItem">delete</a>
            </div>
            <p class="user"><span style="font-size: 18px;">{{content.name}}</span><span style="font-size: 18px;">say:</span>{{content.content}}</p>
        </li>
    </div>
</template>

<script>
    export default{
        name: 'item',
        props: {
            // Specify the attribute name and the type of the attribute value
            content : Object,
            deleteComment : Function,
            index : Number 
         },
         methods: {
             deleteItem() {
                 const {content, deleteComment, index} = this;
                 // Use back quotation marks + ${}, ES6 Template string
                 if(window.confirm(`Confirm deletion ${content.name}Comments?`)){
                     deleteComment(index);
                 }
             }
         }
    }
</script>

<style>

</style>

 

Operation results:

 

 

 

 

 

 

7. Complete code

(1) Project Structure and Modified Documents

 

 

(2) Code

[index.html]
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <!--All components are index.html Service, so introduce it here css,js file-->
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
    <title>vuedemo</title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but vuedemo doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>


[main.js]
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')


[App.vue]
<template>
    <div>
        <!--head-->
        <header class="site-header jumbotron">
            <div class="container">
                <div class="row">
                    <div class="col-xs-12">
                        <h1>Welcome to Tucao hall.</h1>
                    </div>
                </div>
            </div>
        </header>

        <!--Main part-->
        <!--bootstrap Divide the page into 12 panes, where it is split into 4 left panes and 8 right panes.-->
        <div class="container">
            <!--Use each component-->
            <Comment :addComment="addComment"></Comment>
            <!--Need to use v-bind Binding properties-->
            <Comments :contents="contents" :deleteComment="deleteComment"></Comments>
        </div>
    </div>
    <!--App -->
</template>

<script>
    // Introducing components
    import Comment from './components/Comment.vue'
    import Comments from './components/Comments.vue'

    export default {
        name: 'app',
        // Register components
        components: {
            Comment,
            Comments
        },
        
        // Transmit data
        data(){
            return {
                contents:[
                    {name: 'tom', content: 'Mom, I want to have roast yam.'},
                    {name: 'jarry', content: 'Eat, eat large pieces.'},
                    {name: 'jarry', content: 'Two yuan is enough.'},
                    {name: 'tom', content: 'That's enough, Mom. Thank you, Mom.'},
                ]
            }
        },
        
        // Methods of manipulating data
        methods: {
            addComment(comment){
                // Insert data in the header of an array
                this.contents.unshift(comment);
            },
            deleteComment(index){
                // Delete data with specified Subscripts
                this.contents.splice(index, 1);
            }
        }
    }
</script>

<style>
</style>


[Comment.vue]
<template>
    <div class="col-md-4">
        <form action="form-horizontal">
            <div class="form-group">
                <label>User name</label>
                <input type="text" class="form-control" placeholder="User name" v-model="name">
            </div>
            <div class="form-group">
                <label>Content of Tucao</label>
                <textarea type="text" class="form-control" placeholder="Content of Tucao" v-model="content"></textarea>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="button" class="btn btn-default pull-right" @click="add">Submission</button>
                </div>
            </div>
        </form>
    </div>
    <!--Comment -->
</template>

<script>
    export default{
        name: 'comment',
        data(){
            return {
                name : '',
                content : ''
            }
        },
        props:{
            // Define attribute type, attribute value type, necessity
            addComment: { 
                type: Function,
                required: true
            }
        },
        methods: {
            add(){
                // step1: Testing the Legitimacy
                const name = this.name.trim();
                const content = this.content.trim();
                if(!name || !content){
                    alert("Input cannot be empty");
                    return;
                }
                
                // step2: take name,content Encapsulated into a single comment(Object of Tucao
                const comment = {name, content};
                
                console.log(comment);
                // step3: take comment Add to comments(Tucao District
                this.addComment(comment);
                
                // step4: Clear the input box
                this.name = '';
                this.content = '';
            }
        }
    }
</script>

<style>

</style>


[Comments.vue]
<template>
    <div class="col-md-8">
        <h3 class="reply">Tucao replies:</h3>
        <h3 v-show="contents.length === 0">No Tucao slot, click on the left side to submit Tucao!!!</h3>
        <ul class="list-group">
            <Item v-for="(content, index) in contents" :key="index" :content="content" :deleteComment="deleteComment" :index="index"></Item>
        </ul>
    </div>
    <!--md8 for List end -->
</template>

<script>
    import Item from './Item.vue'

    export default {
        name: 'comments',
        // Declare the receive property, which can be used in this component
        props: ['contents', 'deleteComment'], // Specify only attribute names

        // Registration component
        components: {
            Item
        }
    }
</script>

<style>

</style>


[Item.vue]
<template>
    <!--Note that you need to use div Pack, or you'll make a mistake.-->
    <div>
        <li class="list-group-item">
            <div class="handle col-sm-offset-2 col-sm-10">
                <a class="pull-right" @click="deleteItem">delete</a>
            </div>
            <p class="user"><span style="font-size: 18px;">{{content.name}}</span><span style="font-size: 18px;">say:</span>{{content.content}}</p>
        </li>
    </div>
</template>

<script>
    export default{
        name: 'item',
        props: {
            // Specify the attribute name and the type of the attribute value
            content : Object,
            deleteComment : Function,
            index : Number 
         },
         methods: {
             deleteItem() {
                 const {content, deleteComment, index} = this;
                 // Use back quotation marks + ${}, ES6 Template string
                 if(window.confirm(`Confirm deletion ${content.name}Comments?`)){
                     deleteComment(index);
                 }
             }
         }
    }
</script>

<style>

</style>

The results of the operation will not repeat the screenshots here, the same as the screenshots above.

Keywords: Javascript Vue Attribute IE

Added by lixid on Thu, 10 Oct 2019 17:13:52 +0300