zoukankan      html  css  js  c++  java
  • Vue--基础2

    Vue--基础2

    vue成员获取

    1. 当获取Vue对象中的的成员里面的值的时候, 可以直接通过变量名直接进行获取
    2. 当获取Vue对象中的成员时, 可以通过$成员名进行获取, 但此时拿不到methods以及自定义的成员
    3. 最终可以通过$options.成员名获取Vue对象成员所有的内容
    <body>
    <div id="app">
        <h1 @click="btn_click">{{ msg }}</h1>
        <p>{{ num | 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: '消息',
                num: 20,
            },
            methods: {
                btn_click(){
                    console.log(this.msg)
                    console.log(this.$data)
                    // console.log(1, this.el)
                }
            },
            filters:{
                add(v){
                    console.log(v);
                    return v * v
                }
            },
            arr: [1,4,5,7,3]
        });
    
        console.log(app.msg);
        console.log(app.$data);
        console.log(app.$options.methods);
        console.log(app.$options.arr);
    </script>
    

    分隔符成员

    分隔符成员主要是进行差值表达式的符号重定义, 以便不与其他的模板语言造成混淆,比如django中的模板语言也是通过{{ }}进行变量渲染,所以我们可以通过delimeters分隔符成员进行重定义

    <body>
        <div id="app">
            <!--{{ msg }}-->
            <!--[[ msg }}-->
            ${ msg }
        </div>
    </body>
    <script src="js/vue.js">
        new Vue({
            el: '#app',
            data: {
                msg: 'message'
            },
            // 修改插值表达式符号
            // delimiters: ['[[', '}}'],
            delimiters: ['${', '}'],
        })
    </script>
    

    计算属性成员

    什么是计算属性

    在vue插值表达式中,我们可以进行一些简单的运算,在模板中放入太多的逻辑会让模板过重且难以维护。例如:

    放在插值表达式中:

    <div id="example">
      {{ message.split('').reverse().join('') }}
    </div>
    

    这里的表达式包含3个操作,并不是很清晰,所以遇到复杂逻辑时应该使用Vue特带的计算属性computed来进行处理。

    计算属性的用法

    在一个计算属性里可以完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回一个结果就可以

    上面的的例子可以重写一下

    <div id="example">
      <p>Original message: "{{ message }}"</p>
      <p>Computed reversed message: "{{ reversedMessage }}"</p>  //我们把复杂处理放在了计算属性里面了
    </div>
    
    <script>
        var vm = new Vue({
            el: '#example',
            data: {
                message: 'Hello'
            },
            computed: {
                reversedMessage: function () {
                    // `this` 指向 vm 实例
                    return this.message.split('').reverse().join('')
                }
            }
        });
    </script>
    
    
    /*
    运行结果:
    Original message: "Hello"
    Computed reversed message: "olleH"
    */
    

    除了上例简单的用法,计算属性还可以依赖多个Vue 实例的数据,只要其中任一数据变化,计算属性就会重新执行,视图也会更新。

    <body>
        <div id="app">
            <button @click="add()">补充货物1</button>
            <div>总价为:{{price}}</div>
        </div>
    </body>
    var app = new Vue({        
           el: '#app', 
       data: {
           package1: {
               count: 5,
               price: 5
           },
           package2: {
               count: 10,
               price: 10
           }
        },
        computed: {
         price: function(){
             return this.package1.count*this.package1.price+this.package2.count*this.package2.price  //总价随着货物或价格的改变会重新计算
         }
        },
        methods: {   //对象的方法
            add: function(){
                this.package1.count++
            }
        }
    });
    

    注意:

    1. 计算后属性不需要在data中重复定义
    2. 计算后属性必须渲染后,绑定的方法才会生效;
    3. 计算后属性绑定的方法中的任意变量值更新,方法都会被调用;
    4. 计算后属性为只读属性(不可写)
    5. 计算属性可以依赖其他计算属性
    6. 计算属性不仅可以依赖当前Vue 实例的数据,还可以依赖其他实例的数据

    监听属性成员

    监听属性,即监听data中的属性,当属性发生变化的时候,就会触发这个方法,只要监听的属性发生变化,就会触发

    1. 监听绑定的属性,该属性可以get、set;
    2. 只要监听的属性发生变化,绑定的方法就会被调用

    注意点:监听的属性需要在data中定义

    <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">
        new Vue({
            el: '#app',
            data: {
                num_a: '',
                num_b: '',
                num_c: '',
            },
    
            watch:{
                num_a() {
                    this.num_b = this.num_a * 2;
                    this.num_c = this.num_b *5
                }
            }
        })
    </script>
    

    组件

    组件的介绍

    组件就是一个虚拟DOM,在渲染的时候会替换真实DOM,但是组件本身可以有自己的data和方法,就相当于python中的类,具有自己的类属性和方法

    1. 组件都有自己的template(虚拟DOM),最后要替换掉真实DOM
    2. 挂载点el,在根组件没有规定template,用挂载的真实DOM拷贝出虚拟DOM,完成实例创建后再替换掉真实DOM(渲染),但是在根组件规定template,就采用自己的template作为虚拟DOM,挂载点还是必须的,用于占位
    3. template只能解析一个根标签
    4. 所有 new Vue() 产生的组件都称之为根组件 ---> 项目开发时,整个项目只有一个根组件

    组件的优点:

    1. 组件是由template + css + js三部分组成
    2. 具有复用性,减少代码的冗余
    3. 复用组件时,需要注意组件之间的数据隔离,但是方法不需要隔离,因为调用相同的方法使用的数据不一样,产生的结果也不一样

    局部组件

    局部组件只能在引入当前的vue实例中有效,在当前vue实例中components属性加上引入进来的组件实例即可

    创建局部组件步骤:

    1. 创建组件
    2. 注册组件
    3. 渲染组件
    <div id="app">
        {{msg}}
        <!-- 3 渲染组件 -->
        <local-comp></local-comp>
    </div>
    
    <script>
        // 1 创建组件
        let localComp = {
            template: "<div>我是局部组件</div>"
        };
        
        new Vue({
            el: "#app",
            data: {
                msg: "hello component"
            },
            // 2 注册组件
            components: {
                localComp
            }
        });
    </script>    
    

    全局组件

    使用Vue.component进行全局注册,所有vue实例都会共享此组件,不需要在Vue示例中在进行注册

    创建全局组件步骤:

    1. 创建组件
    2. 渲染组件
    <div id="app">
    	{{msg}}
        /<!-- 2 渲染组件 -->
    	<const-comp></const-comp>
    </div>
    
    <script>
        // 1 创建组件
        Vue.component('constComp', {
            template: "<h3>我是全局组件</h3>"
        });
    
        new Vue({
            el: "#app",
            data: {
                msg: "hello component"
            }
        });
    </script>
    

    组件复用的数据隔离

    <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">
        // 局部组件
        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 ++
                }
            },
        };
    
        // 全局组件
        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>
    

    组件之间的数据交互

    vue组件的通信是vue组件的核心,组件不仅仅是要把模板的内容进行复用;更主要的是组件间要进行通信;组件之间的通信数据传递是组件的生命力之一。

    父组件向子组件传递数据

    子组件可以通过props接受父组件传过来数据

    props可以是一个数据类型也可以是一个数组,也可以是对象,如果作为对象,数据有3个属性type,default,require。其中default,require值都是布尔类型值。type有Number, String, Boolean, Array, Object, Function,Symbol。

    如果props数据是对象或数组时默认值default必须是一个函数来返回初始化数据。

    步骤

    1. 父组件提供给数据
    2. 在父组件模板中,为子组件标签设置自定义属性绑定父级数据
    3. 在子组件props成员中,接收自定义属性
    4. 在子组件模板和方法中,使用自定义属性名就可以访问父级数据
    <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">
        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
            }
        })
    </script>
    

    子组件向父组件传递数据

    自定义事件$emit,子组件向父组件通信

    步骤

    1. 子组件提供数据
    2. 子组件通过系统事件激活自己的绑定方法,发送一个自定义事件,携带自身数据
    3. 在父组件模板中的子组件标签中为自定义事件绑定父组件方法
    4. 父组件实现方法获取到子组件数据
    <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">
        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);
                }
            }
        });
    </script>
    

    插槽指令

    上面的父组件和子组件之间的数据交互看起来贼麻烦,所以我们可以通过插槽(slot)指令来进行

    所谓的插槽,也就是类似于一个子组件或者标签的引用的过程,在父组件里面定义一个slot,给她起个name叫“del_btn”,然后组件引入到子组件,子组件里面有个元素的属性slot值等于name的值"del_btn",然后父组件里面没有值的时候就可以显示子组件里面的信息了(切记:插槽slot要写在父组件里面!!!)

    <body>
        <div id="app">
            <p>
                <input type="text" v-model="info">
                <button @click="add_msg">留言</button>
                <ul>
                    <msg-tag :msg="msg" v-for="(msg, i) in msgs" :key="msg">
                        <!--template通过v-slot绑定子组件内部slot插槽标签的name属性值-->
                        <template v-slot:del_btn>
                            <span @click="del_fn(i)" class="del">x</span>
                        </template>
                    </msg-tag>
                </ul>
            </p>
        </div>
    </body>
    <script src="js/vue.js">
        let msgTag = {
            props: ['msg'],
            template: `
            <li>
    			<!--slot标签是在子组件中占位,父组件模板中可以通过name名字来填充-->
                <slot name="del_btn"></slot>
                <span>{{ msg }}</span>
            </li>
            `,
        };
        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_fn(index) {
                    console.log(index);
                    this.msgs.splice(index, 1);
                    sessionStorage.msgs = JSON.stringify(this.msgs);
                }
            }
        });
    </script>
    
  • 相关阅读:
    Centos 7 下安装LDAP 双主同步
    Apache Ranger && HDFS
    Java 学习(六)
    Java学习(五)
    Java学习(四)
    Java学习(三)
    Java学习(二)
    Java学习(一)
    css笔记
    磁盘性能测试方法
  • 原文地址:https://www.cnblogs.com/Hades123/p/11432174.html
Copyright © 2011-2022 走看看