• Vue框架


    1. vue.js的快速入门使用

    1.1 vue.js库的下载

    vue.js是目前前端web开发最流行的工具库,由尤雨溪在2014年2月发布的。

    另外几个常见的工具库:react.js /angular.js

    官方网站:

    ​ 中文:https://cn.vuejs.org/

    ​ 英文:https://vuejs.org/

    官方文档:https://cn.vuejs.org/v2/guide/

    vue.js目前有1.x、2.x和3.x 版本,我们使用2.x版本的。

    1.2 vue.js库的基本使用

    在github下载:

    在官网下载地址: https://cn.vuejs.org/v2/guide/installation.html

    vue的引入类似于jQuery,开发中可以使用开发版本vue.js,产品上线要换成vue.min.js。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script src="js/vue.js"></script>
        <script>
        window.onload = function(){
          	// vue.js的代码开始于一个Vue对象。所以每次操作数据都要声明Vue对象开始。
            var vm = new Vue({
                el:'#app',   // 设置当前vue对象要控制的标签范围。
                data:{  // data是将要展示到HTML标签元素中的数据。
                  message: 'hello world!',
                }
            });
        }
        </script>
    </head>
    <body>
    <div id="app">
        <!-- {{ message }} 表示把vue对象里面data属性中的对应数据输出到页面中 -->
        <!-- 在双标签中显示数据要通过{{  }}来完成 -->
        <p>{{ message }}</p>
    </div>
    </body>
    </html>
    

    总结:

    1. vue的使用要从创建Vue对象开始
       var vm = new Vue();
       
    2. 创建vue对象的时候,需要传递参数,是json对象,json对象对象必须至少有两个属性成员
       var vm = new Vue({
            el:"#app",
            data: {
                数据变量:"变量值",
                数据变量:"变量值",
                数据变量:"变量值",
            },
       });
       
       el:设置vue可以操作的html内容范围,值一般就是css的id选择器。
       data: 保存vue.js中要显示到html页面的数据。
       
    3. vue.js要控制器的内容外围,必须先通过id来设置。
      <div id="app">
          <h1>{{message}}</h1>
          <p>{{message}}</p>
      </div>
    

    1.3 vue.js的M-V-VM思想

    MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式。

    Model 指代的就是vue对象的data属性里面的数据。这里的数据要显示到页面中。

    View 指代的就是vue中数据要显示的HTML页面,在vue中,也称之为“视图模板” 。

    ViewModel 指代的是vue.js中我们编写代码时的vm对象了,它是vue.js的核心,负责连接 View 和 Model,保证视图和数据的一致性,所以前面代码中,data里面的数据被显示中p标签中就是vm对象自动完成的。

    编写代码,让我们更加清晰的了解MVVM:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="js/vue.min.js"></script>
        <script>
        window.onload = function(){
            // 创建vm对象
            vm = new Vue({
                el: "#app",
                data: {
                    name:"大标题",
                    age:16,
                },
            })
        }
        </script>
    </head>
    <body>
        <div id="app">
            <!-- 在双标签中显示数据要通过{{  }}来完成 -->
            <h1>{{name}}</h1>
            <p>{{age}}</p>
            <!-- 在表单输入框中显示数据要使用v-model来完成,模板语法的时候,我们会详细学习 -->
            <input type="text" v-model="name">
        </div>
    </body>
    </html>
    

    在浏览器中可以在 console.log通过 vm对象可以直接访问el和data属性,甚至可以访问data里面的数据

    console.log(vm.$el)     # #box  vm对象可以控制的范围
    console.log(vm.$data);  # vm对象要显示到页面中的数据
    console.log(vm.$data.message);  # 访问data里面的数据
    console.log(vm.message);# 这个 message就是data里面声明的数据,也可以使用 vm.变量名显示其他数据,message只是举例.
    

    总结:

    1. 如果要输出data里面的数据作为普通标签的内容,需要使用{{  }}
       用法:
          vue对象的data属性:
              data:{
                name:"小明",
              }
          标签元素:
          		<h1>{{ name }}</h1>
    2. 如果要输出data里面的数据作为表单元素的值,需要使用vue.js提供的元素属性v-model
       用法:
          vue对象的data属性:
              data:{
                name:"小明",
              }
          表单元素:
          		<input v-model="name">
          
       使用v-model把data里面的数据显示到表单元素以后,一旦用户修改表单元素的值,则data里面对应数据的值也会随之发生改变,甚至,页面中凡是使用了这个数据都会发生变化。
    

    1.4 显示数据

    1. 在双标签中显示数据要通过{{ }}来完成数据显示
    2. 在表单输入框中显示数据要使用v-model来完成数据显示
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="js/vue.min.js"></script>
        <script>
          window.onload = function(){
            var vm = new Vue({
              el:"#app",
              data:{
                str1: "hello",
                num: 20,
                url1: "http://www.baidu.com",
                url2: "http://www.taobao.com"
              }
            })        
            }
        </script>
    </head>
    <body>
        <p>{{ str1 }}</p>
        <p>{{ str1.split("").reverse().join("") }}</p>
        <p>num和num2中比较大的数是:{{ num>num2? num:num2 }}</p>
        <input type="text" v-model="name">
    </body>
    </html>
    

    双花括号仅用输出文本内容,如果要输出html代码,则不能使用这个.要使用v-html来输出.

    v-html必须在html标签里面作为属性写出来.

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div class="app">
            <h1>{{title}}</h1>
            <h3>{{url1}}</h3>
            {{img}}<br>
            <span v-html="img"></span>
        </div>
        <script>
            let vm = new Vue({
                el:".app",
                data:{
                    title:"我的vue",
                    url1:"我的收获地址",
                    img:'<img src="images/shendan.png">',
                }
            })
        </script>
    </body>
    </html>
    

    总结:

    1. 可以在普通标签中使用{{  }} 或者 v-html 来输出data里面的数据
       <h1>{{message}}</h1>
       
    2. 可以在表单标签中使用v-model属性来输出data里面的数据,同时还可以修改data里面的数据
       <input type="text" v-model="username">
    

    在输出内容到普通标签的使用{{ }}

    v-model或者v-html等vue提供的属性,或者 {{}} 都支持js代码。

        <h1>{{str1.split("").reverse().join("")}}</h1>
        <!-- 3.2 支持js的运算符-->
        <h1>{{num1+3}}</h1>
    
        <!-- 3.3 js还有一种运算符,三元运算符,类似于python里面的三元表达式
            三元运算符的语法:
             判断条件 ? 条件为true : 条件为false的结果
    
            python 三元表达式[三目运算符]的语法:
            a if 条件 else b
         -->
        <h1>num1和num2之间进行比较,最大值:{{ num2>num1?num2:num1 }}</h1>
    

    例子:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Vue的快速使用</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
    <div id="app">
        <p>{{url}}</p>
        <div>{{text}}</div>
        <div v-html="text"></div>
        <input v-model="url">
        <div>num是{{num%2==0?'偶数':'奇数'}}</div>
        <div>num的下一个数字:{{num-0+1}}</div>
        <input type="text" v-model="num">
        <div>{{message.split("").reverse().join("")}}</div>
        <input type="text" v-model="message.split('').reverse().join('')">
    </div>
        <script>
        var vm = new Vue({
            el:"#app", // 设置vue对象控制的标签范围
            data:{     // vue要操作的数据
                url:"http://www.luffycity.com",
                text:"<h1>大标题</h1>",
                num: 100,
                message:"abcdef",
            }
        })
        </script>
    </body>
    </html>
    

    2. 常用指令

    指令 (Directives) 是带有“v-”前缀的特殊属性。每一个指令在vue中都有固定的作用。

    在vue中,提供了很多指令,常用的有:v-if、v-model、v-for等等。

    指令会在vm对象的data属性的数据发生变化时,会同时改变元素中的其控制的内容或属性。

    因为vue的历史版本原因,所以有一部分指令都有两种写法:

    vue1.x写法             vue2.x的写法
    v-html         ---->   {{ 普通文本 }}   # vue2.x 也支持v-html,v-text,输出html代码的内容
    v-bind:属性名   ---->   :属性
    v-on:事件名     ---->   @事件名
    

    2.1 操作属性

    格式:

    <标签名 :标签属性="data属性"></标签名>
    
    <p :title="str1">{{ str1 }}</p> <!-- 也可以使用v-html显示双标签的内容,{{  }} 是简写 -->
    <a :href="url2">淘宝</a>
    <a v-bind:href="url1">百度</a>  <!-- v-bind是vue1.x版本的写法 -->
    

    显示wifi密码效果:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
    
    <div id="index">
        <img :src="url" :alt="title"><br>
        <input :type="type" placeholder="请输入wifi密码"> <button @click="type='text'">显示密码</button>
    </div>
    
    <script>
        let vm = new Vue({
            el:"#index",
            data:{
              url:"https://www.luffycity.com/static/img/head-logo.a7cedf3.svg",
              title:"路飞学成",
              type:"password"
            }
        })
    </script>
    </body>
    </html>
    

    2.2 事件绑定

    有两种事件操作的写法,@事件名 和 v-on:事件名

    <button v-on:click="num++">按钮</button>   <!-- v-on 是vue1.x版本的写法 -->
    <button @click="num+=5">按钮2</button>
    

    总结:

    1. 使用@事件名来进行事件的绑定
       语法:
          <h1 @click="num++">{{num}}</h1>
    
    2. 绑定的事件的事件名,全部都是js的事件名:
       @submit   --->  onsubmit
       @focus    --->  onfocus
       ....
    
    

    例如:完成商城购物车中的商品增加减少数量

    步骤:

    1. 给vue对象添加操作数据的方法
    2. 在标签中使用指令调用操作数据的方法
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="js/vue.js"></script>
    </head>
    <body>
        <div id="box">
            <button @click="++num">+</button>
            <input type="text" v-model="num">
            <button @click="sub">-</button>
        </div>
    
        <script>
            let vm = new Vue({
                el:"#box",
                data:{
                    num:0,
                },
                methods:{
                    sub(){
                        if(this.num<=1){
                            this.num=0;
                        }else{
                            this.num--;
                        }
                    }
                }
            })
        </script>
    </body>
    </html>
    
    <!--#box>(button+input+button) tab键-->
    
    

    2.3 操作样式

    2.3.1 控制标签class类名

    格式:
       <h1 :class="值">元素</h1>  值可以是字符串、对象、对象名、数组
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="js/vue.js"></script>
        <style>
        .box1{
            color: red;
            border: 1px solid #000;
        }
        .box2{
            background-color: orange;
            font-size: 32px;
        }
        </style>
    </head>
    <body>
        <div id="box">
            <!--- 添加class类名,值是一个对象
            {
             class类1:布尔值变量1,
             class类2:布尔值变量2,
            }
             -->
            <p :class="{box1:myclass1}">一个段落</p>
            <p @click="myclass3=!myclass3" :class="{box1:myclass2,box2:myclass3}">一个段落</p>
        </div>
        <script>
            let vm1=new Vue({
                el:"#box",
                data:{
                    myclass1:false, // 布尔值变量如果是false,则不会添加对象的属性名作为样式
                    myclass2:true,  // 布尔值变量如果是true,则会添加对象的属性名作为样式
                    myclass3:false,
                },
            })
        </script>
    
        <!-- 上面的代码可以:class的值保存到data里面的一个变量,然后使用该变量作为:class的值 -->
        <style>
        .box4{
            background-color: red;
        }
        .box5{
            color: green;
        }
        </style>
        <div id="app">
            <button @click="mycls.box4=!mycls.box4">改变背景</button>
            <button @click="mycls.box5=!mycls.box5">改变字体颜色</button>
            <p :class="mycls">第二个段落</p>
        </div>
        <script>
            let vm2 = new Vue({
                el:"#app",
                data:{
                    mycls:{
                        box4:false,
                        box5:true
                    },
                }
            })
        </script>
    
        <!-- 批量给元素增加多个class样式类 -->
        <style>
        .box6{
            background-color: red;
        }
        .box7{
            color: green;
        }
        .box8{
            border: 1px solid yellow;
        }
        </style>
        <div id="app2">
                <p :class="[mycls1,mycls2]">第三个段落</p>
        </div>
        <script>
            let vm3 = new Vue({
                el:"#app2",
                data:{
                    mycls1:{
                        box6:true,
                        box7:true,
                    },
                    mycls2:{
                        box8:true,
                    }
                }
            })
        </script>
    </body>
    </html>
    

    总结:

    1. 给元素绑定class类名,最常用的就是第二种。
        vue对象的data数据:
            data:{
              myObj:{
                complete:true,
                uncomplete:false,
              }
            }
    
    		html元素:    
        		<div class="box" :class="myObj">2222</div>
        最终浏览器效果:
    		    <div class="box complete">2222</div>
    

    2.3.2 控制标签style样式

    格式1:值是json对象,对象写在元素的:style属性中
    	 标签元素:
    		     <div :style="{color: activeColor, fontSize: fontSize + 'px' }"></div>
    	 data数据如下:
             data: {
                 activeColor: 'red',
                 fontSize: 30
             }
    格式2:值是对象变量名,对象在data中进行声明
       标签元素:
       			<div v-bind:style="styleObject"></div>
       data数据如下:
             data: {
                	styleObject: {
                 		color: 'red',
                 		fontSize: '13px'
    			  	}
    		}
    
    格式3:值是数组
      标签元素:
    				<div v-bind:style="[style1, style2]"></div>
    	data数据如下:
    				data: {
                         style1:{
                           color:"red"
                         },
                         style2:{
                           background:"yellow",
                           fontSize: "21px"
                         }
    				}
    

    2.3.2 实例-vue版本选项卡

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            #card{
                 500px;
                height: 350px;
            }
            .title{
                height:50px;
            }
            .title span{
                 100px;
                height: 50px;
                background-color:#ccc;
                display: inline-block;
                line-height: 50px; /* 设置行和当前元素的高度相等,就可以让文本内容上下居中 */
                text-align:center;
            }
            .content .list{
                 500px;
                height: 300px;
                background-color: yellow;
                display: none;
            }
            .content .active{
                display: block;
            }
    
            .title .current{
                background-color: yellow;
            }
        </style>
        <script src="js/vue.js"></script>
    </head>
    <body>
    
        <div id="card">
            <div class="title">
                <span @click="num=0" :class="num==0?'current':''">国内新闻</span>
                <span @click="num=1" :class="num==1?'current':''">国际新闻</span>
                <span @click="num=2" :class="num==2?'current':''">银河新闻</span>
                <!--<span>{{num}}</span>-->
            </div>
            <div class="content">
                <div class="list" :class="num==0?'active':''">国内新闻列表</div>
                <div class="list" :class="num==1?'active':''">国际新闻列表</div>
                <div class="list" :class="num==2?'active':''">银河新闻列表</div>
            </div>
        </div>
        <script>
            // 思路:
            // 当用户点击标题栏的按钮[span]时,显示对应索引下标的内容块[.list]
            // 代码实现:
            var card = new Vue({
                el:"#card",
                data:{
                    num:0,
                },
            });
        </script>
    
    </body>
    </html>
    

    2.4 条件渲染指令

    vue中提供了两个指令可以用于判断是否要显示元素,分别是v-if和v-show。

    2.4.1 v-if

      标签元素:
          <!-- vue对象最终会把条件的结果变成布尔值 -->
    			<h1 v-if="ok">Yes</h1>
      data数据:
      		data:{
          		ok:false    // true则是显示,false是隐藏
          }
    

    2.4.2 v-else

    v-else指令来表示 v-if 的“else 块”,v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。

      标签元素:
    			<h1 v-if="ok">Yes</h1>
    			<h1 v-else>No</h1>
      data数据:
      		data:{
          		ok:false    // true则是显示,false是隐藏
          }
    

    2.4.3 v-else-if

    可以出现多个v-else-if语句,但是v-else-if之前必须有一个v-if开头。后面可以跟着v-else,也可以没有。

      标签元素:
    			<h1 v-if="num==1">num的值为1</h1>
    			<h1 v-else-if="num==2">num的值为2</h1>
    		  <h1 v-else>num的值是{{num}}</h1>
      data数据:
      		data:{
          		num:2
          }
    

    2.4.4 v-show

    用法和v-if大致一样,区别在于2点:

    1. v-show后面不能v-else或者v-else-if
    2. v-show隐藏元素时,使用的是display:none来隐藏的,而v-if是直接从HTML文档中移除元素[ DOM操作中的remove ]
      标签元素:
    			<h1 v-show="ok">Hello!</h1>
      data数据:
      		data:{
          		ok:false    // true则是显示,false是隐藏
          }
    

    2.5 列表渲染指令

    在vue中,可以通过v-for指令可以将一组数据渲染到页面中,数据可以是数组或者对象。

    数据是数组:        
            <ul>
                <!--book是列表的每一个元素-->
                <li v-for="book in book_list">{{book.title}}</li>
            </ul>
    
            <ul>
                <!--book是列表的每一个元素,index是每个元素的下标-->
                <li v-for="book, index in book_list">第{{ index+1}}本图书:{{book.title}}</li>
            </ul>
    
    
            <script>
                var vm1 = new Vue({
                    el:"#app",
                    data:{
                        book_list:[
                            {"id":1,"title":"图书名称1","price":200},
                            {"id":2,"title":"图书名称2","price":200},
                            {"id":3,"title":"图书名称3","price":200},
                            {"id":4,"title":"图书名称4","price":200},
                        ]
                    }
                })
            </script>
    
    数据是对象:
            <ul>
                <!--i是每一个value值-->
                <li v-for="value in book">{{value}}</li>
            </ul>
            <ul>
                <!--i是每一个value值,j是每一个键名-->
                <li v-for="attr, value in book">{{attr}}:{{value}}</li>
            </ul>
            <script>
                var vm1 = new Vue({
                    el:"#app",
                    data:{
                        book: {
                            // "attr":"value"
                            "id":11,
                            "title":"图书名称1",
                            "price":200
                        },
                    },
                })
            </script>
    
    

    练习:

    goods:[
    	{"name":"python入门","price":150},
    	{"name":"python进阶","price":100},
    	{"name":"python高级","price":75},
    	{"name":"python研究","price":60},
    	{"name":"python放弃","price":110},
    ]
    
    # 把上面的数据采用table表格输出到页面,价格大于60的数据需要添加背景色橙色[orange]
    

    代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="js/vue.js"></script>
        <style>
        .orange{
            background: orange;
        }
        </style>
    </head>
    <body>
        <div id="app">
            <table border="1" width="800px">
                <tr>
                    <th>序号</th>
                    <th>标题</th>
                    <th>价格</th>
                </tr>
                <tr v-for="item,key in goods" :class="item.price>60?'orange':''">
                    <td>{{key+1}}</td>
                    <td>{{item.name}}</td>
                    <td>{{item.price}}</td>
                </tr>
            </table>
        </div>
        <script>
            var vm = new Vue({
                el:"#app",
                data:{
                    goods:[
                        {"name":"python入门","price":150},
                        {"name":"python进阶","price":100},
                        {"name":"python高级","price":75},
                        {"name":"python研究","price":60},
                        {"name":"python放弃","price":110},
                    ]
                }
            })
        </script>
    
    </body>
    </html>
    

    3. Vue对象提供的属性功能

    3.1 过滤器

    过滤器,就是vue允许开发者自定义文本格式化函数,可以使用在两个地方:输出内容和操作数据中。

    定义过滤器的方式有两种。

    3.1.1 使用Vue.filter()进行全局定义

    Vue.filter("RMB1", function(v){
      	//就是来格式化(处理)v这个数据的
      	if(v==0){
        		return v;
      	}
      	return v+"元";
    })
    //可以将全局过滤器保存到单独的js文件中,在需要使用时进行引用
    

    3.1.2 在vue对象中通过filters属性来定义

    var vm = new Vue({
        el: "#app",
        data: {},
        filters: {
            RMB2: function (value) {
                if (value == '') {
                    return;
                } else {
                    return '¥ ' + value;
                }
            }
        }
    });
    

    3.4 计算和侦听属性

    3.4.1 计算属性

    比如字符串反转,如果直接把反转的代码写在元素中,则会使得其他同事在开发时时不易发现数据被调整了,所以vue提供了一个计算属性(computed),可以让我们把调整data数据的代码存在该属性中。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="vue.min.js"></script>
    </head>
    <body>
    
    <div id="box">
        <p>{{price2}}</p>
        <p>{{price}}</p>
    </div>
    
    <script>
        //当我们需要针对data的数据需要调整成另一个变量,留作后面其他地方使用时
        //可以使用计算属性得到一个新的变量
        Vue.filter('RMB', function (v) {
            return "¥" + v
        });
        var vm = new Vue({
            el: "#box",
            data: {
                price: 30.5
            },
            computed: {
                price2() {
                    //必须有返回值
                    return this.price.toFixed(2)
                }
            }
        })
    </script>
    </body>
    </html>
    

    3.4.2 监听属性

    侦听属性,可以帮助我们侦听data某个数据的变化,从而做相应的自定义操作。

    侦听属性是一个对象,它的键是要监听的对象或者变量,值一般是函数,当侦听的data数据发生变化时,会自定执行的对应函数,这个函数在被调用时,vue会传入两个形参,第一个是变化后的数据值,第二个是变化前的数据值。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="vue.min.js"></script>
    </head>
    <body>
    
    <div id="box">
        数量: <input type="text" v-model="num">
        单价: <input type="text" v-model="price">
        总价: {{total}}
    </div>
    
    <script>
        var vm = new Vue({
            el: "#box",
            data: {
                price: 30.5,
                num: 0,
                total: 0
            },
            watch: {
                num: function (newval, oldval) {
                    this.total = parseInt(newval) * this.price
                },
                price: function (newval, oldval) {
                    this.total = parseInt(newval) * this.num
                }
            }
        })
    </script>
    </body>
    </html>
    

    3.5 vue对象的生命周期

    每个Vue对象在创建时都要经过一系列的初始化过程。在这个过程中Vue.js会自动运行一些叫做生命周期的的钩子函数,我们可以使用这些函数,在对象创建的不同阶段加上我们需要的代码,实现特定的功能。

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue的生命周期</title>
        <script src="vue.min.js"></script>
    </head>
    <body>
    <div id="app" ref="app">
        {{ name }}
    </div>
    </body>
    <script>
        let vm = new Vue({
            el: "#app",
            data: {
                name: "python",
            },
            beforeCreate() {
                //这里的代码执行时,vm对象尚未创建,所有data中的属性是无法操作的
                console.log("vm对象创建前:");
                console.log(this.name);  //此时找不到this.name
                this.name = 'java'; //此时设置this对象的属性不会生效
                console.log(this.$el);
                console.log(this.$data);
            },
            created() {
                //这里的代码执行时,vm对象已经创建完成,但是还没有把数据和视图模板进行绑定
                //这里可以用于写从后端获取数据的代码
                console.log("vm对象创建完成:");
                console.log(this.$el);
                console.log(this.$data);
            },
            beforeMount() {
                //这里的代码执行时,已经绑定了视图,但是没有更新视图中的数据
                console.log("挂载前:");
                console.log(this.$el.innerHTML);
                console.log(this.$data);
            },
            mounted() {
                //这里的代码执行时,已经把data中的数据替换了模板中对应的内容了
                //注意: 此时页面还没有显示
                console.log("挂载后:");
                console.log(this.$el.innerHTML);
                console.log(this.$data);
            },
            beforeUpdate() {
                //当data的中数据发生变化时,执行beforeUpdate()和updated()
                //此时data中的数据还没有发生变化
                console.log('更新数据前:');
                let name = this.$el.innerHTML;
                console.log('name:' + name);
            },
            updated() {
                //此时data中的数据已经改变
                console.log('更新数据后:');
                let name = this.$el.innerHTML;
                console.log('name:' + name);
            },
            beforeDestory() {
                console.log("vm对象销毁前");
            },
            destoryed() {
                console.log("vm对象销毁后");
            }
        });
    </script>
    </html>
    

    总结:

    mounted: 在vue使用的过程中,如果要初始化操作,把初始化操作的代码放在 mounted 中执行。mounted阶段就是在vm对象已经把data数据填充到页面模板中。一般页面初始化使用。例如,用户访问页面加载成功以后,就要执行的ajax请求。
    
    created: 这个阶段就是在 vue 对象创建以后,把ajax请求后端数据的代码放进 created 中
    

    3.2 阻止事件冒泡和刷新页面

    使用.stop和.prevent

    .stop: 阻止事件冒泡

    .prevent: 阻止事件冒泡,并且阻止事件的默认行为,比如a标签的刷新页面,submit的提交表单

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="vue.min.js"></script>
    </head>
    <body>
    
    <div onclick="alert('div')">
        <button id="btn">按钮</button>
    </div>
    
    <div id="box" @click="show2()">
        <!--    stop: 阻止事件冒泡-->
        <button @click.stop="show()">按钮</button>
        <!--    prevent: 阻止事件冒泡,并且阻止事件的默认行为,比如a标签的刷新页面,submit的提交表单-->
        <a href="" @click.prevent="show()"></a>
    </div>
    
    <script>
        //事件event,在js中表示用户和浏览器之间进行的一次交互过程
        //事件在触发时,就会有一个事件对象来记录整个事件发生的过程和发生的位置
        //从事件发生位置由内及外,根据标签之间父子嵌套关系,逐层往外传播,这种事件的传递方式,就是事件的冒泡
        //事件冒泡有好有坏,好处就是可以利用这种机制,实现事件委托
        //坏处就是当页面中如果不需要执行父级元素的事件,会随着冒泡全部执行
    
        //js原生
        // var div = document.getElementById('box');
        var btn = document.getElementById('btn');
        btn.onclick = function (e) {
          alert('按钮');
          e.stopPropagation();
          e.cancelBubble = true
        };
    
        var vm = new Vue({
            el: "#box",
            data: {},
            methods: {
                show() {
                    alert('按钮')
                },
                show2() {
                    alert('div')
                }
            }
        })
    </script>
    </body>
    </html>
    

    3.3 综合案例-todolist

    我的计划列表

    html代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>todolist</title>
    	<style type="text/css">
    		.list_con{
    			600px;
    			margin:50px auto 0;
    		}
    		.inputtxt{
    			550px;
    			height:30px;
    			border:1px solid #ccc;
    			padding:0px;
    			text-indent:10px;
    		}
    		.inputbtn{
    			40px;
    			height:32px;
    			padding:0px;
    			border:1px solid #ccc;
    		}
    		.list{
    			margin:0;
    			padding:0;
    			list-style:none;
    			margin-top:20px;
    		}
    		.list li{
    			height:40px;
    			line-height:40px;
    			border-bottom:1px solid #ccc;
    		}
    
    		.list li span{
    			float:left;
    		}
    
    		.list li a{
    			float:right;
    			text-decoration:none;
    			margin:0 10px;
    		}
    	</style>
    </head>
    <body>
    	<div class="list_con">
    		<h2>To do list</h2>
    		<input type="text" name="" id="txt1" class="inputtxt">
    		<input type="button" name="" value="增加" id="btn1" class="inputbtn">
    
    		<ul id="list" class="list">
    			<!-- javascript:; # 阻止a标签跳转 -->
    			<li>
    				<span>学习html</span>
    				<a href="javascript:;" class="up"> ↑ </a>
    				<a href="javascript:;" class="down"> ↓ </a>
    				<a href="javascript:;" class="del">删除</a>
    			</li>
    			<li><span>学习css</span><a href="javascript:;" class="up"> ↑ </a><a href="javascript:;" class="down"> ↓ </a><a href="javascript:;" class="del">删除</a></li>
    			<li><span>学习javascript</span><a href="javascript:;" class="up"> ↑ </a><a href="javascript:;" class="down"> ↓ </a><a href="javascript:;" class="del">删除</a></li>
    		</ul>
    	</div>
    </body>
    </html>
    

    特效实现效果:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>todolist</title>
    	<style type="text/css">
    		.list_con{
    			600px;
    			margin:50px auto 0;
    		}
    		.inputtxt{
    			550px;
    			height:30px;
    			border:1px solid #ccc;
    			padding:0px;
    			text-indent:10px;
    		}
    		.inputbtn{
    			40px;
    			height:32px;
    			padding:0px;
    			border:1px solid #ccc;
    		}
    		.list{
    			margin:0;
    			padding:0;
    			list-style:none;
    			margin-top:20px;
    		}
    		.list li{
    			height:40px;
    			line-height:40px;
    			border-bottom:1px solid #ccc;
    		}
    
    		.list li span{
    			float:left;
    		}
    
    		.list li a{
    			float:right;
    			text-decoration:none;
    			margin:0 10px;
    		}
    	</style>
        <script src="js/vue.js"></script>
    </head>
    <body>
    	<div id="todolist" class="list_con">
    		<h2>To do list</h2>
    		<input type="text" v-model="message" class="inputtxt">
    		<input type="button" @click="addItem" value="增加" class="inputbtn">
    		<ul id="list" class="list">
    			<li v-for="item,key in dolist">
    				<span>{{item}}</span>
    				<a @click="upItem(key)" class="up" > ↑ </a>
    				<a @click="downItem(key)" class="down"> ↓ </a>
    				<a @click="delItem(key)" class="del">删除</a>
    			</li>
    		</ul>
    	</div>
        <script>
        // 计划列表代码
        let vm = new Vue({
            el:"#todolist",
            data:{
                message:"",
                dolist:[
                    "学习html",
                    "学习css",
                    "学习javascript",
                ]
            },
            methods:{
                addItem(){
                    if(this.messsage==""){
                        return false;
                    }
    
                    this.dolist.push(this.message);
                    this.message = ""
                },
                delItem(key){
                    // 删除和替换
                    // 参数1: 开始下表
                    // 参数2: 元素长度,如果不填默认删除到最后
                    // 参数3: 表示使用当前参数替换已经删除内容的位置
                    this.dolist.splice(key, 1);
                },
                upItem(key){
                    if(key==0){
                        return false;
                    }
                    // 向上移动
                    let result = this.dolist.splice(key,1);
                    this.dolist.splice(key-1,0,result[0]);
                },
                downItem(key){
                    // 向下移动
                    let result = this.dolist.splice(key, 1);
                    console.log(result);
                    this.dolist.splice(key+1,0,result[0]);
                }
            }
        })
        </script>
    </body>
    </html>
    

    4. 通过axios实现数据请求

    vue.js默认没有提供ajax功能的。

    所以使用vue的时候,一般都会使用axios的插件来实现ajax与后端服务器的数据交互。

    注意,axios本质上就是javascript的ajax封装,所以会被同源策略限制。

    插件: http://www.axios-js.com/

    下载地址:

    https://unpkg.com/axios@0.18.0/dist/axios.js
    https://unpkg.com/axios@0.18.0/dist/axios.min.js
    

    axios提供发送请求的常用方法有两个:axios.get() 和 axios.post() 。

    增 post

    删 delete

    改 put/patch

    查 get

    	// 发送get请求
        // 参数1: 必填,字符串,请求的数据接口的url地址,例如请求地址:http://www.baidu.com?id=200
        // 参数2:可选,json对象,要提供给数据接口的参数
        // 参数3:可选,json对象,请求头信息
    	axios.get('服务器的资源地址',{ // http://www.baidu.com
        	params:{
        		参数名:'参数值', // id: 200,
        	}
        
        }).then(function (response) { // 请求成功以后的回调函数
        		console.log("请求成功");
        		console.log(response.data); // 获取服务端提供的数据
        
        }).catch(function (error) {   // 请求失败以后的回调函数
        		console.log("请求失败");
        		console.log(error.response);  // 获取错误信息
        });
    
    	// 发送post请求,参数和使用和axios.get()一样。
        // 参数1: 必填,字符串,请求的数据接口的url地址
        // 参数2:必填,json对象,要提供给数据接口的参数,如果没有参数,则必须使用{}
        // 参数3:可选,json对象,请求头信息
        axios.post('服务器的资源地址',{
        	username: 'xiaoming',
        	password: '123456'
        },{
            responseData:"json",
        })
        .then(function (response) { // 请求成功以后的回调函数
          console.log(response);
        })
        .catch(function (error) {   // 请求失败以后的回调函数
          console.log(error);
        });
    
    	
    	// b'firstName=Fred&lastName=Flintstone'
    

    4.1 json

    json是 JavaScript Object Notation 的首字母缩写,单词的意思是javascript对象表示法,这里说的json指的是类似于javascript对象的一种数据格式。

    json的作用:在不同的系统平台,或不同编程语言之间传递数据。

    4.1.1 json数据的语法

    json数据对象类似于JavaScript中的对象,但是它的键对应的值里面是没有函数方法的,值可以是普通变量,不支持undefined,值还可以是数组或者json对象。

    // 原生的js的json对象
    var obj = {
      age:18,
      sex: '男',
      work:function(){
        return "怀心抱素",
      }
    }
    
    
    // json数据的对象格式,json数据格式,是没有方法的,只有属性:
    {
        "name":"怀心抱素",
        "age":18
    }
    
    // json数据的数组格式:
    ["怀心抱素",18,"python"]
    

    复杂的json格式数据可以包含对象和数组的写法。

    {
      "name":"怀心抱素",
      "age":18,
      "is_delete": false,
      "fav":["code","eat","swim","read"],
      "son":{
        "name":"心素如简",
        "age":18,
        "lve":["code","eat"]
      }
    }
    
    // 数组结构也可以作为json传输数据。
    

    json数据可以保存在.json文件中,一般里面就只有一个json对象。

    总结:

    1. json文件的后缀是.json
    2. json文件一般保存一个单一的json数据
    3. json数据的属性不能是方法或者undefined,属性值只能:数值[整数,小数,布尔值]、字符串、json和数组
    4. json数据只使用双引号、每一个属性成员之间使用逗号隔开,并且最后一个成员没有逗号。
       {
          "name":"小明",
          "age":200,
          "fav":["code","eat","swim","read"],
          "son":{
            "name":"小小明",
            "age":100
          }
        }
    

    工具:postman可以用于测试开发的数据接口。

    4.1.2 js中提供的json数据转换方法

    javascript提供了一个JSON对象来操作json数据的数据转换.

    方法 参数 返回值 描述
    stringify json对象 字符串 json对象转成字符串
    parse 字符串 json对象 字符串格式的json数据转成json对象
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <script>
        // json语法
        let humen = {
            "username":"怀心抱素",
            "password":"1234567",
            "age":18
        };
    
        console.log(humen);
        console.log(typeof humen);
    
        // JSON对象提供对json格式数据的转换功能
        // stringify(json对象) 用于把json转换成字符串
        let result = JSON.stringify(humen);
        console.log(result);
        console.log(typeof result);
    
        // parse(字符串类型的json数据)  用于把字符串转成json对象
        let json_str = '{"password":"1123","age":18,"name":"怀心抱素"}';
        console.log(json_str)
        console.log(typeof json_str)
    
        let json_obj = JSON.parse(json_str);
        console.log(json_obj);
        console.log(typeof json_obj)
    
        console.log(json_obj.age)
    </script>
    </body>
    </html>
    

    4.2 ajax

    ajax,一般中文称之为:"阿贾克斯",是英文 “Async Javascript And Xml”的简写,译作:异步js和xml数据传输数据。

    ajax的作用: ajax可以让js代替浏览器向后端程序发送http请求,与后端通信,在用户不知道的情况下操作数据和信息,从而实现页面局部刷新数据/无刷新更新数据。

    所以开发中ajax是很常用的技术,主要用于操作后端提供的数据接口,从而实现网站的前后端分离

    ajax技术的原理是实例化js的XMLHttpRequest对象,使用此对象提供的内置方法就可以与后端进行数据通信。

    4.2.1 数据接口

    数据接口,也叫api接口,表示后端提供操作数据/功能的url地址给客户端使用。

    客户端通过发起请求向服务端提供的url地址申请操作数据【操作一般:增删查改】

    同时在工作中,大部分数据接口都不是手写,而是通过函数库/框架来生成。

    4.2.3 ajax的使用

    ajax的使用必须与服务端程序配合使用。

    jQuery将ajax封装成了一个函数$.ajax(),可以直接用这个函数来执行ajax请求。

    接口 地址
    天气接口 http://wthrcdn.etouch.cn/weather_mini?city=城市名称
    音乐接口搜索 http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.search.catalogSug&query=歌曲标题
    音乐信息接口 http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.song.play&songid=音乐ID

    编写代码获取接口提供的数据:

    jQ版本

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="js/jquery-1.12.4.js"></script>
        <script>
        $(function(){
            $("#btn").on("click",function(){
                $.ajax({
                    // 后端程序的url地址
                    url: 'http://wthrcdn.etouch.cn/weather_mini',
                    // 也可以使用method,提交数据的方式,默认是'GET',常用的还有'POST'
                    type: 'get', 
                    dataType: 'json',  // 返回的数据格式,常用的有是'json','html',"jsonp"
                    data:{ // 设置发送给服务器的数据,如果是get请求,也可以写在url地址的?后面
                        "city":'北京'
                    }
                })
                .done(function(resp) {     // 请求成功以后的操作
                    console.log(resp);
                })
                .fail(function(error) {    // 请求失败以后的操作
                    console.log(error);
                });
            });
        })
        </script>
    </head>
    <body>
    <button id="btn">点击获取数据</button>
    </body>
    </html>
    

    vue版本:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="vue.min.js"></script>
        <script src="axios.min.js"></script>
    </head>
    <body>
    <div id="box">
        <button id="btn" @click="get_data()">点击</button>
    </div>
    <script>
        var vm = new Vue({
            el: '#box',
            data: {},
            methods: {
                get_data() {
                    axios.get("http://wthrcdn.etouch.cn/weather_mini", {
                        params: {
                            city: '北京'
                        }
                    }).then(resposne => {
                        console.log(resposne.data)
                    }).catch(error => {
                        console.log(error.response)
                    })
                }
            }
        })
    </script>
    </body>
    </html>
    

    4.2.4 同源策略

    同源策略,是浏览器为了保护用户信息安全的一种安全机制。所谓的同源就是指代通信的两个地址(例如服务端接口地址与浏览器客户端页面地址)之间比较,是否协议、域名(IP)和端口相同。不同源的客户端脚本[javascript]在没有明确授权的情况下,没有权限读写对方信息。

    ajax本质上还是javascript,是运行在浏览器中的脚本语言,所以会被受到浏览器的同源策略所限制。

    前端地址:http://www.baidu.cn/index.html 是否同源 原因
    http://www.baidu.cn/user/login.html 协议、域名、端口相同
    http://www.baidu.cn/about.html 协议、域名、端口相同
    https://www.baidu.cn/user/login.html 协议不同 ( https和http )
    http:/www.baidu.cn:5000/user/login.html 端口 不同( 5000和80)
    http://bbs.baidu.cn/user/login.html 域名不同 ( bbs和www )

    同源策略针对ajax的拦截,代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="vue.min.js"></script>
        <script src="axios.min.js"></script>
    </head>
    <body>
    <div id="box">
        <button id="btn" @click="get_data()">点击</button>
    </div>
    <script>
        var vm = new Vue({
            el: '#box',
            data: {},
            methods: {
                get_data() {
                    axios.get("http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.search.catalogSug&query=我的中国心", {
                        params: {
                        }
                    }).then(resposne => {
                        console.log(resposne.data)
                    }).catch(error => {
                        console.log(error.response)
                    })
                }
            }
        })
    </script>
    </body>
    </html>
    

    上面代码运行错误如下:

    Access to XMLHttpRequest at 'http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.search.catalogSug&query=%E6%88%91%E7%9A%84%E4%B8%AD%E5%9B%BD%E5%BF%83' from origin 'http://localhost:63342' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
    

    上面错误,关键词:Access-Control-Allow-Origin

    只要出现这个关键词,就是访问受限。出现同源策略的拦截问题。

    4.2.5 ajax跨域(跨源)方案之CORS

    ajax跨域(跨源)方案:后端授权[CORS],jsonp,服务端代理

    • CORS是一个W3C标准,全称是"跨域资源共享",它允许浏览器向跨源的后端服务器发出ajax请求,从而克服了AJAX只能同源使用的限制。

    • 实现CORS主要依靠后端服务器中响应数据中设置响应头信息Access-Control-Allow-Origin返回的。

    django的视图

    def post(request):	
    response = new Response()
    # 指定允许的域名地址
    response .headers["Access-Control-Allow-Origin"] = "*"
    return response
    
    // 在响应行信息里面设置以下内容:
    Access-Control-Allow-Origin: ajax所在的域名地址
    
    Access-Control-Allow-Origin: www.huaixinbaosu.cn  # 表示只允许www.huaixinbaosu.cn域名的客户端的ajax跨域访问
    
    // * 表示任意源,表示允许任意源下的客户端的ajax都可以访问当前服务端信息
    Access-Control-Allow-Origin: '*'
    

    总结:

    0. 同源策略:浏览器的一种保护用户数据的一种安全机制。
       浏览器会限制ajax不能跨源访问其他源的数据地址。
       同源:判断两个通信的地址之间,是否协议,域名[IP],端口一致。
       
       ajax:  http://127.0.0.1/index.html
       api数据接口:  http://localhost/index
       
       这两个是同源么?不是同源的。是否同源的判断依据不会根据电脑来判断,而是通过协议、域名、端口的字符串是否来判断。
       
    1. ajax默认情况下会受到同源策略的影响,一旦受到影响会报错误如下:
    	 No 'Access-Control-Allow-Origin' header is present on the requested resource
    
    2. 解决ajax只能同源访问数据接口的方式:
       1. CORS,跨域资源共享,在服务端的响应行中设置:
          Access-Control-Allow-Origin: 允许访问的域名地址
       2. jsonp
       3. 是否服务端代理
          思路:通过python来请求对应的服务器接口,获取到数据以后,再返回给自己的ajax请求
    

    5. 组件化开发

    5.1 组件[component]

    组件(Component)是自定义封装的功能。在前端开发过程中,经常出现多个网页的功能是重复的,而且很多不同的页面之间,也存在同样的功能。

    而在网页中实现一个功能,需要使用html定义功能的内容结构,使用css声明功能的外观样式,还要使用js来定义功能的特效,因此就产生了把一个功能相关的[HTML、css和javascript]代码封装在一起组成一个整体的代码块封装模式,我们称之为“组件”。

    所以,组件就是一个html网页中的功能,一般就是一个标签,标签中有自己的html内容结构,css样式和js特效。

    这样,前端人员就可以在组件化开发时,只需要书写一次代码,随处引入即可使用。

    vue的组件有两种:默认组件[全局组件] 和 单文件组件

    5.1.1 默认组件

    缺点:

    • 没有地方写CSS代码
    • 长篇的组件,极易错乱
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="../js/vue.js"></script>
    </head>
    <body>
    <div id="box">
        <comp></comp>
        <comp></comp>
        <comp></comp>
        <comp></comp>
    </div>
    <script>
        //第一个参数是组件的名称
        //第二个参数是json对象
        Vue.component("comp", {
            //模板
            template: "<p>公共头部:<span @click='show()'>{{message}}</span></p>",
            //data在组件中变成了一个函数,函数的返回值必须是一个json对象
            data: function () {
                return {
                    message: "这是一段文本"
                }
            },
            methods: {
                show() {
                    alert(this.message)
                }
            }
        });
        var vm = new Vue({
            el: "#box",
            data: {},
            methods: {}
        })
    </script>
    </body>
    </html>
    

    6. Vue自动化工具(Vue-cli)

    前面提了普通组件以后,接下来的单文件组件则需要提前先安装准备一些组件开发工具。否则无法使用和学习单文件组件。

    一般情况下,单文件组件,我们运行在 自动化工具Vue-cli中,可以帮我们编译单文件组件。所以我们需要在系统中先搭建Vue-cli工具,

    官网:https://cli.vuejs.org/zh/

    Vue-cli需要 Node.js 8.9 或更高版本 (推荐 8.11.0+)。可以使用 nvmnvm-windows在同一台电脑中管理多个 Node 版本。

    nvm工具的下载和安装:

    https://www.jianshu.com/p/d0e0935b150a

    https://www.jianshu.com/p/622ad36ee020

    安装记录:

    打开:https://github.com/coreybutler/nvm-windows/releases

    windows安装完成以后,先查看环境变量是否设置好了.

    常用的nvm命令

    nvm list # 列出目前在nvm里面安装的所有node版本
    nvm install node版本号 # 安装指定版本的node.js
    nvm uninstall node版本号 # 卸载指定版本的node.js
    nvm use node版本号 # 切换当前使用的node.js版本

    如果使用nvm工具,则直接可以不用自己手动下载,如果使用nvm下载安装 node的npm比较慢的时候,可以修改nvm的配置文件(在安装根目录下)

    # settings.txt
    root: C:	ool
    vm    [这里的目录地址是安装nvm时自己设置的地址,要根据实际修改]
    path: C:	ool
    odejs
    arch: 64
    proxy: none
    node_mirror: http://npm.taobao.org/mirrors/node/ 
    npm_mirror: https://npm.taobao.org/mirrors/npm/
    

    6.1 安装node.js

    Node.js是一个新的后端(后台)语言,它的语法和JavaScript类似,所以可以说它是属于前端的后端语言,后端语言和前端语言的区别:

    • 运行环境:后端语言一般运行在服务器端,前端语言运行在客户端的浏览器上
    • 功能:后端语言可以操作文件,可以读写数据库,前端语言不能操作文件,不能读写数据库。

    我们一般安装LTS(长线支持版本 Long-Time Support):

    下载地址:https://nodejs.org/en/download/【上面已经安装了nvm,那么这里不用手动安装了】

    node.js的版本有两大分支:

    官方发布的node.js版本:0.xx.xx 这种版本号就是官方发布的版本

    社区发布的node.js版本:xx.xx.x 就是社区开发的版本

    Node.js如果安装成功,可以查看Node.js的版本,在终端输入如下命令:

    node -v
    

    6.2 npm

    在安装node.js完成后,在node.js中会同时帮我们安装一个npm包管理器npm。我们可以借助npm命令来安装node.js的包。这个工具相当于python的pip管理器。

    npm install -g 包名              # 安装模块   -g表示全局安装,如果没有-g,则表示在当前项目安装
    npm list                        # 查看当前目录下已安装的node包
    npm view 包名 engines            # 查看包所依赖的Node的版本 
    npm outdated                    # 检查包是否已经过时,命令会列出所有已过时的包
    npm update 包名                  # 更新node包
    npm uninstall 包名               # 卸载node包
    npm 命令 -h                      # 查看指定命令的帮助文档
    

    6.3 安装Vue-cli

    npm install -g @vue/cli-init
    

    如果安装速度过慢,一直超时,可以考虑切换npm镜像源:http://npm.taobao.org/

    6.4 使用Vue-Cli初始化创建前端项目

    6.4.1 生成项目目录

    使用vue自动化工具可以快速搭建单页应用项目目录。

    该工具为现代化的前端开发工作流提供了开箱即用的构建配置。只需几分钟即可创建并启动一个带热重载、保存时静态检查以及可用于生产环境的构建配置的项目:

    // 生成一个基于 webpack 模板的新项目
    vue init webpack 项目目录名
    例如:
    vue init webpack myproject
    
    
    // 启动开发服务器 ctrl+c 停止服务
    cd myproject
    npm run dev           # 运行这个命令就可以启动node提供的测试http服务器
    

    运行了上面代码以后,终端下会出现以下效果提示:

    那么访问:http://localhost:8080/

    6.4.2 项目目录结构

    src 主开发目录,要开发的单文件组件全部在这个目录下的components目录下

    static 静态资源目录,所有的css,js文件放在这个文件夹

    dist 项目打包发布文件夹,最后要上线单文件项目文件都在这个文件夹中[后面打包项目,让项目中的vue组件经过编译变成js 代码以后,dist就出现了

    node_modules 目录是node的包目录

    config 是配置目录

    build 是项目打包时依赖的目录

    src/router 路由,后面需要我们在使用Router路由的时候,自己声明.

    6.4.3 项目执行流程图

    整个项目是一个主文件index.html,index.html中会引入src文件夹中的main.js,main.js中会导入顶级单文件组件App.vue,App.vue中会通过组件嵌套或者路由来引用components文件夹中的其他单文件组件。

    7. 单文件组件的使用

    组件有两种:普通组件、单文件组件

    普通组件的缺点:

    1. html代码是作为js的字符串进行编写,所以组装和开发的时候不易理解,而且没有高亮效果。
    2. 普通组件用在小项目中非常合适,但是复杂的大项目中,如果把更多的组件放在html文件中,那么维护成本就会变得非常昂贵。
    3. 普通组件只是整合了js和html,但是css代码被剥离出去了。使用的时候的时候不好处理。

    将一个组件相关的html结构,css样式,以及交互的JavaScript代码从html文件中剥离出来,合成一个文件,这种文件就是单文件组件,相当于一个组件具有了结构、表现和行为的完整功能,方便组件之间随意组合以及组件的重用,这种文件的扩展名为“.vue”,比如:"Home.vue"。

    1. 创建组件

    1552362045478

    在组件中编辑三个标签,编写视图、vm对象和css样式代码。

    7.1 template 编写html代码的地方

    <template>
      <div id="Home">
        <span @click="num--" class="sub">-</span>
        <input type="text" size="1" v-model="num">
        <span @click="num++" class="add">+</span>
      </div>
    </template>
    

    7.2 script编写vue.js代码

    <script>
      export default {
        name:"Home",
        data: function(){
          return {
            num:0,
          }
        }
      }
    </script>
    

    7.3 style编写当前组件的样式代码

    <style scoped>
      .sub,.add{
        border: 1px solid red;
        padding: 4px 7px;
      }
    </style>
    

    7.4 完成案例-点击加减数字

    创建Home.vue

    <template>
      <div>
        <button @click="add">+</button>
        <input type="text" v-model="num" id="">
        <button @click="sub">-</button>
      </div>
    
    </template>
    
    <script>
        export default {
            name: "Home",
            data() {
                return {
                    num: 0
                }
            },
            methods: {
                add() {
                    this.num = parseInt(this.num) + 1
                },
                sub() {
                    if (parseInt(this.num) >= 1) {
                        this.num -= 1
                    }
                }
            }
        }
    </script>
    
    <style scoped>
    
    </style>
    
    

    在App.vue组件中调用上面的组件

    <Home></Home>
    import Home from "./components/Home";
    

    在开发vue项目之前,需要手动把 App.vue的HelloWorld组件代码以及默认的css样式,清除。

    上面的代码效果:

    7.5 组件的嵌套

    有时候开发vue项目时,页面也可以算是一个大组件,同时页面也可以分成多个子组件.

    因此,产生了父组件调用子组件的情况.

    例如,我们可以声明一个组件,作为父组件

    在components/创建一个保存子组件的目录HomeSon

    在HomeSon目录下,可以创建当前页面的子组件,例如,是Menu.vue

    //  组件中代码必须写在同一个标签中
    <template>
        <div id="menu">
          <span>{{msg}}</span>
          <div>hello</div>
      </div>
    </template>
    
    <script>
      export default {
        name:"Menu",
        data: function(){
          return {
            msg:"这是Menu组件里面的菜单",
          }
        }
      }
    </script>
    
    

    然后,在父组件中调用上面声明的子组件。

    最后,父组件被App.vue调用.就可以看到页面效果.

    7.6 传递数据

    父组件的数据传递给子组件

    例如,我们希望把父组件的数据传递给子组件.

    可以通过props属性来进行数据传递.

    传递数据三个步骤:

    1. 在父组件中,调用子组件的组件标签处,使用属性值的方式往下传递数据

      <Menu :mynum="num" title="home里面写的数据"/>
      
      # 上面表示在父组件调用Menu子组件的时候传递了2个数据:
        如果要传递变量[变量可以是各种类型的数据],属性名左边必须加上冒号:,同时,属性名是自定义的,会在子组件中使用。
        如果要传递普通字符串数据,则不需要加上冒号:
      
    2. 在子组件中接收上面父组件传递的数据,需要在vm组件对象中,使用props属性类接受。

      <script>
        export default {
          name:"Menu",
          props:["mynum","title"],
          data: function(){
            return {
              msg:"这是Menu组件里面的菜单",
            }
          }
        }
      </script>
      
      // 上面 props属性中表示接收了两个数据。
      
    3. 在子组件中的template中使用父组件传递过来的数据.

      <template>
          <div id="menu">
            <span>{{msg}},{{title}}</span>
            <div>hello,{{mynum}}</div>
        </div>
      </template>
      

    使用父组件传递数据给子组件时, 注意一下几点:

    1. 传递数据是变量,则需要在属性左边添加冒号.

      传递数据是变量,这种数据称之为"动态数据传递"

      传递数据不是变量,这种数据称之为"静态数据传递"

    2. 父组件中修改了数据,在子组件中会被同步修改,但是,子组件中的数据修改了,是不是影响到父组件中的数据.

      这种情况,在开发时,也被称为"单向数据流"

    子组件传递数据给父组件

    1. 在子组件中,通过this.$emit()来调用父组件中定义的事件.

      <template>
          <div>
            <p>Post的子组件</p>
            <h2>{{fnum}}</h2>
            <p>data={{data}}</p>
            <p>fnum={{fnum}}</p>
            <div><input type="text" v-model="fnum"></div>
          </div>
      </template>
      
      <script>
          export default {
              name: "PostSon",
              // 父组件传递数据给子组件: 1. 在父组件中调用子组件的组件名称标签上面声明属性和传递值,2. 在子组件中通过props进行接收
              props:["data","fnum"],  // 接受父组件中传递过来的数据
              // 子组件传递数据给父组件[事件的方式进行传递]:
              watch:{
                fnum(){
                  console.log(this.fnum);
                  // this.$emit("父元素的自定义事件","要传递的数据");  // 通过this.$emit()方法,子组件可以把数据传递给父组件
      
                  this.$emit("postparentdata",this.fnum);
                }
              }
          }
      </script>
      
      <style scoped>
      
      </style>
      
      
    2. 父组件中声明一个和子组件中this.$emit("自定义事件名称")对应的事件属性。

      <template>
          <div>
            <h1>num={{num}}</h1>
            <Son data="我是付组件里面的内容" :fnum="num" @postparentdata="getsondata"></Son>
          </div>
      
      </template>
      
    3. 父组件中,声明一个自定义方法,在事件被调用时,执行的。

      <script>
          import Son from "./PostSon"
          export default {
              name: "Post",
              data(){
                return {
                  num: 100,
                }
              },
              components:{
                Son:Son,
              },
              methods:{
                getsondata(message){
                  console.log("父组件"+message);
                  this.num = message;
                }
              }
          }
      </script>
      

    8. 在组件中使用axios获取数据

    默认情况下,项目中并没有对axios包的支持,所以需要下载安装。

    在项目根目录中使用 npm安装包

    npm install axios
    

    接着在main.js文件中,导入axios并把axios对象 挂载到vue属性中多为一个子对象,这样我们才能在组件中使用。

    // The Vue build version to load with the `import` command
    // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    import Vue from 'vue'
    import App from './App' // 这里表示从别的目录下导入 单文件组件
    import axios from 'axios'; // 从node_modules目录中导入包
    Vue.config.productionTip = false
    
    Vue.prototype.$axios = axios; // 把对象挂载vue中
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      components: { App },
      template: '<App/>'
    });
    
    

    8.1 在组建中使用axios获取数据

    <script>
      export default{
    	。。。
    	methods:{
          get_data:function(){
             // 使用axios请求数据
            this.$axios.get("http://wthrcdn.etouch.cn/weather_mini?city=深圳").then((response)=>{
                console.log(response);
            }).catch(error=>{
                console.log(error);
            })
          }
        }
      }
    </script>
    

    效果:

    使用的时候,因为本质上来说,还是原来的axios,所以也会受到同源策略的影响。

  • 相关阅读:
    Power Apps 创建响应式布局
    SharePoint Online 软件边界限制
    Power Apps 中人员选择器的使用
    Power Apps 中修改 SharePoint Online 数据
    Power Apps 中调用 Automate 工作流
    如何查看你的Office 365 账号的订阅
    Microsoft Teams 中嵌入SharePoint Online 页面
    SharePoint Online 触发Outlook邮件内审批
    Linux查看实时网卡流量的几种方式
    Linux性能优化和监控系列(三)——分析Memory使用状况
  • 原文地址:https://www.cnblogs.com/zyyhxbs/p/11748561.html
Copyright © 2020-2023  润新知