【Vue】02 Component 组件 & Axios

Vue自定义组件:

不论任何注册组件的方式:template属性有且仅有一个根节点标签

就是说模版属性的标签只能有一个在最外面

<div id="container-element">

  <mod-1></mod-1>

</div>

<script type="text/javascript">

  Vue.component("mod-1",{
    template : "<h1>这是模版的标签</h1>"
  });

  let vueModel = new Vue({
    el : "#container-element"
  });
</script>

效果:

使用模版进行传值获取:

<div id="container-element">

  <mod-1 v-for="lang in items" v-bind:A="lang"></mod-1>

</div>

<script type="text/javascript">

  Vue.component("mod-1",{
    props : ['A'],
    template : "<h1>{{A}}</h1>"
  });

  let vueModel = new Vue({
    el : "#container-element",
    data : {
      items : [
        "java","c++","python","rust","linux"
      ]
    }
  });
</script>

效果:

这里值传递的很让人费解:

在模版组件这里的设置

然后是正常的vue指令编写,但是这个A注入就要注意一下

另一种注册组件的方式:

<template id="sample">
    <h1>呵呵</h1>
</template>

像这样先使用模版声明好

    Vue.component("he-he", {
        template : "#sample"
    });

然后再声明组件,使用id选择绑定teamplate标签

私有组件和父子组件

使用Vue.component声明组件时,注册的是一个全局的组件,

允许在任意的一个Vue实例中使用该组件。

但是我们希望注册一个局部的私有组件,可将组件挂载到某个实例上面

私有组件:

    let privateComponent = Vue.extend({
        template: "<h1>这是私有组件</h1>"
    });
    
    let vm = new Vue({
        el : "#app", 
        components : {
            "pc" : privateComponent
        }
    });

效果:

如果组件变量名称和components的属性名称一致可以不写k:v,直接写变量名称即可:

    let privateComponent = Vue.extend({
        template: "<h1>这是私有组件</h1>"
    });

    let vm = new Vue({
        el : "#app",
        components : {
            privateComponent
        }
    });

注意遵循驼峰命名:然后再使用组件时,命名以-分割,并且全小写:

<div id="app">
    <private-component></private-component>
</div>

父组件 & 子组件

<div id="app">
    <parent-com></parent-com> <!-- 最终渲染 -->
</div>

<script type="text/javascript">
    let childCom = Vue.extend({
       template : `<h1>这是子组件!!!</h1>`
    });

    let parentCom = Vue.extend({
        template :
                `<div>
                    <h1>这是父组件!!!</h1>
                    <child-com></child-com>
                </div>`,
        components : { // 在父组件中声明子组件装载
            childCom 
        }
    });

    let vm = new Vue({
        el : "#app",
        components : { // 在Vue实例中声明父组件装载
            parentCom
        }
    })
</script>

效果:

组件的数据:

<div id="app">
    <compo></compo>
</div>

<script type="text/javascript">
    let compo = Vue.extend({
        template : `<h1>这是一个组件 {{msg}}</h1>`
    });

    let vm = new Vue({
        el : "#app",
        data : {
           msg : "这是Vue实例的数据信息"
        },
        components : {
            compo
        }
    });
</script>

可以看出来,我们的实例数据无法渲染在这个组件上面:

组件也可以具有data methods filter等等属性的对象,但是只有data的方式不一样

    let compo = Vue.extend({
        template : `<h1>这是一个组件 {{msg}}</h1>`,
        data (){
            return {
                msg : "这是子组件的消息msg"
            }
        }
    });

然后页面的渲染恢复了正常:

为什么组件的数据data必须是一个方法的返回?

因为Vue会报错,其次每个组件都是一个独立的对象,如果不是独立将会导致数据公用问题:

就是一个组件被多个渲染,里面数据也将是共同使用,所以要以方法的形式返回

父子通信:


【Axios模拟后台传输的json数据】

{
  "name" : "echo42",
  "url" : "https://www.cnblogs.com/mindzone/p/13329771.html",
  "page" : 10,
  "gender" : true,
  "address" : {
    "country" : "中国",
    "city" : "江西南昌",
    "street" : "北京东路1688号"
  },

  "links" : [
    {
      "name" : "qqZone",
      "url" : "https://user.qzone.qq.com/1791255334"
    },

    {
      "name" : "acFun",
      "url" : "https://www.acfun.cn/u/8680899"
    },

    {
      "name" : "biliBili",
      "url" : "https://space.bilibili.com/2931347"
    }
  ]
}

页面:

