zoukankan      html  css  js  c++  java
  • VUE之指令,组件

    一:指令集

    (1)v-once

    (1)作用:

      (1)使得标签内部的属性一旦被赋值便不可以被更改

      (2)如果是input框 可以主动输入数据进行更改

    (2)使用方式

    <div id="app">
        <!--    其不加 v-once input框内数据可以更改-->
        <p><input type="text" v-model="num"></p>
        <!--    其加了v-once input框内数据不能随着别的数据变动而变动 但是可以主动变动-->
        <p><input type="text" v-model="num" v-once></p>
    <!--    无论标签内部数据是否变动 其都不会变动-->
        <p v-once>{{num}}</p>
    </div>
    </body>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                num: 0
            },
        })
    </script>
    v-once使用方式

    (2)v-cloak

    (1)作用:防止页面闪烁

    <style>
        [v-cloak] {
            display: none;
        }
    </style>
    <!-- 不处理的情况下,每次新价值该页面,都会先渲染{{}},当vue环境加载成功,{{}}有会被解析消失 -->
    <!-- 处理后,vue环境没加载好时,#app是被隐藏的,vue环境加载成功,会依次#app的v-cloak属性,就不会出现{{}}渲染闪烁问题 -->
    <div id="app" v-cloak>
        {{ }}
        {{ }}
        {{ }}
    </div>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
        })
    </script>
    v-cloak使用方式

    (3)v-if与v-show

    (1)作用:

      (1)可以控制标签的显隐

      (2)绑定的都是布尔值

      (3)v-if不会渲染标签 

      (5)v-show会以{display:none}的形式隐藏标签

    <div id="app">
        <!--    其下方布尔值对应为false不会再页面渲染出来 且检测内部html标签也不会被渲染-->
        <p v-if="is_show">if标签渲染</p>
        <!--    其下方布尔值对应为false不会再页面渲染出来 检测内部html标签会以display:none的形式渲染-->
        <p v-show="is_show">show标签渲染</p>
    </div>
    </body>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                is_show: false
            }
        })
    </script>
    v-if与v-show对比展示

    (4)v-if条件判断

    (1)作用:

      (1)类似于条件语句进行逻辑判断

    (2)使用方式:

    v-if = '布尔值'
    v-else-if = '布尔值'
    v-else 
    PS:v-else没有条件 上述条件都不成立 走else条件
    <div id="app">
    <!--    情况一 v-if布尔值为真 只有其才会进行页面渲染-->
        <p v-if="0">if条件语句运行</p>
    <!--    情况二 v-else-if布尔值为真 其余都为假 只有其才会进行页面渲染-->
        <p v-else-if="0">else-if条件语句运行</p>
    <!--    情况三 上述if条件都为假 else会进行渲染 且只要if条件对应的布尔值为假 无论else对应的布尔值如何 都会进行渲染-->
        <p v-else>else条件语句运行</p>
    </div>
    </body>
    <script>
        let app = new Vue({
            el: '#app',
        })
    </script>
    v-if基本使用方式
        <style>
            .box {
                width: 400px;
                height: 300px;
            }
    
            .r {
                background-color: red;
            }
    
            .y {
                background-color: yellow
            }
    
            .b {
                background-color: blue;
            }
    
        </style>
    </head>
    <body>
    <div id="app">
        <div class="em">
            <p>
                <!--            点击事件 此时点击红 页面显示红色框 以此类推-->
                <button @click="chang_box('rbox')"></button>
                <button @click="chang_box('ybox')"></button>
                <button @click="chang_box('bbox')"></button>
            </p>
            <!--    页面渲染三个框   根据showname对应的值不同进行不同的页面渲染 -->
            <div class="box r" v-if="showname=='rbox'"></div>
            <div class="box y" v-else-if="showname=='ybox'"></div>
            <div class="box b" v-else="showname=='bbox'"></div>
    
        </div>
    </div>
    </body>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                // 默认渲染红色
                showname: 'rbox'
            },
            methods: {
                // 上述点击事件会进行传参 当传参的参数赋值给函数 函数将传值赋值给showname
                chang_box(name) {
                    this.showname = name
                }
            }
        })
    </script>
    边框渲染LowB版本
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cn.vuejs.org/js/vue.min.js"></script>
        <style>
            .box {
                width: 400px;
                height: 300px;
            }
    
            .r {
                background-color: red;
            }
    
            .y {
                background-color: yellow
            }
    
            .b {
                background-color: blue;
            }
    
            .active {
                color: blueviolet;
            }
        </style>
    </head>
    <body>
    <div id="app">
        <div class="em">
            <p>
                <!--            根据布尔值判断这个按钮字体显示-->
                <button @click="changeBox('rbox')" :class="{active:showname=='rbox'}"></button>
                <button @click="changeBox('ybox')" :class="{active:showname=='ybox'}"></button>
                <button @click="changeBox('bbox')" :class="{active:showname=='bbox'}"></button>
    
            </p>
            <p>
                <!--            三元表达式 如果条件成立则给字体进行渲染 如果不成立则将页面置位空-->
                <button @click="changeBox('rbox')" :class="showname == 'rbox' ? 'active' : ''"></button>
                <button @click="changeBox('ybox')" :class="showname == 'ybox' ? 'active' : ''"></button>
                <button @click="changeBox('bbox')" :class="showname == 'bbox' ? 'active' : ''"></button>
            </p>
    
            <div class="box r" v-if="showname == 'rbox'"></div>
            <div class="box y" v-else-if="showname == 'ybox'"></div>
            <div class="box b" v-else></div>
        </div>
    </div>
    </body>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                // 默认渲染红色
                showname: 'rbox'
            },
            methods: {
                // 上述点击事件会进行传参 当传参的参数赋值给函数 函数将传值赋值给showname
                changeBox(name) {
                    this.showname = name
                }
            }
        })
    </script>
    </html>
    边框盒子渲染进阶版

    (5)v-pre

    (1)作用:让标签在受VUE控制区域内的标签 不受VUE控制

    <div id="app">
        <p>{{ msg }}</p>
        <!-- v-pre 指令可以在vue控制范围内,形成局部vue不控制区域
        {{ }} 和 v-if 都会原样输出,不会被解析
        -->
        <p v-pre>
            {{ }}
            <span v-if="hehe"></span>
        </p>
    </div>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: 'message'
            }
        })
    </script>
    Vv-pre

    (6)v-for

    (1)作用:对语句进行for循环

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cn.vuejs.org/js/vue.min.js"></script>
    </head>
    <body>
    <div id="app">
        <div>
            <!--        基础使用方式-->
            <span v-for="ch in str">{{ ch }}</span>
        </div>
        <div>
            <!--针对循环遍历的标签 ch循环的一个个原素 index索引,通过会提供key属性来优化渲染速度,但key的值必须唯一(key可以不用提供) -->
            <span v-for="(ch, index) in str" :key="ch + index">{{ index }}{{ ch }}</span>
        </div>
        <div>
            <!--          便利字典对应的value-->
            <p v-for="ele in dic">{{ ele }}</p>
        </div>
        <div>
            <!--          便利 key,value-->
            <p v-for="(ele, k) in dic">{{ k }}:{{ ele }}</p>
        </div>
        <div>
            <!--            便利key value index-->
            <p v-for="(ele, k, i) in dic">{{ i }}{{ k }}:{{ ele }}</p>
        </div>
    </div>
    </body>
    <script>
        new Vue({
            el: '#app',
            data: {
                str: '鸡你太美啊!',
                arr: [3, 4, 1, 2, 5],
                dic: {
                    name: 'SR',
                    age: 18,
                    gender: '男神',
                }
            }
        })
    </script>
    </html>
    v-for使用方式
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cn.vuejs.org/js/vue.min.js"></script>
        <style>
            li:hover {
                color: red;
                cursor: pointer;
    
            }
            li{
                  list-style: none;
            }
        </style>
    </head>
    <body>
    <div id="app">
        <p>
            <input type="text" v-model="userMsg">
            <button @click="sendMsg" type="button">留言</button>
        <ul>
            <li v-for="(msg, index) in msgs" @click="deleteMsg(index)">{{index}}:{{msg}}</li>
        </ul>
        </p>
    </div>
    </body>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                // 三元表达式 判断存储数据库中是否有数据 如果有则渲染出来
                msgs: localStorage.msgs ? JSON.parse(localStorage.msgs) : [],  // 存储用户留言
                userMsg: ''  // 用户留言
            },
            methods: {
                sendMsg() {
                    // 尾增
                    // this.msgs.push(this.userMsg);
                    // 首增
                    // this.msgs.unshift(this.userMsg);
    
                    let userMsg = this.userMsg;  // 获取用户输入的值
                    if (userMsg) {
                        this.msgs.unshift(userMsg);  // 列表首增用户输入数据
                        localStorage.msgs = JSON.stringify(this.msgs);  // 将数据已字符串格式存入前段数据库
                        this.userMsg = '' // 清空用户的留言框
                    }
                },
                deleteMsg(index){
                    // 从索引位置开始操作 操作1位 没有操作结果
                    this.msgs.splice(index,1)  // 开始索引  操作长度  操作的结果们
                }
    
            }
        })
    </script>
    </html>
    todolist

    二:属性

    (1)计算属性

    (1)特点

      (1)computed用来声明方法属性的

      (2)声明的方法属性 不能与data中定义的重复

      (3)方法属性必须在页面中渲染 才会对内部的出现的变量进行监听

      (4)计算属性的值 来源于监听方法的返回值

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cn.vuejs.org/js/vue.min.js"></script>
    </head>
    <body>
    <div id="app">
        姓:<input type="text" v-model="fName">
        名:<input type="text" v-model="lName">
        姓名:<b>{{ flName }}</b>
    </div>
    </body>
    <script>
        let app = new Vue({
            el:'#app',
            data:{
                fName:'',
                lName:'',
            },
            computed:{
                flName(){
                     // fName 与 lName 值发生改变 该方法就会触发
                    // 计算属性的值 来源于该函数的返回值  flName
                    return this.fName + this.lName
                }
            }
        })
    </script>
    </html>
    computed方法属性

    (2)监听属性

      (1)watch为data中已存在的属性设置监听事件

      (2)监听属性值发生改变 就会触发该方法

      (3)监听事件方法的返回值 无任何意义

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cn.vuejs.org/js/vue.min.js"></script>
    </head>
    <body>
    <div id="app">
        姓名:<input type="text" v-model="fullName">
        姓:<b>{{ firstName }}</b>
        名:<b>{{ lastName }}</b>
    </div>
    </body>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                fullName: '',
                firstName: '',
                lastName: '',
            },
            watch:{  // 监听事件的开启方式
                fullName(){
                    nameArr = this.fullName.split('');  // 字符串切换列表
                    this.firstName = nameArr[0];
                    this.lastName = nameArr[1];
                }
            }
    
        })
    </script>
    </html>
    监听事件

    三:组件

    (1)基本概念

    (1)定义:一个包含html + css + js的集合体属于一个组件

    (2)分类

      (1)根组件:属于new Vue()产生的组件 在项目开发中一个项目 只有一个组件

      (2)全局组件:不用注册就可以成为任何一个组件的子组件

      (3)局部组件:需要注册才能成为局部组件的一个子组件

    (3)特点

      (1)每一个组件都包含自己的 html + css + js逻辑

      (2)每一个组件都有自己template模板 用来标识自己html结构

      (3)每一个template只有一个根标签

      (4)根组件一般不提供template模板 就是由真实的挂载点提供

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cn.vuejs.org/js/vue.min.js"></script>
    </head>
    <body>
    <div id="app">
        {{msg}}
    </div>
    </body>
    <script>
        let app = new Vue({
            el: '#app',
            data: {
                msg: '组件'
            },
            template: `
    
            <div> </div>>  // 此时不会被渲染 在加载顺序的时候 其会有限加载虚拟模板 而不是dom内部数据 导致上述内部数据消失
    
        <div>{{msg}}</div>  // 其会被加载
        <div>{{msg}}</div>  // 其不会被加载 一个模板下只有一个根标签
            `
        })
    </script>
    </html>
    组件特点展示

    (2)局部组件

    (1)创建局部组件

    (2)注册局部组件

    (3)调用局部组件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cn.vuejs.org/js/vue.min.js"></script>
        <style>
            .box {
                box-shadow: 0 3px 5px 0 #666;
                width: 240px;
                height: 300px;
                text-align: center;
                padding: 20px 0;
                float: left;
                margin: 5px;
            }
    
            .box img {
                width: 200px;
            }
        </style>
    </head>
    <body>
    <div id="app">
        <!--    调用局部组件 因为含有大写字母 此时标签不能识别大写字母 因此需要使用--->
        <local-tag></local-tag>
        <local-tag></local-tag>
    </div>
    </body>
    <script>
        // 定义局部组件 给局部组件命名
        let localTag = {
            template: `
            <div class="box">
            <img src="img/001.png" alt="">
            <h3>猫星人</h3>
             <p>猫星人❤猫星人</p>
            </div>
            `
        };
        let app = new Vue({
            el: '#app',
            // 注册局部组件
            components: {
                localTag  // 等价于 localTag:localTag
            }
        })
    </script>
    </html>
    局部组件

    (3)全局组件

    (1)创建全局组件

    (2)父组件之间调用

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cn.vuejs.org/js/vue.min.js"></script>
        <style>
            .box {
                box-shadow: 0 3px 5px 0 #666;
                width: 240px;
                height: 300px;
                text-align: center;
                padding: 20px 0;
                float: left;
                margin: 5px;
            }
    
            .box img {
                width: 200px;
            }
    
        </style>
    </head>
    <body>
    <div id="app">
        <!--    调用局部组件 因为含有大写字母 此时标签不能识别大写字母 因此需要使用--->
        <global-tag></global-tag>
        <global-tag></global-tag>
        <global-tag></global-tag>
        <global-tag></global-tag>
    
    </div>
    </body>
    <script>
        // 定义全局组件 给局部组件命名
        Vue.component('global-tag', {
            template: `
            <div class="box" @click="action">
            <img src="img/001.png" alt="">
            <p>猫星人</p>
             <p >猫星人❤{{num}}</p>
            </div>>
            `,
            data() {
                // 给上述的爱心赋值 使用返回值的原因是因为 有多个图片每个对应自己独立的
                return {
                    num: 0
                }
            },
            methods: {
                action() {
                    this.num++
                }
            }
        });
    
        let app = new Vue({
            el: '#app',
            // 注册局部组件
    
        })
    </script>
    </html>
    全局组件

     三:组件交互

     (1)父传子

    (1)基本思路:数据交互 - 父传子 - 通过绑定属性的方式

      (1)父组件提供数据

      (2)父组件模板中 子组件设置自定义属性 绑定的值由父组件提供

      (3)通过props获得自定义的属性

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cn.vuejs.org/js/vue.min.js"></script>
        <style>
            .info {
                text-align: center;
                width: 200px;
                padding: 3px;
                box-shadow: 0 3px 5px 0 pink;
                float: left;
                margin: 5px;
            }
    
            .info img {
                width: 200px;
            }
        </style>
    </head>
    <body>
    <div id="app">
            <!--  在父组件模板中,为子组件标签设置自定义属性,绑定的值由父组件提供 -->
        <!--    my_info属于自定义属性 其值是便利出来的-->
        <info v-for="info in infos" :key="info.image" :my_info="info"></info>
    </div>
    </body>
    <script>
        // 给所有被渲染的图片打印信息
        let infos = [
            {
                image: 'img/001.png',  // 这些都是图片路径
                title: '猫星人'
            },
            {
                image: 'img/002.png',
                title: '蛋糕'
            },
            {
                image: 'img/003.png',
                title: '蓝糕'
            },
            {
                image: 'img/004.png',
                title: '二哈'  // 图片命名
            },
        ];
    
        let info = {
            template: `
            <div class="info">
    
            <img :src="my_info.image" alt="">
            <p>{{my_info.title}}</p>
    </div>
    
    
            `,
            props: ['my_info']  // 通过反射获取上述变量info
        };
        let app = new Vue({
            el: '#app',
            components: {
                info  // 注册局部组件
            },
            data: {
                // 为上述组件 提供数据
                infos
            }
        })
    
    </script>
    </html>
    父传子

    (2)子传父

    (1)基本思路

      (1)数据由子组件提供

      (2)子组件内部通过触发系统事件,发送一个自定义事件,将数据携带出来

      (3)父组件位子组件标签的自定义属性通过方法实现,就可以通过参数拿到子组件传递处理的参数

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cn.vuejs.org/js/vue.min.js"></script>
        <style>
            .close:hover {
                cursor: pointer;
                color: red;
            }
    
            li {
                list-style: none;
            }
        </style>
    </head>
    <body>
    <div id="app">
        <p>
            <input type="text" v-model="userMsg">
            <button @click="sendMsg">留言</button>
        </p>
        <ul>
    <!--        子组件通过触发系统事件 发送一个自定义事件 将数据携带过来 自定义事件remove_msg-->
            <msg-li v-for="(msg,index) in msgs " :msg='msg' :index='index' @remove_msg="removeAction"></msg-li>
    
        </ul>
    </div>
    </body>
    <script>
        let msgLi = {
            template: `
               <li>
                <span class="close" @click="deleteMsg(index)">x </span>
                <span>第{{ index + 1 }}条:</span>
                <span>{{ msg }}</span>
              </li>
    
            `,
            props: ['msg', 'index'],
            methods: {
                    // 自定一个系统事件 传递参数
                deleteMsg(index) {
                // 数据由子组件提供  index
                    this.$emit('remove_msg', index);
                }
            }
        };
        let app = new Vue({
            el: '#app',
            data: {
                msgs: [],
                userMsg: ''
            },
            components: {
                msgLi
            },
            methods: {
                sendMsg() {
                    if (this.userMsg) {
                        this.msgs.unshift(this.userMsg);
                        this.userMsg = ''
                    }
                },
                // 拿到上述自定义事件remove_msg传递过来的参数 index
                removeAction(index) {
                    this.msgs.splice(index, 1)
                }
            }
        })
    </script>
    </html>
    子传父
  • 相关阅读:
    洛谷 P3128 [ USACO15DEC ] 最大流Max Flow —— 树上差分
    洛谷 P3953 [ NOIP 2017 ] 逛公园 —— 最短路DP
    bzoj 3231 [ Sdoi 2008 ] 递归数列 —— 矩阵乘法
    bzoj 1024 [ SCOI 2009 ] 生日快乐 —— 递归
    hdu 5823 color II —— 子集DP
    bzoj 1093 [ ZJOI 2007 ] 最大半连通子图 —— 拓扑+DP
    洛谷 P3959 NOIP2017 宝藏 —— 状压搜索
    最短路(模板
    线段树 扫描线
    Dijkstra算法
  • 原文地址:https://www.cnblogs.com/SR-Program/p/11643952.html
Copyright © 2011-2022 走看看