vue_基础(2)

 目录: 

   axios  

   同源机制

   组件化开发

   组件传值

   vue-router的使用 

 

 

vue-axios

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

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

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

下载地址: 

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

 

通过axios实现数据请求

 

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

增 post

删 delete

改 put

查 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);
    
    }).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'

 

数据接口

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

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

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

ajax和axios的对比使用

获取天气信息 

接口地址
天气接口 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

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

axios获取天气

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">

    请输入您想查询城市:<input type="text" v-model="city">
    <button @click="get_weather">确定</button>
    <h2 style='color: red'>{{message}}</h2>
</div>
</body>
<script src="vue.js"></script>
<script src="axios.js"></script>
<script>
    new Vue({
        el: '#app',
        data() {
            return {
                city:'',
                message:'',  // 展示查询到的信息
            }
        },
        methods:{
            get_weather(){
                axios.get('http://wthrcdn.etouch.cn/weather_mini?',{
                    params:{
                        city:this.city, 
                    }
                })

                    .then((res)=>{
                        console.log(res)
                        this.message = res.data.data.city + ':' + res.data.data.ganmao;
                    }).catch(function (error){
                        console.log(error)
                })

            }
        }
    })
</script>
</html>

 

 

ajax获取天气

ajax的使用必须与服务端程序配合使用,但是目前我们先学习ajax的使用,所以暂时先不涉及到服务端python代码的编写。因此,我们可以使用别人写好的数据接口进行调用。

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

<!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) {     // 请求成功以后的操作,新的ajax是这样写的,之前是通过属性success:function(){}的形式来写的
                console.log(resp);
            })
            .fail(function(error) {    // 请求失败以后的操作 error:function(){}
                console.log(error);
            });
        });
    })
    </script>
</head>
<body>
<button id="btn">点击获取数据</button>
</body>
</html>

总结: 

1. 发送ajax请求,要通过$.ajax(),参数是对象,里面有固定的参数名称。
   $.ajax({
     "url":"数据接口url地址",
     "method":"http请求方式,前端只支持get和post",
     "dataType":"设置服务器返回的数据格式,常用的json,html,jsonp,默认值就是json",
     // 要发送给后端的数据参数,post时,数据必须写在data,get可以写在data,也可以跟在地址栏?号后面
     "data":{
       "数据名称":"数据值",
     }
   }).then(function(resp){ // ajax请求数据成功时会自动调用then方法的匿名函数
     console.log( resp ); // 服务端返回的数据
   }).fail(function(error){ // ajax请求数据失败时会自动调用fail方法的匿名函数
     console.log( error );
   });
   
2. ajax的使用往往配合事件/钩子操作进行调用。

 

同源策略

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

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

测试: 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
    <script src="js/axios.js"></script>
</head>
<body>
    <div id="app">
        <button @click="get_music">点击获取天气</button>
    </div>
    <script>
        let vm = new Vue({
            el:"#app",
            data:{},
            methods:{
                get_music(){
                    axios.get("http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.search.catalogSug&query=我的中国心")
                        .then(response=>{
                            console.log(response);

                        }).catch(error=>{
                            console.log(error.response)
                    });
                }
            }
        })
    </script>
</body>
</html>
View Code

 

上面的代码错误如下

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

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

解决ajax跨域(跨源)方案之CORS

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

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

 

首先创建两个django项目, t1, t2 , 

分别分配不同的端口号模拟同源机制:  http://127.0.0.1:8001/  http://127.0.0.1:8000/

t1中向t2发送get请求获取数据 

