zoukankan      html  css  js  c++  java
  • VUE(二)

    一.vue成员获取

              vue成员中除data外其他成员需要用$options.成员名(比如$options.methods)来获取.

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <h1 @click="btnClick">{{ msg }}</h1>
            <p>{{ 10 | add }}</p>
            <p>{{ $data }}</p>
            <p>{{ $options.arr }}</p>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                msg: '数据',
                a: 1,
                b: 2,
            },
            methods: {
                btnClick() {
                    console.log(this.msg)
                }
            },
            filters: {
                add(v) {
                    return v+1
                }
            },
            arr: [1, 2, 3, 4],
        });
    
    
        console.log(app.msg);
        console.log(app.$data);
        console.log(app.$options.methods);
        console.log(app.$options.arr);
    </script>
    </html>

    二.pre指令

         v-pre的内部解除vue控制

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <p v-pre>
                <!--v-pre的内部解除vue控制-->
                <!--{{}}不是插值表达式,msg不是变量,v-on不是指令,都是原义输出-->
                <p>{{ msg }}</p>
                <span v-on="abc"></span>
            </p>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: "message"
            }
        })
    </script>
    </html>

    三.循环指令

    通过v-for可遍历列表,字典或者列表套字典等可迭代对象,可以嵌套,可以拿到索引,对于字典第一个参数是value
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <p>{{ arr }}</p>
            <div>
                <!--值 遍历-->
                <p v-for="v in arr">
                    <span>{{ v }}</span>
                </p>
            </div>
            <div>
                <!--值,索引 遍历-->
                <p v-for="(v, i) in arr">
                    <span>第{{ i + 1 }}个值:{{ v }}</span>
                </p>
            </div>
            <p>{{ student }}</p>
            <div>
                <p v-for="(v, k, i) in student">
                    <span>{{ k, v, i | f1 }}</span>
                </p>
            </div>
            <div>
                <!--
                name: Bob | aendge:18 | ger:男
                name: Tom | age:1 | gender:男
                -->
                <p v-for="stu in stus">
                    <!--<span v-for="(v, k, i) in stu">{{i?' | ':''}}{{k}}:{{v}}</span>-->
                    <span v-for="(v, k, i) in stu">{{i|f2}}{{k}}:{{v}}</span>
                </p>
            </div>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                arr: [1, 4, 2, 3, 5],
                student: {
                    'name': 'Bob',
                    'age': 18,
                    'gender': ''
                },
                stus: [
                    {
                        'name': 'Bob',
                        'age': 18,
                        'gender': ''
                    },
                    {
                        'name': 'Tom',
                        'age': 20,
                        'gender': ''
                    }
                ]
            },
            filters: {
                f1(k, v, i) {
                    // return k + ":" + v + '(' + i + ')'
                    return `${k}:${v}(${i})`
                },
                f2(i) {
                    // i为0代表假,返回'',其它索引时返回' | '
                    return i ? ' | ' : ''
                }
            }
        })
    </script>
    </html>

    四.todolist案例:

        在input框中输入数据,点击提交按钮后触发点击事件,数据以数组形式添加,input内容会清空,而缓存中以json字符串保存,data中

    提交的数据则是json解析后的空数组或者是缓存记录的数组,页面渲染的就是for循环之后的一条条数据,可用无需列表展示;

       在展示的数据上还可以绑定删除点击事件,把索引传给methods中的删除函数, this.msgs.splice(i, 1),第二个参数是条数,第三个

    参数是替换后的内容,删除后也要保存到sessionstorage后者localstorage中

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>todolist</title>
        <style>
            li:hover {
                color: red;
                cursor: pointer;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <p>
                <input type="text" v-model="info">
                <button @click="addMsg">留言</button>
                <ul>
                    <li v-for="(msg, i) in msgs" @click="delFn(i)">{{ msg }}</li>
                </ul>
            </p>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                info: '',
                // msgs: ['11111', '22222'],
                // msgs: sessionStorage.msgs && JSON.parse(sessionStorage.msgs) || [],
                // sessionStorage存放数组和字典需要JSON字符串参与
                msgs: JSON.parse(sessionStorage.msgs || '[]'),
            },
            methods: {
                addMsg() {
                    let info = this.info;
                    if (info) {
                        // this.msgs.push(this.info);  // 尾增
                        this.msgs.unshift(this.info);  // 首增
                        // 清空留言框
                        this.info = '';
                        sessionStorage.msgs = JSON.stringify(this.msgs);
                    }
                },
                delFn(i) {
                    this.msgs.splice(i, 1);
                    sessionStorage.msgs = JSON.stringify(this.msgs);
                }
            }
        })
    </script>
    </html>

    五.分隔符成员

     修改插值表达式符号,一般修改为${ }
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            {{ msg }}
            [[ msg }}
            ${ msg }
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: 'message'
            },
            // 修改插值表达式符号
            // delimiters: ['[[', '}}'],
            // delimiters: ['${', '}'],
        })
    </script>
    </html>

    六.计算属性成员(写在computed字典中)

                1) 计算后属性不需要在data中重复定义
                2) 计算后属性必须渲染后,绑定的方法才会生效
                3) 计算后属性绑定的方法中的任意变量值更新,方法都会被调用
                4) 计算后属性为只读属性(不可写)
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <p>
                <input type="text" v-model="a">
                <input type="text" v-model="b">
            </p>
            <!--报错:计算后属性为只读属性-->
            <!--<input type="text" v-model="xyz">-->
            <!--关键:计算后属性必须渲染后,绑定的方法才会生效-->
            <p>{{ xyz }}</p>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                a: '',
                b: '',
                // 报错:计算后属性不需要在data中重复定义
                // xyz: '',
            },
            computed: {
                // 1) 计算后属性不需要在data中重复定义
                // 2) 计算后属性必须渲染后,绑定的方法才会生效
                // 3) 计算后属性绑定的方法中的任意变量值更新,方法都会被调用
                // 4) 计算后属性为只读属性(不可写)
                xyz () {
                    // a值一变化,该方法就会被回调
                    // 原因:计算后属性绑定的方法中的任意变量值更新,方法都会被调用
                    this.a;
                    this.b;
                    console.log('该方法调用了')
                }
                // 使用场景:一个计算后属性的值,可以来源于多个属性值
            }
        })
    </script>
    </html>

       案例: 使用场景 (一个计算后属性的值,可以来源于多个属性值)

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <p>
                姓:<input type="text" v-model="first_name">
                名:<input type="text" v-model="last_name">
            </p>
            <p>{{ full_name }}</p>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        // 使用场景:一个计算后属性的值,可以来源于多个属性值
        new Vue({
            el: '#app',
            data: {
                first_name: '',
                last_name: '',
            },
            computed: {
                full_name () {
                    if (this.first_name && this.last_name)
                        return this.first_name + ' ' + this.last_name;
                    return '姓名'
                }
            }
        })
    </script>
    </html>

    七.监听属性成员(watch)

              1) 监听绑定的属性,该属性可以get、set
              2) 监听的属性一旦发生值更新,绑定的方法就会被调用
              3) 监听的属性是已定义的属性(必须在data中定义)
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            <input type="text" v-model="num_a">
            <p>num_a: {{ num_a }}</p>
            <p>num_b: {{ num_b }}</p>
            <p>num_c: {{ num_c }}</p>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                num_a: '',
                num_b: '',
                num_c: '',
            },
            watch: {
                // 1) 监听绑定的属性,该属性可以get、set
                // 2) 监听的属性一旦发生值更新,绑定的方法就会被调用
                // 3) 监听的属性是已定义的属性(必须在data中定义)
                num_a() {
                    console.log('num_a值更新,该方法被调用');
                    this.num_b = this.num_a * 10;
                    this.num_c = this.num_a * 20;
                },
              }
            // computed: {
            //     num_b() {
            //         return this.num_a * 10
            //     },
            //     num_c() {
            //         return this.num_a * 20
            //     },
            // }
        })
    </script>
    </html>

    八.组件

        组件:由 template + css + js 三部分组成(.vue文件)
           1)组件具有复用性
           2) 复用组件时,数据要隔离
           3) 复用组件时,方法不需要隔离,因为方法使用隔离数据就可以产生区别
    
        组件介绍:
           1) 每一个组件都有自己的template(虚拟DOM),最后要替换掉真实DOM(渲染)
           2) 挂载点el,在根组件没有规定template,用挂载的真实DOM拷贝出虚拟DOM,完成实例创建后再替换掉真实DOM(渲染)
           3) 挂载点el,在根组件规定template,就采用自己的template作为虚拟DOM,挂载点还是必须的,用于占位
           4) 所有 new Vue() 产生的组件都称之为根组件 - 项目开发时,整个项目只有一个根组件
           5) template只能解析一个根标签
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
    </head>
    <body>
        <div id="app">
            {{ msg }}
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
    
        let num = 100;
        new Vue({
            el: '#app',
            data: {
                msg: 'message'
            },
            // template: '<div id="main"><p>{{ msg }}</p><p>{{ msg }}</p></div>'
            template: `
            <div id="main">
                <p>{{ msg }}</p>
                <p>{{ msg }}</p>
                <div>{{ msg }}</div>
                <div>${ num }</div>
            </div>
            `,
    
        })
    
    </script>
    </html>

    九.局部组件:

       创建组件------注册组件--------组件渲染

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            .ad {
                 200px;
                padding: 5px;
                margin: 5px;
                box-shadow: 0 0 5px 0 gold;
                float: left;
            }
            .ad img {
                 100%;
            }
            .ad h4 {
                margin: 0;
                font: normal 20px/30px '微软雅黑';
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <!--<div class="ad">-->
                <!--<img src="img/mn.jpg" alt="">-->
                <!--<h4>美女</h4>-->
            <!--</div>-->
    
            <!--<ad></ad>-->
            <!--<ad></ad>-->
    
            <!--3)组件渲染-->
            <local-tag></local-tag>
            <local-tag></local-tag>
            <local-tag></local-tag>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        // 1)创建组件
        let localTag = {
            template: `
            <div class="ad">
                <img src="img/mn.jpg" alt="">
                <h4>美女</h4>
            </div>
            `
        };
    
    
        new Vue({
            el: '#app',
            // 2)注册组件
            components: {
                // ad: localTag,
                // localTag: localTag,
                localTag
            }
        })
    </script>
    </html>

    十.全局组件

        1)创建组件: Vue.component
        2)渲染组件: <global-tag></global-tag>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            .ad {
                 200px;
                padding: 5px;
                margin: 5px;
                box-shadow: 0 0 5px 0 gold;
                float: left;
            }
            .ad img {
                 100%;
            }
            .ad h4 {
                margin: 0;
                font: normal 20px/30px '微软雅黑';
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <local-tag></local-tag>
            <global-tag></global-tag>
        </div>
        <div id="main">
            <local-tag></local-tag>
            <global-tag></global-tag>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        // 局部组件
        // 1)创建组件
        // 2)注册组件
        // 3)渲染组件
        let localTag = {
            template: `
            <div class="ad">
                <img src="img/mn.jpg" alt="">
                <h4>美女</h4>
            </div>
            `
        };
    
        // 全局组件
        // 1)创建组件
        // 2)渲染组件
        Vue.component('global-tag', {
            template: `
            <div class="ad">
                <img src="img/mn.jpg" alt="">
                <h4>共享美女</h4>
            </div>
            `
        });
    
        new Vue({
            el: '#app',
            components: {
                localTag
            }
        });
        new Vue({
            el: '#main',
            components: {
                localTag
            }
        });
    </script>
    </html>

    十一.组件复用的数据隔离

          在子组件中写templates模板,data以函数的形式书写,返回的是一个字典, 有自己的作用域,每个子组件的数据都是隔离的,而调用的方法是公用的

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            .ad {
                 200px;
                padding: 5px;
                margin: 5px;
                box-shadow: 0 0 5px 0 gold;
                float: left;
            }
            .ad img {
                 100%;
            }
            .ad h4 {
                margin: 0;
                font: normal 20px/30px '微软雅黑';
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <local-tag></local-tag>
            <global-tag></global-tag>
        </div>
        <div id="main">
            <local-tag></local-tag>
            <global-tag></global-tag>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        // 局部组件
        // 1)创建组件
        // 2)注册组件
        // 3)渲染组件
        let localTag = {
            template: `
            <div @click="click1" class="ad">
                <img src="img/mn.jpg" alt="">
                <h4>美女被点了{{ num }}下</h4>
            </div>
            `,
            // 除了根组件,数据都是函数的返回值字典
            data () {
                return {
                    num: 0
                }
            },
            methods: {
                click1() {
                    this.num ++
                }
            },
        };
    
        // 全局组件
        // 1)创建组件
        // 2)渲染组件
        Vue.component('global-tag', {
            template: `
            <div class="ad" @click="click2">
                <img src="img/mn.jpg" alt="">
                <h4>共享{{ count }}次美女</h4>
            </div>
            `,
            data() {
                return {
                    count: 0
                }
            },
            methods: {
                click2() {
                    this.count ++
                }
            }
        });
    
        new Vue({
            el: '#app',
            components: {
                localTag
            }
        });
        new Vue({
            el: '#main',
            components: {
                localTag
            }
        });
    </script>
    </html>

    十二.组件信息交互父传子

        分析数据 父传子
         1)父组件提供数据
         2)在父组件模板中,为子组件标签设置自定义属性绑定父级数据
         3)在子组件props成员中,接收自定义属性
         4)在子组件模板和方法中,使用自定义属性名就可以访问父级数据
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            .ad {
                 200px;
                padding: 5px;
                margin: 5px;
                box-shadow: 0 0 5px 0 gold;
                float: left;
            }
            .ad img {
                 100%;
            }
            .ad h4 {
                margin: 0;
                font: normal 20px/30px '微软雅黑';
                text-align: center;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <local-tag :ad_dic="ad" v-for="ad in ads" :key="ad.img"></local-tag>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        let localTag = {
            props: ['ad_dic'],
            template: `
            <div class="ad">
                <img :src="ad_dic.img" alt="">
                <h4>{{ ad_dic.title }}</h4>
            </div>
            `,
        };
    
        // 模拟后台的数据
        let ads = [
            {
                'img': 'img/001.png',
                'title': '小猫'
            },
            {
                'img': 'img/002.png',
                'title': '黄蛋'
            },
            {
                'img': 'img/003.png',
                'title': '蓝蛋'
            },
            {
                'img': 'img/004.png',
                'title': '短腿'
            },
        ];
        new Vue({
            el: '#app',
            data: {
                ads,  // 后期项目是后台返回的数据
            },
            components: {
                localTag
            }
        })
        // 分析数据 父传子
        // 1)父组件提供数据
        // 2)在父组件模板中,为子组件标签设置自定义属性绑定父级数据
        // 3)在子组件props成员中,接收自定义属性
        // 4)在子组件模板和方法中,使用自定义属性名就可以访问父级数据
    </script>
    </html>

    十三.组件信息交互子传父

        分析数据 父传子
           1)父组件提供数据 :  info为空数组或缓存数组
            2)在父组件模板中,为子组件标签设置自定义属性绑定父级数据 
           3)在子组件props成员中,接收自定义属性: props: ['msg', 'index'],
           4)在子组件模板和方法中,使用自定义属性名就可以访问父级数据
         分析数据 子传父
           1)子组件提供数据  this.index可从父级拿
           2)子组件通过系统事件激活自己的绑定方法,发送一个自定义事件,携带自身数据: 子组件模板中@click="del_fn"
                子组件方法中 this.$emit('del_action', this.index)
           3)在父组件模板中的子组件标签中为自定义事件绑定父组件方法: 
                   @del_action="del_li"
           4)父组件实现方法获取到子组件数据
                  del_li(index)
    
    
    
    
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            body {
                font-size: 30px;
            }
            li:hover {
                color: orange;
                cursor: pointer;
            }
            .del:hover {
                color: red;
            }
        </style>
    </head>
    <body>
        <div id="app">
            <p>
                <input type="text" v-model="info">
                <button @click="add_msg">留言</button>
                <ul>
                    <msg-tag @del_action="del_li" :msg="msg" :index="i" v-for="(msg, i) in msgs" :key="msg"></msg-tag>
                </ul>
            </p>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        let msgTag = {
            props: ['msg', 'index'],
            template: `
            <li>
                <span @click="del_fn" class="del">x</span>
                <span>{{ msg }}</span>
            </li>
            `,
            methods: {
                del_fn() {
                    this.$emit('del_action', this.index)
                }
            }
        };
    
    
        new Vue({
            el: '#app',
            components: {
                msgTag
            },
            data: {
                info: '',
                msgs: JSON.parse(sessionStorage.msgs || '[]'),
            },
            methods: {
                add_msg() {
                    let info = this.info;
                    if (info) {
                        this.msgs.unshift(this.info);
                        this.info = '';
                        sessionStorage.msgs = JSON.stringify(this.msgs);
                    }
                },
                del_li(index) {
                    console.log(index);
                    this.msgs.splice(index, 1);
                    sessionStorage.msgs = JSON.stringify(this.msgs);
                }
            }
        });
        // 分析数据 子传父
        // 1)子组件提供数据
        // 2)子组件通过系统事件激活自己的绑定方法,发送一个自定义事件,携带自身数据
        // 3)在父组件模板中的子组件标签中为自定义事件绑定父组件方法
        // 4)父组件实现方法获取到子组件数据
    </script>
    </html>
  • 相关阅读:
    前端试题-正则中test, exec, match的区别
    前端试题-什么是css sprite?优缺点?
    有哪些软件堪称「神器」,却不被大众所知?(转)
    gif,png,jpg的区别
    前端试题-两列等高布局
    20160109小问题
    动画效果之运动
    用JS控制下拉菜单效果
    获取当前时间getDate()注意点
    全心加入web前端开发,向上吧!
  • 原文地址:https://www.cnblogs.com/sima-3/p/11426654.html
Copyright © 2011-2022 走看看