夫天地者,万物之逆旅;光阴者,百代之过客。而浮生若梦,为欢几何?
Vue.js项目实战二:组件的生命周期及父子组件的传值

生命周期函数

生命周期函数/生命周期钩子:组件挂载、以及组件更新、组件销毁、的时候触发的一系列的方法  这些方法就叫做生命周期函数。这里只简单列举,在实际的项目中一般会经常用到其中created、mounted、computed等钩子函数。

export default{
  data(){
    return{}
  },
  beforeCreate(){
    console.log('实例刚刚被创建1');
  },
  created(){
    console.log('实例已经创建完成2');
  },
  beforeMount(){
    console.log('模板编译之前3');
  },
  mounted(){     //请求数据,操作dom ,放在这个里面mounted
    console.log('模板编译完成4');
  },
  beforeUpdate(){
    console.log('数据更新之前');
  },
  updated(){
    console.log('数据更新完毕');
  },
  beforeDestroy(){   //页面销毁的时候要保存一些数据,就可以监听这个销毁的生命周期函数
    console.log('实例销毁之前');
  },
  destroyed(){
    console.log('实例销毁完成');
  }
}

vue-resource请求数据

以查询文章的评论数据为例:

getComments:function () {
  let that = this;
  var _id = that.$route.params.id; // 获取文章编号
  that.$http.get('/api/getCommentList?_articleId='+_id).then((response)=>{
    if(response.data.code === 200){
      that.commentlist = response.data.data;
    }
  })
}

Axios请求数据

首先需要安装axios插件

cnpm  install  axios --save

然后在需要使用的页面里引入axios,上述方法就可以改成如下方式:

import Axios from 'axios';//引入axios
getComments:function () {
  let that = this;
  var _id = that.$route.params.id; // 获取文章编号
  Axios.get('/api/getCommentList?_articleId='+_id).then((response)=>{
    if(response.data.code === 200){
      that.commentlist = response.data.data;
    }
  })
}

父子组件间的通信

首先看在主页面index.vue中如何引入自定义的子组件

<template>
  <div class="index">
    <!--头部组件-->
    <nav-header></nav-header>
    <div class="main container">
      <!--左侧导航组件-->
      <slider-bar :categorylist="categorylist"></slider-bar>
      <!--文章列表组件-->
      <main-content></main-content>
    </div>
    <!--底部组件-->
    <nav-footer></nav-footer>
  </div>
</template>
<script>
  import {mapState,mapActions} from 'vuex'
  import navHeader  from '../../components/navHeader'
  import navFooter  from '../../components/navFooter'
  import mainContent from '../../components/conMain'
  import sliderBar from '../../components/sliderBar'
  export default {
    data(){
      return{}
    },
    mounted(){
      this.getCategoryList();
    },
    methods:{
      ...mapActions(['getCategoryList'])
    },
    components:{
      navHeader,
      navFooter,
      mainContent,
      sliderBar
    }
  }
</script>

这里我们在index.vue主页面里引入了4个子组件,其中父组件向slider-bar子组件传递了分类列表的数据(即通过绑定动态属性的方式 :categorylist=categorylist),那么在子组件中如何获取并使用这个数据呢?在子组件里面通过 props接收父组件传过来的数据。

<template>
  <div class="sideBar">
    <div class="sidebar_postcategory">
      <h3 class="catListTitle">文章分类</h3>
      <ul>
        <li v-for="item in categorylist">
          <a :href="'/list/'+item._id">{{item.categoryname}}</a>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
  export  default {
    name:'sliderBar',
    props:['categorylist'],
    data(){
      return{ }
    }
  }
</script>

父组件主动获取子组件的数据和方法

具体的方法是:父组件在调用子组件时,定义一个ref 如:<v-header ref="header"></v-header>,然后在父组件里通过如下方式获取子组件中的数据:

this.$refs.header.属性
this.$refs.header.方法

下面仍是通过代码和效果图来演示:

定义父组件home.vue

<template>
  <div id="home">
    <v-header ref="header"></v-header>
    <button @click="getChildData()">获取header子组件的数据和方法</button>
  </div>
</template>
<script>
  import Header from './header.vue';
  export default{
    data(){
      return {
        msg:'我是home父组件',
        title:'首页'
      }
    },
    components:{
      'v-header':Header
    },
    methods:{
      run(){
        console.log('我是Home组件的run方法');
      },
      getChildData(){
        //父组件主动获取子组件的数据
        console.log(this.$refs.header.msg);
        //父组件主动获取子组件的方法
        this.$refs.header.run();
      }
    }
  }
</script>

定义子组件header.vue

<template>
  <div>
    <h2>我是header子组件</h2>
    <button @click="getParentData()">获取home父组件的数据和方法</button>
  </div>
</template>
<script>
  export default{
    data(){
      return{
        msg:'我是header子组件'
      }
    },
    methods:{
      run(){
        console.log('我是子组件的run方法');
      },
      getParentData(){
        //子组件主动获取父组件的数据
        console.log(this.$parent.msg);
        //子组件主动获取父组件的方法
        this.$parent.run();
      }
    }
  }
</script>

执行的结果如下(先点击第二个按钮,再点击第一个按钮):

子组件向父组件传值

在vue中,子组件时不能直接修改父组件中的数据的,因为vue只允许单向数据传递,因此我们可以通过子组件触发事件来通知父组件改变数据,从而达到改变子组件数据的目的。这里就需要使用$emit事件的方式,具体实现如代码:

home.vue父组件html代码

<template>
 <div id="home">
   <h2>我是home父组件</h2>
   <!--自动监听子组件注册的 getChildValue 事件-->
   <v-header @getChildValue="receive"></v-header>
   <p>{{valueFromChild}}</p>
 </div>
</template>

home父组件JavaScript代码

<script>
  import Header from './header.vue';
  export default{
    data(){
      return {
        valueFromChild:'我是父组件,准备接收子组件的数据'
      }
    },
    components:{
      'v-header':Header
    },
    methods:{
      receive(valueFromChild){
        this.valueFromChild = valueFromChild;
      }
    }
  }
</script>

header子组件html代码

<template>
  <div>
    <h2>我是header子组件</h2>
    <button @click="sendValueToParent">header子组件向home父组件传递数据</button>
  </div>
</template>

header子组件JavaScript代码

<script>
  export default{
    data(){
      return{
        childValue:'我是header子组件的值,触发header点击事件'
      }
    },
    methods:{
      sendValueToParent(){
        //将childValue传递给父组件
        this.$emit('getChildValue',this.childValue);
      }
    }
  }
</script>

点击子组件中的button按钮后即可将子组件中的数据传递给父组件,效果如下:

总结

本文示例代码较多,以较为完整的代码更能直观的体会Vue.js的基础概念及用法。

作者:一蓑烟雨

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

0

支持

0

反对

posted @2020-3-17  拜读(408)

评论列表

评论内容:



喜欢请打赏

支付宝 微信

请放心支付