<!DOCTYPE html>
<html lang="en"
      xmlns:v-bind="http://www.w3.org/1999/xhtml"
      xmlns:v-on="http://www.w3.org/1999/xhtml"
>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
      [v-clock] {
        display: none;
      }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js" ></script>
    <script src="./../node_modules/_axios@0.19.2@axios/dist/axios.min.js"></script>
</head>
<body>

<div id="container-element" v-clock> <!-- v-clock  -->
  <div></div>

  <a v-bind:href="info.url">绑定的个人地址</a> <!-- 利用v-bind完成对一些属性的赋值-->

</div>


<script type="text/javascript">

  let vueModel = new Vue({
    el : "#container-element",

    data(){
      return{
        info : {
          name : null,
          url : null,
          page : null,
          gender : null,
          address : {
            country : null,
            city : null,
            street : null
          },

          links : [
            {name : null, url : null},
            {name : null, url : null},
            {name : null, url : null}
          ]

        }

      }

    },

    mounted() {
      axios.get('./json/data.json').then(response=>(this.info = response.data));
    }

  });

【回顾JQuery的Ajax语法】

// 详细见W3CSchool https://www.w3school.com.cn/jquery/ajax_ajax.asp
$.ajax({
    url : "${pageContext.request.contextPath}/xxx/xxx.action", // 请求发送地址
    type : "post/get", // 请求方式/请求类型
    dataType : "json", // 响应的数据格式
    data : {
      // 请求发送的数据
    },
    success : function (data) { // 后台有响应就会触发
        // TODO ...
    },
    error : function () { // 一般请求异常会触发此回调函数
        // TODO ...
    },
    async : true, // 是否异步请求:true / false 默认true
})

JQuery缩写版本:

$.get(
    "urlAddress",
    {
      // data对象
    },
    function (responseData) {
        // TODO 响应回调函数
    }
);
$.post(
"urlAddress", { // data对象 }, function (responseData) { // TODO 响应回调函数 } );

【Axios语法】

// get请求
axios.get("requestUrlAddress?k1=v1&k2=v2&k3=v3&...").then(
  function (response) {
    // TODO 响应成功
  },
  function (err) {
      // TODO 请求异常或者其他...
  }  
);

// post请求
axios.post(
    "requestUrlAddress",
    {
        // 参数对象
        // K : V, ...
    }
).then(
    function (response) {
        // TODO 响应成功
    },
    function (err) {
        // TODO 请求异常或者其他...
    }
);

axios要求post请求必须把参数统一在参数对象中声明【没试过地址传参,所以8知道】

原来axios是可以单独和原生JS或者JQuery结合使用,只是说配合Vue可以最佳实践吧

结合Vue也是一样的,在声明函数中声明axios发送异步请求

【笑话接口案例】

但是注意一点是Vue实例的data属性的数据会发生变化,需要在函数内作为变量接受一下再处理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="./js/vue.min.js"></script>
    <!--<script type="text/javascript" src="./js/axios.min.js"></script>-->
    <script type="text/javascript" src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>

<div id="application">
    <input type="button" value="点击或取随机笑话" @click="getJoke">
    <p v-text="joke"></p>
</div>

<script type="text/javascript">
    let vueModel = new Vue({
        el : "#application",
        data : {
            joke : "笑话案例"
        },
        methods : {
            getJoke : function () {
                let that = this; // 注意要在这里声明变量接受
                axios.get("https://autumnfish.cn/api/joke").then(
                  function (response) {
                    console.log(response);
                    that.joke = response.data;
                  },
                  function (err) {
                    alert(err);
                  }
                );
            }
        }
    });
</script>

</body>
</html>

 【属性计算】

<!DOCTYPE html>
<html lang="en"
      xmlns:v-bind="http://www.w3.org/1999/xhtml"
      xmlns:v-on="http://www.w3.org/1999/xhtml"
>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./../node_modules/_axios@0.19.2@axios/dist/axios.min.js"></script>
</head>
<body>

<div id="container-element" v-clock> <!-- v-clock  -->

  <p>currentTimeInMethods : {{currentTimeInMethods()}}</p>
  <p>currentTimeInComputed : {{currentTimeInComputed}}</p>

</div>

<script type="text/javascript">
  let vueModel = new Vue({
    el : "#container-element",

    data : {
      message : "Hello,Echo42!!!"
    },

    methods : {
      currentTimeInMethods : function () {
        return Date.now();
      }
    },
    computed : {
      currentTimeInComputed : function () {
        this.message;
        return Date.now();
      }
    }
  });
</script>

</body>
</html>
原文地址:https://www.cnblogs.com/mindzone/p/13331066.html