美文网首页
vue生命周期和组件间传值

vue生命周期和组件间传值

作者: 没了提心吊胆的稗子 | 来源:发表于2019-07-31 22:29 被阅读0次

生命周期

new Vue() 初始化一些事件和生命周期 例如:vm.$on, vm.$once, vm.$emit
beforeCreate 初始化之前,会先把一些数据方法放在实例中,还没初始化完,不能操作数据,一般用不到
created 数据,方法初始化完成,可以操作数据,实现响应式绑定,此处一般ajax获取数据
必须有el属性(有编译的元素),才能进行挂载,只能有一个根元素,如果有template属性(内部html),app(外部html)中的内容就会被覆盖掉,就没有意义了
beforeMount 挂载之前,没有什么实际意义,会用vm.$el替换el
mounted 挂载完成,数据和模板挂载好了,真实DOM渲染完了,可以操作DOM
beforeUpdate 更新之前,页面依赖的数据有变化就会开始更新
updated 更新之后,一般用watch方法替代这两个方法
beforeDestory 销毁之前,开始移除一些定时器和事件绑定等操作,方法还没销毁,
destoryed 销毁完成

this.$data:vm上的数据
this.$watch:监控
this.$el:当前el元素
this.$set:后添加的属性实现响应式变化
this.$options:实例上的属性,包括内置的还有自定义的
this.$refs:所有ref的集合,带ref属性的标签,如果不是通过v-for循环出来的DOM元素,只能获取一个
this.$nextTick():异步方法,等待渲染完成后获取vm,数据变化后想获取真实dom,需要等待页面获取完成后再去获取,因此所有dom操作最好都放在this.$nextTick()

mounted(){
  // console.log(document.getElementsByTagName('p')[0].innerHTML);
  console.log(this.$refs.message);
  console.log(this.$refs.wrap);
  this.arr = [1,2,3,4,5]; // dom的渲染是异步的
  this.$nextTick(function () {
  // 数据变化后想获取真实dom,需要等待页面获取完成后再去获取
      console.log(this.$refs.wrap.children.length); // 5
   });
  console.log(this.$refs.wrap.children.length); // 3
}

组件化开发

组件化开发可以提高开发效率,方便重复利用,便与协同开发,更容易被管理和维护。一般根据功能可分为两种:
1、页面级组件,一个页面是一个组件
2、基础组件,将可复用的部分抽离出来
vue中,一个自定义标签就会被看成一个组件
根据用法划分:
全局组件:声明一次可以在任何地方使用,写插件的时候用的多
局部组件:必须要声明这个组件属于哪一部分
声明组件的时候,标签名不要大写,多个单词用- 组件名和定义的名字相同是可以的(首字母可以大写)
html中用-,JS中转驼峰也是可以的
组件中的data必须是函数类型的,返回一个实例作为组件中的数据

<body>
<!--分类 页面级组件 一个页面是一个组件-->
<!--将可复用的部分抽离出来  基础组件-->

<div id="app">
<my-vue></my-vue>
</div>

<script src="../node_modules/vue/dist/vue.js"></script>
<script>
    // 一个对象可以看成一个组件
    Vue.component('my-vue', {
        template: '<div>{{msg}}</div>',
        data(){
            return {msg: 'vue学习'}
        }
    });
</script>
</body>

局部组件
局部组件使用的三部曲
1、创建组件
2、注册组件
3、引用组件
组件是相互独立的,不能直接跨作用域,vm这个实例也是一个组件,组件中拥有生命周期函数,如果组件共用了数据会导致同时更新,因此要求data必须是函数类型的。
子组件不能直接使用父组件的数据(组件间数据传递),组件理论上可以无限嵌套

<body>
<div id="app">
    <component1></component1>
    <component2></component2>
</div>