# t1
{% load static %}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <button @click="btn">获取数据</button> </div> </body> <script src="{% static 'vue.js' %}"></script> <script src="{% static 'axios.js' %}"></script> <script> new Vue({ el: '#app', data() { return {} }, methods:{ btn(){ axios.get('http://127.0.0.1:8001/data/') // 指定获取数据 .then(function (res){ console.log(res) }).catch(function (error){ console.log(error) }) } } }) </script> </html>

 

t2中的views

from django.http import JsonResponse

def data(request):
    info = {'name': 'I', 'say': ' love you'}
    ret = JsonResponse(info)
    return ret

 

同样的出现了如下报错

 

 

 j解决方案,我们只需要在视图中添加Access-Control-Allow-Origin响应键值对即可

def data(request):
    info = {'name': 'I', 'say': ' love you'}
    ret = JsonResponse(info)
    ret['Access-Control-Allow-Origin'] = 'http://127.0.0.1:8000'  # 允许该地址的请求正常获取响应数据
    # ret['Access-Control-Allow-Origin'] = '*'  # 允许所有地址请求都能拿到数据
    return ret

 

组件化开发

组件 component

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

 

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

 

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

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

我们在进行vue开发的时候,还记得我们自己创建的vm对象吗,这个vm对象我们称为一个大组件,根组件(页面上叫Root),在一个网页的开发中,根据网页上的功能区域我们又可以细分成其他组件,或称为子组件

img

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

局部组件

三步 : 生子 挂子 用子  

注意:每个组件中的template对应的标签,都必须有一个外层标签包裹

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--3. 使用子组件-->
    <!--组件化开发, 页面上需要哪些子组件,就将哪些组件拼到页面上显示-->
    <Vheader></Vheader>
    <Banner></Banner>
</div>
</body>
<script src="vue.js"></script>
<script>
    // 1. 声明子组件   除了没有el 其他和vue对象一样
    let Vheader ={
        data(){
            return{ nav_list: ['个人中心','登录','注册']}
        },
        template:  `
            <div>
                <h1>{{nav_list}}</h1>
            </div>
        `

    }
    let Banner = {
        data(){
            return{content: '内容区域,这里有好多小图片,你看不到吧!'}
        },
        template: `
            <div>
                <h1 style="color: red">{{content}}</h1>
            </div>
        `
    }

    let vm = new Vue({
        el:"#app",
        data(){
            return{
            }
        },
        components:{
            Vheader:Vheader, // 2.挂载子组件,都挂载到vue中
            Banner,  // 键和值相同时,可以简写
        }
    })
</script>
</html>

 

全局组件 : 子组件都写在Vue上面

直接看代码,局部组件使用时需要挂载,全局组件使用时不需要挂载。那么他们两个什么时候用呢,局部组件就在某个局部使用的时候,全局组件是大家公用的,或者说每个页面都有这么一个功能的时候,在哪里可能都会用到的时候。

<div id="app">
    <love></love>
    <kk></kk>
</div>
</body>
<script src="vue.js"></script>
<script>
        // 全局组件  不需挂载,直接使用
     Vue.component('kk',{
         data(){
             return{
                 name:'全局组件!!!'
             }
         },
         template:`
            <h1 style="color: yellow">{{name}}</h1>
         `
     })

    new Vue({
        el:"#app",
        data(){
            return{}
        }
    })
</script>

 

一般组件开发时并不会直接将所有的子组件挂载到vue的components,那样显得太多不利于维护,所以一般定义个App组件,将所有的子组件挂载到App中, 然后Vue中只需要挂载一个App就可以了, 这里的App就相当于一个包工头
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <App></App>   <!--使用子组件-->
</div>
</body>
<script src="vue.js"></script>
<script>

    let aa = {    // 声明aa子组件
        data(){
            return{hobby:'听歌,跳舞'}
        },
        template:'<h2 style="color: red">{{hobby}}</h2>'
    }
    let bb = {   // 声明bb子组件
        data(){
            return{dream:'妹妹, money'}
        },
        template: `<h2 style="color: tan">{{dream}}</h2>`
    }

    // 包工头
    let App = {
        data() {
            return{msg:'我是App'}
        },
        template:`
            <div class="app">
                <h1>{{msg}}</h1>
                <aa></aa>
                <bb></bb>
            </div>
        `,
        components:{
            aa,bb,   // 将那两个小组件挂载到这
        }
    }

    // Vue对象
    let vm = new Vue({
        el:'#app',
        data(){
            return{
            }
        },
        components:{
            App,  // 将包工头挂载到这
        }
    })
</script>
</html>

 注意: components一定要加s , 不要使用data:{ }

 

组件传值

父组件向子组件传值  prop 

props是子组件用来接收父组件传递过来的数据的一个自定义属性

父组件的数据需要通过props把数据传给子组件 ,子组件需要显式地用 props 选项声明 "prop":

 

两步:
    1. 父组件在使用子组价的时候要定义自定义的属性,比如:
            动态传值: <Vheader :ff="num"></Vheader>
            静态传值: <Vheader ff="123"><Vheader>
    2. 在子组件中使用props属性声明: 比如 props['ff',],然后子组件就可以将
    ff作为一个数据属性来使用了比如: 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--两步:-->
<!--    1. 父组件在使用子组价的时候要定义自定义的属性,比如:-->
<!--            动态传值: <Vheader :ff="num"></Vheader>-->
<!--            静态传值: <Vheader ff="123"><Vheader>-->
<!--    2. 在子组件中使用props属性声明: 比如 props['ff',],然后子组件就可以将-->
<!--    ff作为一个数据属性来使用了比如: -->

<div id="app">
    <App></App>
</div>
</body>
<script src="vue.js"></script>
<script>

    let Vheader = {
        data(){
            return{}
        },
        template:`<h1>{{ff}}</h1>`,
        props:['ff',],   // 接收父组件的值
    }

    let App = {
        data(){
            return{message: 'App', num:100}
        },
        template:`
            <div class="app">
                <h2>{{message}}</h2>
                <Vheader :ff="num"></Vheader>  //动态传值   
            </div>    // <Vheader ff='123'></Vheader> // 静态传值
        `,       
        components:{
            Vheader,
        }
    }

    new Vue({
        el:'#app',
        components:{
            App,
        }
    })
</script>
</html>

 

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

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

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

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

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

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

子组件向父组件传值

 

父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,就需要使用自定义事件!

我们可以使用 v-on 绑定自定义事件, 每个 Vue 实例都实现了事件接口(Events interface),即:

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName) 触发事件

另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

a. 子组件中使用 this.$emit('ffunc',val)  // ffunc是父组件中使用子组件的地方添加的绑定自定义事件
this.$emit('ffunc', this.num);

b. 父组件中的methods中写一个自定义的事件函数: recv_data(val), 这个val就是子组件传过来的数据
<son @ffunc="recv_data"></son>  
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<div id="app">
    <App></App>
</div>
</body>
<script src="vue.js"></script>
<script>

    let son = {
        data(){
            return{msg:'我是子组件',
                num:1000,   // num传递给父组件
            }
        },template: `
            <div>
                <h2>{{msg}}</h2>
                <button @click="zouni">点击传值</button>
            </div>
        `,
        methods:{
            zouni(){
                // 给父组件传值
                this.$emit('ffunc', this.num);
            }
        }
    }

    let App = {     
        data(){
            return{ msg:'我是父组件',son_data:''}
        },
        template:`
            <div>
                <son @ffunc="recv_data"></son> // 父组件使用子组件的时候,写上一个自定义事件    
                <h3>{{msg}}</h3>
                <h3 style="color: #2c3e50">{{son_data}}</h3>

            </div>
        `
        ,components:{
            son,
        },methods:{
            recv_data(val){
                this.son_data = val  
            }
        }
    }

    let vm = new Vue({
        el:'#app',
        components:{
            App,
        }
    })
</script>
</html>

 

 平行组件传值

 

 

 

看代码 :声明两个全局组件T1和T2,T1组件将数据传送给T2组件

a. 声明一个公交车, t1组件使用$.emit往公交车上传值  

b. t2组件使用 bus.$on 从公交车上获取值

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <App></App>
</div>
</body>
<script src="vue.js"></script>
<script>

    // 1.声明一个公交车
    let bus = new Vue();

    Vue.component('t1',{
        data(){
            return{
                msg:'hello',
                num:200,
            }
        },template:`
            <div class="t1">
                <h1>{{msg}}</h1>
                <button @click="kk">点我</button>


            </div>
        `,
        // 2. 往公交车上放值
        methods:{
            kk(){
                bus.$emit('xxx', this.num)
            }
        }
    })


    Vue.component('t2',{
        data(){
            return{msg:'hello',t1_num:''}
        },template:`
            <div>
                <h1>{{msg}}</h1>
               <h2>{{t1_num}}</h2>
            </div>

         `,

        created(){
            bus.$on('xxx',(val)=>{
                this.t1_num = val;
            })
        }
    })
    let App = {
        data(){
            return{msg:'App'}
        },
        template:`
            <div class="app">
                <t1></t1>
                <t2></t2>
            </div>
        `
    }

    new Vue({
        el:"#app",
        components:{
            App,
        }
    })

</script>
</html>

 

 

vue-router的使用

vue就是我们前面学习的vue基础,vue + vue-router 主要用来做SPA(Single Page Application),单页面应用

为什么要使用单页面应用呢?因为传统的路由跳转,如果后端资源过多,会导致页面出现'白屏现象',所以我们希望让前端来做路由,在某个生命周期的钩子函数中,发送ajax来请求数据,进行数据驱动,之前比如我们用django的MTV模式,我们是将后端的数据全部渲染给了模板,然后模板再发送给前端进行浏览器页面的渲染,一下将所有的数据都给了页面,而我们现在使用vue,我可以在组件的钩子函数中发送对应的ajax请求去获取对应的数据,而不是全部一下子就把数据都放到页面上了,单页面应用给我们提供了很多的便利,说起来大家可能没有什么切实的体会,来,给大家推荐一个稀土掘金网站,这个网站就是一个单页面应用,是一个开发者技术社区网站,里面的资源会有很多,看样子:

 

 

  这样的网站我们通过django是可以来完成页面的渲染的,模板渲染嘛,但是这个论坛的数据资源有很多,我们通过django的MTV模式是一下子就将数据全部放到页面里面了,那么页面通过浏览器渲染的时候,浏览器可能没有那么快渲染出来,会出现几秒钟的白屏现象,也就是说几秒钟之后用户才看到页面的内容,这样体验起来就不好,为了用户体验好,就用到了我们说的单页面应用,django模板渲染做大型应用的时候,也就是页面很复杂,数据量很大的页面的时候,是不太合适的,当然如果你够nb,你也可以优化,但是一般它比较适合一些页面数据比较小的应用。

  那么解释一下什么是单页应用,看下图:(react、angular也都是做单页面应用,很多大型的网站像网易云音乐,豆瓣等都是react写的单页面应用)

 

 下面我们来下载一下vue-router,文档地址,下载vue-router的cnd链接地址:https://unpkg.com/vue-router/dist/vue-router.js

 HTML

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!-- 使用 router-link 组件来导航. -->
    <!-- 通过传入 `to` 属性指定链接. -->
    <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>
</div>

 

JavaScript

// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)

// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }

// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
  { path: '/foo', component: Foo },
  { path: '/bar', component: Bar }
]

// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
  routes // (缩写) 相当于 routes: routes
})

