zoukankan      html  css  js  c++  java
  • Vue初识

    一.  Vue的简单介绍

      前端、django的重点简单描述:

    """
    1、BBS:前后台不分离的web项目
        前台页面主要是通过后台逻辑完成渲染
    2、Django:Python Web 框架
        HttpResponse | ORM | 模板语言 | Forms | Auth
    3、前端:HTML5 CSS3 JavaScript jQuery Bootstrap
        HTML5:页面架构
        CSS3:选择器 样式 布局
        JS:ES DOM BOM => 选择器拿到标签,操作标签,标签事件完成交互
        
    DOM驱动 => Vue数据驱动
    """

      前后端不分离值得是前端的数据都是由后端用语法渲染出来的,比如Django的render、redirect等,前端页面都是由它们渲染好然后返回的。前后端分离值得是前端后端服务器不同,各写各的,仅仅只进行数据的交互。前后端分离对于Django来说稍微麻烦一点,因为csrf跨站请求伪造的存在,Django无法从不是它渲染的页面中拿到csrf_token,这就意味着前后端分离时,Django需要注释掉csrf中间件,然后需要我们自己写对应的验证。

      vue框架:

    # Angular React Vue
    
    # js渐进式框架:一个页面小到一个变量,大到整个页面,均可以有vue控制,vue也可以控制整个项目
    
    # 思考:vue如何做到一次引入控制整个项目 => 单页面应用 => vue基于组件的开发
        # vue的工作原理:vue如何渲染一个页面
        # vue的组件概念
        # vue路由的概念
        # vue的ajax概念
    # 学习曲线:vue的指令 vue的实例成员  vue组件  vue项目开发

      vue的优点:

    """
    1.单页面:高效
    2.虚拟DOM:页面缓存
    3.数据的双向绑定:数据是具有监听机制
    4.数据驱动:从数据出发,不是从DOM出发 
    """

    1.1 vue的使用

    """
    1.下载vue.js:https://vuejs.org/js/vue.js
    2.在要使用vue的html页面通过script标签引入
    3.在html中书写挂载点的页面结构,用id表示
    4.在自定义的script标签实例化Vue对象,传入一个大字典
    5.在字典中通过 el与挂载点页面结构绑定,data为其通过数据
    """

       当然可以使用cdn,也可以直接在官网将vue的代码复制下来, 然后新建一个js文件黏贴即可。具体步骤如下:

    • 按住ctrl + 鼠标左键 点击开发版本

    • 然后将其中的代码复制后在项目中新建一个js文件保存,后面直接再要使用的项目中script标签导入即可。

    二. vue的简单使用

      无论在使用一个框架还是一门开发语言,最重要的就是要学会看官方的文档,建议每天学习一下英语,达到能够阅读英语文档的能力。vue文档链接:https://cn.vuejs.org/v2/guide/index.html

    2.1 vue初识

      vue是通过new来实例化一个对象,然后该对象里面通过el来添加挂载点,data来给变量提供数据,methods来给挂载点提供事件。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue初始</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div id="app">
         <!-- {{ vue变量 }} 插值表达式 里面的大括号最好在前面加个空格,增加浏览器的兼容性 -->
        <h1>{{ msg1 }}</h1>
        <h2>{{ msg2 }}</h2>
    </div>
    <!--
        vue挂载点一次只能挂载一个,比如很多标签都继承同一个类,使用类选择器时,
        vue只会挂载找到的第一个标签,所以最好都使用标签选择挂载点
    -->
    <!--<div class="app">-->
        <!--<h1>{{ msg1 }}</h1>-->
        <!--<h2>{{ msg2 }}</h2>-->
    <!--</div>-->
    </body>
    <!--将script写在body下面比较保险,可以不用考虑加载时从上往下执行可能发生的问题-->
    <script src="vue.js"></script>
    <script>
        // Vue
        new Vue({
            el: '#app', //挂载点
            data: {
                // 给各变量提供数据 变量名:变量的值
                //vue的实例data中键值对,其实 键 都是字符串,只是省略了引号
                msg1: 'h1的内容',
                msg2: 'h2的内容',
            },
            methods:{
                //为挂载点提供事件 函数名: function(){}
            }
        })
    </script>
    </html>

     2.2 vue完成简单的事件

      vue是通过以下方式来给标签绑定事件:

    <!--绑定事件语法 v-on:事件名='函数名' -->
    <p v-on:click="clickMe">点我</p>
    <!--绑定事件语法简写 @事件名='函数名' -->
    <p @click="clickMe2">你也点我一下</p>

       然后在vue对象的methods中写函数名与对应实现体的逻辑即可,具体代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue完成简单的事件</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div id="app">
        <!--绑定事件语法 v-on:事件名='函数名' -->
        <p v-on:click="clickMe">点我</p>
        <!--绑定事件语法简写 @事件名='函数名' -->
        <p @click="clickMe2">你也点我一下</p>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            methods: { // 为挂载点提供事件
                clickMe : function () {
                    alert(1111)
                },
                clickMe2: function () {
                    alert(2222)
                }
            }
        })
    </script>
    </html>

     2.3 vue简单操作样式

      vue操作样式是通过控制标签的属性来实现的,控制样式通过以下方式:

    <!-- 属性指令:用vue绑定属性,将属性内容交给vue处理 -->
    <!-- 语法:v-bind:属性名="变量"  (v-bind: 可以简写为 :) -->
    <p @click="clickMe" v-bind:style="col">点击当场变绿</p>

      当然还可以给样式写成字典的形式,通过不同变量控制不同的样式:

    <!-- 一个{}:{}内一个个属性有一个个变量单独控制 -->
    <!--这里只需在data中定义col与fs两个变量的值即可-->
    <p @click="clickMe" v-bind:style="{color: col,'font-size': fs}">点击当场变绿</p>

      注意,以上font-size不加引号时需要写为驼峰体:fontSize。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue操作样式</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div id="app">
        <p @click="clickMe" v-bind:style="col">点击当场变绿</p>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
              // 需要以字典的形式改值,因为style是color:red;的形式
              col: {color: 'green'}
            },
            methods: {
                clickMe: function () {
                    //this代表的是整个vue对象
                    this.col = {color: 'red'}
                }
            }
        })
    </script>
    </html>
    小例子一
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>操作样式</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div id="app">
        <!-- 一个{}:{}内一个个属性有一个个变量单独控制 -->
        <p @click="clickMe" v-bind:style="{color: col,'font-size': fs}">点击当场变绿</p>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                fs: '20px',
                col: 'green',
            },
            methods: {
                clickMe: function () {
                    this.col = 'red';
                    this.fs = '25px';
                }
            }
        })
    </script>
    </html>
    小例子二

    2.4 文本指令

      vue通过以下方式来实现文本指令:

     <!-- 插值表达式就是 v-text -->
    <p>{{ msg1 }}</p>
    <p v-text="msg2"></p>
    
    <!-- 可以解析html标签 -->
    <p v-html="msg3"></p>
    
    <!-- 必须赋初值,渲染的结果永远不会发生改变 -->
    <p v-once="msg3" @click="clickMe">{{ msg3 }}</p>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>文本指令</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div id="app">
         <!-- 插值表达式就是 v-text -->
        <p>{{ msg1 }}</p>
        <p v-text="msg2"></p>
    
         <!-- 可以解析html标签 -->
        <p v-html="msg3"></p>
    
        <!-- 必须赋初值,渲染的结果永远不会发生改变 -->
        <p v-once="msg3" @click="clickMe">{{ msg3 }}</p>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
              msg1:'**msg1**',
              msg2:'<h2>msg2</h2>',
              msg3:'<h2>msg3</h2>',
            },
            methods:{
                clickMe:function () {
                    // var msg = this.$data.msg3;
                    // 实例中要访问一阶变量比如el、data等,需要加$,this.$el,
                    // 一般要访问二阶的直接this.二阶变量 即可
                    this.msg3 = '<h2>msg3666</h2>'
                }
            }
        })
    </script>
    </html>
    小例子

    2.5 事件指令

      前面稍微提了以下vue简单的事件绑定,这里再来看看:

     <!-- v-on:事件名="函数名"  可以简写为 @事件名="函数名"  (v-on: => @)-->
    <p v-on:click="action1">{{ msgs[0] }}</p>
    <p @click="action2">{{ msgs[1] }}</p>

       实际上,当绑定事件的时候是可以给函数传参的,在函数名后面加个括号表示传参,而且默认是有一个event对象传过去的,当加了括号之后,无论你传多少参数,都需要加一个参数$event,不然event对象就会失效。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>事件指令</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <ul id="app">
        <!-- v-on:事件名="函数名"  可以简写为 @事件名="函数名"  (v-on: => @)-->
        <!-- 事件的传参 -->
        <li @click="action(111)">列表项1</li>
        <li @click="action(222)">列表项2</li>
        <li @click="action(333)">列表项3</li>
        <li @click="actionMouse">列表项4</li>
    
         <!-- 鼠标事件的对象:直接写函数名,默认将鼠标事件对象传入 -->
        <div @click="func1">func1</div>
        <!-- 鼠标事件的对象:一旦添加(),就必须手动传参,$event就代表鼠标事件对象 -->
        <div @click="func2($event, 'abc')">func2</div>
    </ul>
    </body>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            methods:{
                action:function (num) {
                    alert(num)
                },
                actionMouse:function (event) {
                    console.log(event)
                },
                func1: function (ev) {
                    console.log(ev)
                },
                func2: function (ev, msg) {
                    console.log(ev);
                    console.log(msg)
                }
            }
        })
    </script>
    </html>
    小例子

    2.6 属性指令

       vue属性指令通过以下方式实现:

    <!-- 属性指令:用vue绑定属性,将属性内容交给vue处理 -->
    <!-- 语法:v-bind:属性名="变量"  (v-bind: 可以简写为 :) -->
    <p class="" style="" v-bind:owen="oo" :jason="jj"></p>

       当“”中再以''将变量放在里面是,变量就不再时变量,而是常量:

    <!-- br'是变量 -->
    <p :class="[c1, 'br']"></p>
    <!-- 'br' 固定写死的数据,不再是变量 -->
    <p :class="[c1, 'br']"></p>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>属性指令</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <style>
            div {
                width: 100px;
                height: 100px;
            }
            .gDiv {
                background-color: green;
            }
            .rDiv {
                background-color: red;
            }
            .br {
                border-radius: 50%;
            }
        </style>
    </head>
    <body>
    <div id="app">
        <div @click="clickMe" :class="c1"></div>
        <!-- 属性指令:用vue绑定属性,将属性内容交给vue处理 -->
        <!-- 语法:v-bind:属性名="变量"  (v-bind: 可以简写为 :) -->
        <div :class="[c1, c2]"></div>
        <!-- 'br' 固定写死的数据,不再是变量 -->
        <div :class="[c1, 'br']"></div>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el:'#app',
            data:{
                c1: 'rDiv',
                c2: 'br'
            },
            methods:{
                clickMe:function () {
                    if(this.c1=='rDiv'){
                        this.c1='gDiv'
                    }else {
                        this.c1 = 'rDiv'
                    }
                }
            }
        })
    </script>
    </html>
    小例子

    2.7 表单指令

      属性指令是通过on-bind或者是简写:来实现,但是在form表单中,value属性要使用on-model来实现控制:

    <!-- 表单指令:v-model="变量" -->
    <input type="text" v-model="val">
    
    <!-- 单选框 v-model绑定的变量是单选框中某一个input的value -->
    <p>
         男: <input v-model="r_val" value="male" type="radio" name="sex">
           女: <input v-model="r_val" value="female" type="radio" name="sex">
    </p>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>表单指令</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <!-- 表单指令:v-model="变量" -->
    <form id="app">
        <p>username<input v-model="val" type="text" name="username"></p>
        <p>re_username<input v-model="val" type="text" name="re_username"></p>
        <div>
            <!-- 单选框 v-model绑定的变量是单选框中某一个input的value --><input  v-model="sex" type="radio" name="sex" value="male"><input  v-model="sex" type="radio" name="sex" value="female">
        </div>
        <div>
            <!-- 复选框 v-model绑定的变量是一个列表,列表存存放0到任意个复选框的value  --><input  v-model="hobby" type="checkbox" name="hobby" value="male"><input  v-model="hobby" type="checkbox" name="hobby" value="female">
            哇塞<input  v-model="hobby" type="checkbox" name="hobby" value="ws">
        </div>
        <button>提交</button>
    </form>
    </body>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data:{
                val:'',
                sex:'male',
                hobby:['male', 'female'],
            }
        })
    </script>
    </html>
    表单指令的小例子

    2.8 条件指令

      条件指令分为两种:

    <!-- 条件指令 v-show | v-if-->
    <!-- v-show:消失是以 display: none渲染 当v-show的值为false时触发 -->
    <div v-show="s1"></div>
    <!-- v-if:消失时不会被渲染渲染,所以建议建立缓存, 用key属性 -->
    <div class="wrap red" v-if="tag==0" :key="0"></div>
    <div class="wrap green" v-else-if="tag==1" :key="1"></div>
    <div class="wrap blue" v-else key="2" :key="'2"></div>
    <!-- v-if相关分支操作,在未显示情况下,是不会被渲染到页面中 -->
    <!-- 通过key全局属性操作后,渲染过的分支会建立key对应的缓存,提高下一次渲染速度 -->

       条件指令中v-show和v-if的循环,里面是可以直接写false或true的,他们会自动解析为布尔值,不会将它们当做变量。

      v-show不写条件默认是false,即display:none隐藏标签。

      v-else会默认与v-if等有条件的分支绑定。

      v-else-if必须有条件才和有条件v-if分支绑定。

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>模板</title>
    </head>
    <body>
    <div id="app">
        <p v-if="r1" key="p_r1">if条件</p>
        <p v-show="r2">show条件</p>
        <!--{{ num + 1 - 5 * 2 + '好的' }}-->
        
        
        <ul>
            <!--v-else会默认与v-if等有条件的分支绑定-->
            <!--v-else-if必须由条件才和有条件v-if分支绑定-->
            <!--可以删除各分支的条件来进行验证-->
            <li v-if="tag == 1">111</li>
            <li v-else-if="tag == 2">222</li>
            <li v-else>333</li>
        </ul>
    
    
        <ul>
            <li @click="action('a')">a</li>
            <li @click="action('b')">b</li>
            <li @click="action('c')">c</li>
        </ul>
        <ul>
            <li v-show="flag == 'a'">aaa</li>
            <li v-show="flag == 'b'">bbb</li>
            <li v-show="flag == 'c'">ccc</li>
        </ul>
    </div>
    </body>
    <script src="js/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                num: 10,
                r1: false,
                r2: false,
                tag: 2,
                flag: 'a'
            },
            methods: {
                action: function (s) {
                    this.flag = s
                }
            }
        })
    </script>
    </html>
    分支绑定验证
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>条件指令</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <style>
            .wrap {
                width: 300px;
                height: 100px;
            }
            .red {background-color: red;}
            .green {background-color: green;}
            .blue {background-color: blue;}
        </style>
    </head>
    <body>
    <div id="app">
        <!-- 条件指令 v-show | v-if-->
        <!-- v-show:消失是以 display: none渲染 当v-show的值为false时触发 -->
        <div v-show="s1"></div>
        <ul>
            <li @click="action(0)" style="float: left">red</li>
            <li @click="action(1)" style="float: left">green</li>
            <li @click="action(2)" style="float: left">blue</li>
        </ul>
         <!-- v-if:消失时不会被渲染渲染,所以建议建立缓存, 用key属性 -->
        <div class="wrap red" v-if="tag==0" key="0"></div>
        <div class="wrap green" v-else-if="tag==1" key="1"></div>
        <div class="wrap blue" v-else key="2" key="'2"></div>
        <!-- v-if相关分支操作,在未显示情况下,是不会被渲染到页面中 -->
        <!-- 通过key全局属性操作后,渲染过的分支会建立key对应的缓存,提高下一次渲染速度 -->
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data:{
                tag:0,
                s1:false
            },
            methods:{
                action:function (tag) {
                    this.tag=tag
                }
            }
        })
    </script>
    </html>
    小例子

     2.9 循环指令

      循环指令语法如下:

    <!-- v-for="item in items" -->
    <!-- 遍历的对象: 数组[] 对象(字典){} -->

      当遍历数组时,可以用两个参数来获取值与索引:

    <!-- n为遍历的元素值 -->
    <ul>
          <li v-for="n in list">{{ n }}</li>
    </ul>
    
    
    <!-- n为遍历的元素值, index为索引 -->
    <ul>
          <li v-for="(n, index) in list">{{ n }}{{ index }}</li>
    </ul>

      当遍历自定义对象{}时,可以有三个参数:

    <!-- v-for变量对象{}时,接收三个值时,第一个为元素值,第二个为元素键,第三个为元素索引 -->
    <ul>
         <li v-for="(v, k, i) in dic" :key="k">value:{{ v }} | key:{{ k }} | index: {{ i }}</li>
    </ul>

      在很多时候,为了增加渲染的速度,需要建立缓存:

    <!-- 一般列表渲染需要建立缓存 -->
    <!-- 列表渲染是循环,需要赋值变量给key,使用key需要v-bind:处理 -->
    <!-- v-for变量数组[]时,接收两个值时,第一个为元素值,第二个为元素索引 -->
    <ul>
         <li v-for="(n, i) in list" :key="i">value:{{ n }} | index: {{ i }}</li>
    </ul>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>循环指令</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div id="app">
        <!-- v-for="item in items" -->
        <!-- 遍历的对象: 数组[] 对象(字典){} -->
        <ul>
            <!-- 只遍历数组的值 -->
            <li v-for="num in nums">{{ num }}</li>
        </ul>
    
        <ul>
            <!-- 遍历数组的值与索引 -->
            <li v-for="(num, index) in nums">{{ num }}&nbsp;{{ index }}</li>
        </ul>
    
        <ul>
            <!-- 自定义对象(字典)的 值、键、索引 -->
            <li v-for="(v, k, index) in dic">{{ v }}&nbsp;{{ k }}&nbsp;{{ index }}</li>
        </ul>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data:{
                nums:[5, 2, 3, 1, 4],
                dic:{
                    name: 'json',
                    age: '18',
                    gender: 'male'
                }
            },
        })
    </script>
    </html>
    小例子
    <div id="app">
        <h1>{{ msg }}</h1>
        <!-- v-for="item in items" -->
        <!-- 遍历的对象: 数组[] 对象(字典){} -->
        <ul>
            <li>{{ list[0] }}</li>
            <li>{{ list[1] }}</li>
            <li>{{ list[2] }}</li>
            <li>{{ list[3] }}</li>
            <li>{{ list[4] }}</li>
        </ul>
    
        <!-- n为遍历的元素值 -->
        <ul>
            <li v-for="n in list">{{ n }}</li>
        </ul>
    
        <!-- 一般列表渲染需要建立缓存 -->
        <!-- 列表渲染是循环,需要赋值变量给key,使用key需要v-bind:处理 -->
        <!-- v-for变量数组[]时,接收两个值时,第一个为元素值,第二个为元素索引 -->
        <ul>
            <li v-for="(n, i) in list" :key="i">value:{{ n }} | index: {{ i }}</li>
        </ul>
    
        <ul>
            <li>{{ dic['name'] }}</li>
            <li>{{ dic.age }}</li>
            <li>{{ dic.gender }}</li>
        </ul>
    
        <!-- v-for变量对象{}时,接收三个值时,第一个为元素值,第二个为元素键,第三个为元素索引 -->
        <ul>
            <li v-for="(v, k, i) in dic" :key="k">value:{{ v }} | key:{{ k }} | index: {{ i }}</li>
        </ul>
    
    
        <!-- 遍历的嵌套 -->
        <div v-for="(person, index) in persons" :key="index" style="height: 21px;">
            <div v-for="(v, k) in person" :key="k" style="float: left;">{{ k }} : {{ v }}&nbsp;&nbsp;&nbsp;</div>
        </div>
    </div>
    <script type="text/javascript">
        new Vue({
            el: "#app",
            data: {
                msg: "列表渲染",
                list: [1, 2, 3, 4, 5],
                dic: {
                    name: 'zero',
                    age: 88888,
                    gender: 'god'
                },
                persons: [
                    {name: "zero", age: 8},
                    {name: "egon", age: 78},
                    {name: "liuXX", age: 77},
                    {name: "yXX", age: 38}
                ]
            }
        })
    </script>
    内含循环的嵌套
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>发表评论示例</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <style>
            span {
                margin-left: 100px;
            }
            /*利用伪类选择器,鼠标悬浮是将字体颜色变为红色*/
            span:hover {
                color: red;
            }
        </style>
    </head>
    <body>
    <div id="app">
        <input type="text" v-model="val">
        <button @click="action">提交评论</button>
        <ui>
            <!--将索引拿出当做事件函数的参数,方便删除-->
            <li v-for="(msg, index) in msgs">{{ msg }}<span @click="del(index)">X</span></li>
        </ui>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                val: '', //存放即将发表的评论内容
                msgs: ['hello', 'world'], //存放评论
            },
            methods:{
                action:function () {
                    //其实splice可完成数组的增删改,他有三个参数,第一个是从哪个索引开始(不包含当前索引)
                    //第二个参数是操作几个值,第三个参数是将操作的值替换为什么,不写则替换为空,相当于删除
                    this.msgs.splice(0,0,this.val);
                    this.val = '' //输入评论框置空
                },
                del:function (index) {
                    this.msgs.splice(index,1) //删除留言
                }
            }
        })
    </script>
    </html>
    发表评论小例子

    三. 实例成员computed、watch

      前面实例成员用到了el、data、methods,接下来再补充一下computed、watch,它们的作用都是监听,但是监听的对象是相反的,computed监听函数内的变量,watch监听函数外的变量。

    3.1 computed

      监听方法内所有的变量,返回值给绑定的变量,该变量无需在data中声明,只要里面监听的变量值发生变化,就会马上执行一次该函数。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>实例成员之computed</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div id="app">
        姓:<input type="text" v-model="first_name">
        名:<input type="text" v-model="last_name">
    
        <p style="margin-top: 5px">姓名:<input type="text" v-model="full_name"></p>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el:'#app',
            data:{
                first_name: '',
                last_name: '',
            },
            /*
                计算 -- 监听方法内所有的变量,返回值给绑定的变量,该变量无需在data中声明,
                只要里面监听的变量值发生变化,就会马上执行一次该函数
            */
            computed:{
                full_name:function () {
                    return this.first_name + this.last_name
                }
            }
        })
    </script>
    </html>
    小例子

    3.2 watch

      监听绑定的变量,绑定的变量必须在data中声明,只要监听的变量值发生变化,就会立马执行该函数,该函数的返回值是没有任何意义的,所以不需要return。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>实例成员之watch</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div id="app">
        <p>姓名:<input type="text" v-model="full_name"></p>
        姓:<input type="text" v-model="first_name">
        名:<input type="text" v-model="last_name">
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data:{
                first_name:'',
                last_name:'',
                full_name:''
            },
            watch:{
                /*
                     监听绑定的变量,绑定的变量必须在data中声明,
                     只要监听的变量值发生变化,就会立马执行该函数,
                     该函数的返回值是没有任何意义的,所以不需要return
                */
                full_name:function () {
                    //前端支持切分空 'abc' ->> ['a', 'b', 'c']
                    //python不支持切分空,会报错,不过可以通过list('abc')达到同样的效果
                    let name = this.full_name.split('');
                    this.first_name = name[0];
                    this.last_name = name[1];
                }
            }
        })
    </script>
    </html>
    小例子

    3.3 delimiters

      使用Django时,前往模板渲染语法用的是{{  }},而vue的插值表达式也是一样,所以一起使用时会存在冲突的问题。这时候就需要用到delimiters来改变插值表达式的语法:

    // 为解决与前端模板语法的冲突,可以使用delimiters自定义插值表达式的语法
    // delimiters:['插值表达式前半部分', '后半部分']
    delimiters:['${', '}']
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>解决插值表达式冲突</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div id="app">
        <p>{{ msg }}</p>
        <p>${ msg }</p>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                msg: 'hello world'
            },
            // 为解决与前端模板语法的冲突,可以使用delimiters自定义插值表达式的语法
            delimiters:['${', '}']
        })
    </script>
    </html>
    小例子

    四. 组件

      组件的概念

    • 每一个组件都是一个vue实例

    • 每个组件均具有自身的模板template,根组件的模板就是挂载点

    • 每个组件模板只能拥有一个根标签

    • 子组件的数据具有作用域,以达到组件的复用

      使用vue时,实际项目中大多使用局部组件。局部组件与全局组件都拥有各自的名称空间,这是通过将成员data的值赋予一个return 字典 的的function来实现的。

    4.1 根组件

      根组件就是我们使用挂载点生成的vue实例:

    <div id="app">
        <h1>{{ msg }}</h1>
    </div>
    <script type="text/javascript">
        // 通过new Vue创建的实例就是根组件(实例与组件一一对应,一个实例就是一个组件)
        // 每个组件均拥有模板,template
        var app = new Vue({
            // 根组件的模板就是挂载点
            el: "#app",
            data : {
                msg: "根组件"
            },
            // 模板: 由""包裹的html代码块,出现在组件的内部,赋值给组件的$template变量
            // 显式书写模块,就会替换挂载点,但根组件必须拥有挂载点
            template: "<div>显式模板</div>"
        })
        // app.$template
    </script>

      其中html与body不能作为挂载点,因为显式书写模块会替换挂载点,而html与body是不能被替换,会报错。这里挂载点使用通用选择器时会从上往下,将找到的第一个标签作为挂载点,而第一个标签就是html标签,所以通用选择器*不能使用。

    4.2 局部组件

      局部组件是通过定义变量,变量的值为一个大字典,而字典中书写的形式同vue实例中的书写形式相同。局部组件与全局组件的模板可以是是在template中书写的部分,而不会使用挂载点,挂载点用于根组件。

      局部组件使用前要在父组件的components中注册,然后使用时当做一个自定义标签使用即可。

    let localTag = {
            template:`
            <p @click="action">点了我{{ count }}下</p>
            `,
            // 1.data要达到组件的复用,必须为每个组件提供一个名称空间(作用域)
            // 2.data的值就是一个存放数据的字典
            // 需要满足1和2,data值为一个可以产生名称空间的函数的返回值,返回值是字典
            data:function () {
                return {
                    count: 0
                }
            },
            methods:{
                action:function () {
                    this.count++
                }
            }
        };
    
    //父组件
    new Vue({
        el: '#app',
         // 局部组件必须在父组件的components中注册
         components:{
              // 注册局部组件的别名: 局部组件原名
              //当取的名字与局部组件名字相同时可以这么简写
              localTag: localTag // 简写:localTag
           }
    })

      template中要书写多行html代码时,使用ESC键下面的 `` 即可。

      局部组件

    let localTag = {
            template:`
            <p @click="action">点了我{{ count }}下</p>
            `,
            // 1.data要达到组件的复用,必须为每个组件提供一个名称空间(作用域)
            // 2.data的值就是一个存放数据的字典
            // 需要满足1和2,data值为一个可以产生名称空间的函数的返回值,返回值是字典
            data:function () {
                return {
                    count: 0
                }
            },
            methods:{
                action:function () {
                    this.count++
                }
            }
        };
    小例子

    4.3 全局组件

      全局组件通过通过Vue的一个方法来实现,使用时也是当自定义标签来使用,不需要去父组件中注册。

    Vue.component(组件名, {组件主体});

      全局组件与局部组件的取名都采用驼峰体的形式,而html中是不区分大小写的,所以在标签中建议使用 - 语法命名,对应js中就是驼峰命名:即local-tag等于localTag。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>全局组件</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <style>
            p {
                width: 100px;
                height: 100px;
                border: solid;
            }
        </style>
    </head>
    <body>
    <div id="app">
        <!--在标签中建议使用 - 语法命名,对应js中就是驼峰命名-->
        <global-tag></global-tag>
        <global-tag></global-tag>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        //全局组件 Vue.component(组件名, {组件主体});
        // 全局组件无需注册
        Vue.component('globalTag', {
            template:`
            <p @click="action">点了我{{ count }}下</p>
            `,
            data:function () {
                return {
                    count: 0
                }
            },
            methods:{
                action:function () {
                    this.count++ //this.count += 1
                }
            }
        });
    
        //父组件
        new Vue({
            el:'#app',
        })
    </script>
    </html>
    小例子

    4.4  组件间的数据交互--父传子

      父组件向子组件传输数据时,是通过在自定义属性来实现的,如下:

    <global-tag :hello="msg"></global-tag>

      子组件名为globalTag,在其中定义自定义属性hello,因为该标签是在父组件中,所以变量msg的值由父组件来提供,然后在子组件中通过props:['hello']来然内部可以使用hello变量,而hello属性的值又来自于父组件的msg变量,这就实现了父组件传输数据给子组件。注意: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://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div id="app">
        <!-- local-tag就可以理解为自定义标签,使用msg变量值由父组件提供 -->
        <!-- local-tag标签代表的是子组件,owen为标签的自定义属性 -->
        <!-- 在子组件内部能拿到owen,就可以拿到父组件的信息 -->
        <global-tag :hello="msg"></global-tag>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        //全局组件,是Vue的子组件
        Vue.component('globalTag', {
            // 子组件拿自定义属性
            props:['hello'],
            template:`
            <p @click="action">{{ hello }}</p>
            `,
        });
    
    
        //父组件
        new Vue({
            el:'#app',
            data:{
                msg: '这是父组件的信息'
            }
        })
    </script>
    </html>
    小例子

    4.5 组件间的数据交互--子传父

      首先子组件向父组件传输数据时,要知道什么时候传,所以就需要使用事件。子组件中通过事件,在事件函数中使用this.$emit('自定义事件名', 给父组件的数据),而子组件是当做自定义标签的方式在父组件中使用的,所以自定义事件的函数需要父类提供,而此时自定义事件的函数就能结束子组件传输的参数,也就是emit中第二个参数携带的数据。

    this.$emit('alter', this.msg)
    
    <!--通过@子组件自定义事件名,在父组件的事件函数中拿到子组件的传参-->
    <local-tag @alter="get_title"></local-tag>
    
    <!--父组件通过事件函数拿到子组件传输的数据-->
    get_title: function (msg) {
          this.msg = msg

      具体事例如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>组件间的交互-子传父</title>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
    <div id="app">
        <!--通过@子组件自定义事件名,在父组件的事件函数中拿到子组件的传参-->
        <local-tag @alter="get_title"></local-tag>
        <p>{{ msg }}</p>
    </div>
    </body>
    <script src="vue.js"></script>
    <script>
        let localTag = {
            //template中只能有一个根标签
            template:`
            <div>
                <input type="text" v-model="msg">
                <button @click="action">修改父组件信息</button>
            </div>
            `,
            data: function(){
              return {
                  msg: ''
              }
            },
            methods:{
                action:function () {
                    //$emit('自定义事件名', '参数')
                    this.$emit('alter', this.msg)
                }
            },
            //  watch:{
            //     msg:function () {
            //         this.$emit('alter', this.msg)
            //     }
            // }
        };
    
        new Vue({
            el: '#app',
            data: {
                msg: '这是父组件的信息'
            },
            methods: {
                get_title: function (msg) {
                    this.msg = msg
                }
            },
            components:{
                localTag
            }
        })
    </script>
    </html>
    View Code

      

  • 相关阅读:
    练习上传下载时遇到的问题
    el表达式遇到的问题
    js中for循环闭包问题记录
    随机排座位(模板) 20.10.17
    #STL:优先队列数据结构函数的用法 #堆 #优先队列数据结构(堆) #priority_queue 20.10.17
    关于int的范围
    #归并排序 归并排序的刷题记录 ~20.09.25
    #欧拉函数 ~20.8.27
    #排列 #组合 ~20.8.24
    105.七夕祭
  • 原文地址:https://www.cnblogs.com/maoruqiang/p/11094593.html
Copyright © 2011-2022 走看看