<script src="../node_modules/vue/dist/vue.js"></script>
<script>
    // 局部组件使用的三部曲
    // 1、创建组件
    // 2、注册组件
    // 3、引用组件
    let component1 = {
        template: '<div>{{msg}}</div>',
        data(){
           return {msg: '组件2'}
        }
    };
    let component2 = {
        template: '<div>组件2</div>',
    };
    let vm = new Vue({
        el: '#app',
        components:{
            component1,
            component2
        },
        data: {}
    });
</script>

组件间的嵌套:
1、被调用的子组件必须先定义,否则就拿不到。
2、哪里要用当前组件,就在哪里通过components注册,
3、需要在调用的组件中通过标签的形式引入
理论上是无限嵌套的,单位了好维护,一般最多嵌套3层

<div id="app">
    <!--<div>parent-->
        <!--<div>child-->
            <!--<div>grandson</div>-->
        <!--</div>-->
    <!--</div>-->
    <parent>
        <child>
            <grandson></grandson>
        </child>
    </parent>
</div>

<script src="../node_modules/vue/dist/vue.js"></script>
<script>
    let grandson = {
            template: `<div>grandson</div>`
        },
        child = {
            template: `<div>child<grandson></grandson></div>`,
            components:{
                grandson
            }
        },
        parent = {
        template: `<div>parent<child></child></div>`,
        components: {
            child
        }
    };
    let vm = new Vue({
        el: '#app',
        components:{
            parent,
        },
        data: {}
    });
</script>
</body>

父组件给子组件传值:属性传递,:money=""是传值的,传了一个空值,所以不会用到default,不在子组件定义这个属性,这才算不传值
required: true:表示该值必须传递,不穿就发警告,不能与默认值default同时出现。
校验时不会阻断代码的执行,只会出现警告
还可以自己定义校验信息,用validator方法,里面的参数就是当前传递的值,返回true表示通过反之不通过。(用的8多)

<body>
<div id="app">
    parent: {{money}}
    <!--m属于子,属性值属于父-->
    <!--当前组件的属性=父级的值-->
    <child :money="money"></child>
</div>

<script src="../node_modules/vue/dist/vue.js"></script>
<script>
    // 父传子
    let vm = new Vue({
        el: '#app',
        data: {
            money: 100,
            a: 400
        },
        components: {
            child: {
                // 会在当前子组件上声明一个m属性,值是父组件的
                // 数组的形式可以直接取值,但无法校验
                // props: ['money'], // this.m = money变量 this->child
                // 对象的形式可以校验
                props: {
                    // 子父组件中的属性名不能重复,控制台也会报错
                    // 父组件的会覆盖子组件的值
                    // 可以加个default值,不传值的时候就用默认值
                    money: {
                        // 判断传递值的类
                        // 如果不带冒号:,得到的肯定是字符串类型
                        // 类型不对页面上依旧会显示,但控制台会报类型错误
                        type: [Number],
                        // default: 0
                        required: true,
                        validator(val){ // 参数是当前传递的值,返回true表示通过
                            return val > 300;
                        }
                    }
                },
                template: '<div>child: {{money}}</div>'
            }
        }
    });
</script>
</body>

子组件给父组件传值:通过发布订阅的模式,父亲绑定一些事件,儿子触发这个事件,将参数传递过去,单向数据流 父组件数据刷新,子组件就刷新,不能子组件直接改父组件的值,要想这样,就需要子组件先通知父组件要修改值,父组件再去修改
在本例子中,子组件通过点击事件触发($emit)自己的child-msg方法,而该方法又触发了父组件的moreMoney方法执行,这样一来就实现了子组件向父组件传值

<body>
<div id="app">
    parent: {{money}} <button @click="lessMoney">少要点</button>
    <!--m属于子,属性值属于父-->
    <!--当前组件的属性=父级的值-->
    <!--刚刚那个事件是父级的,订阅需要在子级做-->

    <child :money="money" @child-msg="moreMoney"></child>
</div>