// 4. 创建和挂载根实例。
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({
  router
}).$mount('#app')

// 现在,应用已经启动了!

 

通过注入路由器,我们可以在任何组件内通过 this.$router 访问路由器,也可以通过 this.$route 访问当前路由:

// Home.vue
export default {
  computed: {
    username() {
      // 我们很快就会看到 `params` 是什么
      return this.$route.params.username
    }
  },
  methods: {
    goBack() {
      window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/')
    }
  }
}

 

使用流程

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <App></App>
</div>
</body>
<script src="vue.js"></script>
<script src="vue-router.js"></script>
<script>

    // 1. 定义路由组件
    let Home = {
        data(){
            return{
                msg :'我是home组件',
            }
        },template:`
            <div class="home">
                <h1>{{msg}}</h1>
            </div>
        `
    }
    let Course = {
        data(){
            return{
                msg:'我是course组件',
            }
        },template:`
            <div class="course">
                <h1>{{msg}}</h1>
            </div>
        `
    }
    // 2. 定义路由, 一个路由对应一个组件
    const routes = [
        { path: '/home', component:Home},
        { path: '/course', component:Course},
    ]
    // 3. 创建 VueRouter对象, 然后将路由规则传给这个对象
    let router = new VueRouter({
        routes, //简写
    })
    // 4. 创建router-link 标签来指定路由
    let App = {
        data(){
            return{
                num:100,
            }   // 5. 写路由出口 router-view
        },template:`
            <div class="app">
                <router-link to="/home">首页</router-link>
                <router-link to="/course">课程页</router-link>
                <router-view></router-view>
            </div>
        `
    }


    // 6. 创建和挂载根实例,在vue对象中挂载一下 router对象
    let vm = new Vue({
        el:'#app',
        router,  // 挂载
        components:{
            App,
        }
    })
</script>
</html>

 

posted @ 2020-12-08 20:28  长情不羁的五年  阅读(91)  评论(0编辑  收藏  举报