<script src="../node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el: '#app',
        data: {
            money: 400,
        },
        methods: {
            moreMoney(val){
                this.money = val;
            },
            lessMoney(){
                this.money = 200;
            }
        },
        components: {
            child: {
                props: ['money'],
                template: '<div>child: {{money}} 
                 <button @click="getMoney">再来点</button></div>',
                methods: {
                    getMoney(){ // 触发自己的自定义事件让父组件的方法执行
                        this.$emit('child-msg', 800);
                    }
                }
            }
        }
    });
</script>
</body>

sync语法糖的用法

<child :money="money" @update:money="val=>this.money=val"></child>
same as
<child :money.sync="money"></child>

子父组件声明周期
父组件需要等到子组件挂载完成(mounted)之后才会触发挂载

mounted(){
    console.log(this.$refs.child.$el.innerHTML); 
    // 1 2 3
    // 因为存在DOM映射,所以页面上的数据实时变化,
    // 但是DOM渲染是个异步的过程,这里还新的数据还没有渲染完
    this.$nextTick(() => {
          console.log(this.$refs.child.$el.innerHTML); 
          // 4 5 6
    });
},

兄弟组件间相互通信
eventBus一般不用,了解,发布订阅模式失败的原因是因为在不同组件中的this是不一样的,组件2触发,组件1监听,显然是行不通的。发布订阅的执行者应该是同一个才能成功,因此就需要有一个第三方实例eventBus来实现交互。

let brother1 = {
        template: '<div>{{color}} <button>变绿</button></div>',
        data() {
            return {color: '绿色', old: '绿色'}
        },
        created() {
            // 组件1监听
            this.$on('changeRed', (val) => { // 页面一加载,组件1长一个耳朵来监听
                this.color = val;
            })
        }
    };
let brother2 = {
        template: '<div>{{color}} <button @click="change">变红</button></div>',
        data() {
            return {color: '红色', old: '红色'}
        },
        methods: {
            change() {
                // 组件2发布
                this.$emit('changeRed', this.old);
            }
        }
};

eventBus使用,创建一个Vue实例,在兄弟组件中发布订阅都用这个实例来操作即可,但是触发的方法名不能重复,否则就乱套了

let eventBus = new Vue();
eventBus.$on('changeRed', (val) => { 
      this.color = val;
});
change() {
     eventBus.$emit('changeRed', this.old);
}

相关文章

  • VUE组件(传值,生命周期)

    VUE生命周期 VUE子传父组件通信 VUE非父子组件传值

  • 与Vue.js的第八天

    今天学习了Vue组件中的非父子之间的传值和生命周期Vue组件之间的传值分三种1.父传子之间传值用属性:props2...

  • Vue和React组件通信的总结

    在现代的三大框架中,其中两个Vue和React框架,组件间传值方式有哪些? 组件间的传值方式 组件的传值场景无外乎...

  • 前端基础搬运工-VUE模块

    十、VUE模块 基础部分 1. Vue组件间传值 答: -[ ] 1.父子之间的传值 父组件向子组件传值通过p...

  • vue 6种通信总结①

    常用vue通信大概有这几种方式进行: 组件间的父子之间的传值 组件间的子父之间的传值 非组件间的组件间的传值(简称...

  • Composition API的使用

    目标 父子组件传值props 和 context 祖孙组件传值provice和inject 生命周期 on**...

  • vue生命周期和组件间传值

    生命周期 new Vue() 初始化一些事件和生命周期 例如:vm.$on, vm.$once, vm.$em...

  • Vue组件间通信

    Vue组件间通信 父子组间通信 通过props向子组件传值,通过事件向父级组件发送消息 通过props向子组件传值...

  • vue组件间传值问题总结

    vue项目中,组件间传值的问题总结: 父传子 父组件 子组件 上面父组件和子组件之间的传值是模拟接口请求数据,然后...

  • vue组件间传值之eventBus

    1 概述: vue组件间的传值,父子之间props 和emit; 跨组件间可以使用vuex或者eventBus; ...

网友评论

      本文标题:vue生命周期和组件间传值

      本文链接:https://www.haomeiwen.com/subject/flvtdctx.html