Vue——组件高级——传值

目录

组件高级

一、传值

1 正向属性传值——父传子 

2反向传值——子传父

2.1 子组件通过自定义事件给父组件传新值 $emit

2.2 反向传值的sync

2.3 反向传值的v-model

3多层组件传值:$listeners/$attrs(了解)

4 $ parent/$root、$children/$refs(了解)

5中央事件总线bus(了解)  event bus

6Vue 依赖注入 - **Provide/Inject(重点)**

7仓库vuex(重点)

二、笔试题 / 面试题

1、关于 Vue 组件间的参数传递,下列哪项是不正确的?

2、下列关于 v-model 的说法,哪项是不正确的?


组件高级

1、传值     2.动态组件    3.缓存组件keep-alive     4.异步组件(高薪意向)

一、传值

1 正向属性传值——父传子 

父组件通过属性给子组件传值: 子组件的props接受数据

在页面模板中 使用变量名:属性  data  计算属性(重点)

//注意属性传值是单向的

APP.vue




 Box.vue




2反向传值——子传父

2.1 子组件通过自定义事件给父组件传新值 $emit

子组件通过自定义事件给父组件传count的新值n,父组件收到新值后修改自己的data,自然就会刷新自己 和子组件的模板

子组件通过调用父组件的方法给父组件传值:子组件的自定义事件中,用$emit触发事件调用父组件方法给父组件传值 (重点)

**因为通过属性传值是单向的**,有时候我们需要子组件的data 数据需要交给父组件使用:
通过在子组件上定义自定义事件,在子组件中通过$emit 来触发事件;子组件的事件被触发并传参,事件处理函数可以接收到子组件的数据;事件绑定的事件处理函数在父节点上,故可在事件处理函数中用到子组件的数据值来修改父节点的数据。

//父组件中:

//myevent是事子组件的自定义事件 
//handleEvent是绑定的父组件的方法


子组件中:
在任意业务中触发事件:this.$emit("myevent","要给父组件传的数据")

app.vue




Box.vue




2.2 反向传值的sync

此方法就省略了写事件名字

自定义事件

子组件==>methods里面==>this.$emit("update:a1","数据更新了“)

父组件==> 

app.vue




Box.vue




2.3 反向传值的v-model

父组件:

   

(v-model这是一个语法糖==>     )

子组件:

props:["value"],,然后上面的标签使用这个{{value}}

点击写事件:fn(){this.$emit("input","传值")}

v-model.语法==>官网学

APP.vue




Box.vue




3多层组件传值:$listeners/$attrs(了解)

在不用状态管理vuex的时候,如何让GrandFather与Son通信,我们可以用可以emit一层一层的传递,==>但是会显得冗余

vue2.4之后,提出$attrs、$listeners ,可以实现跨级组件通信。

$listeners官网解说:事件传递     $attrs官网解说:属性传递

在组件中绑定 可以把当前组件的自定义属性和方法传给子元素使用:

one组件:
two组件中:
three组件:可以访问two的 属性和触发事件: {{this.$attrs.xx}} this.$emit("twoEvent",20)

APP.vue




Box1.vue




Box2.vue




4 $ parent/$root、$children/$refs(了解)

这些功能都是有劣势或危险的场景的,官方建议我们尽量避开它们,但是高级点的面试题中会出现

$root:

访问根组件vm (就是new Vue)对象,所有的子组件都可以将这个实例作为一个全局 store 来访问或使用,现在有更好的技术vuex代替。
 
 $parent:

访问父组件对象,直接操作父组件的data数据,不需要再使用属性传值,但是容易出现渲染混乱之后只渲染一个的情况
 
 $children:

访问子组件对象数组,不能保证顺序,没有按照顺序加载,加载的顺序是乱的,因此写项目的时候不能按照下标去获取组件,然后操作组件。也不是响应式的
          
 $refs:

只会在组件渲染完成之后生效,并且它们不是响应式的。应该避免在模板或计算属性中访问 $refs。 (就相当于DOM获取元素)


Tips:

1、在Box1中打印this,this.$parent,$root,就会打印自己的VueComponent 、app.vue的VueComponent 、 Vue根节点对象

2、$parent 、$children都是代表组件,不是元素,就算Box1放在一个div中,它的$parent也是app.vue

3、可以直接修改 父/爷爷/孙子/...组件:

this.$parent.msg="Box1将app.vue里面的msg修改了"

 //在组件或者原生元素绑定ref属性(类似于id):
 
 
 
 //在父组件中可以通过 this.$refs访问到它:
 methods: {
   focus: function () {
     this.$refs.myInput2.focus()
   }
 }

 APP.vue




Box1.vue




 Box2.vue




案例:利用$ref实现放大镜代码迁移

一个网站中有一个很好的功能,别人是DOM操作,而我们用Vue来操作,获取元素

==>mounted之后就去执行,将它的class改为ref,然后用var div1=this.$refs.div1来获取




5中央事件总线bus(了解)  event bus

通过创建一个新的vm对象,专门统一注册事件,供所有组件共同操作,达到所有组件随意隔代传值的效果

//vue-bus.js文件
const install = function (Vue) {
  const Bus = new Vue({
    methods: {
      emit(event, ...args) {
        this.$emit(event, ...args);
      },
      on(event, callback) {
        this.$on(event, callback);
      },
      off(event, callback) {
        this.$off(event, callback);
      }
    }
  });
  Vue.prototype.$bus=Bus;//由于这个新的vm放在与界面绑定的那个vm的原型上,因此页面上的所有组件都能通过this.$bus访问这个新vm对象
};
export default install;




//main.js文件
import VueBus from './vue-bus'
Vue.use(VueBus);

//组件文件中:
任意业务中都可以通过调用来绑定事件,触发事件并传值,和销毁事件 
this.$bus.on(event,callback) 
this.$bus.off(event,callback) 
this.$bus.emit(event, ...args)

示例:
组件1:
 this.$bus.on('changedFormObject',(val) =>{
	        //接受并处理传过来的值:val
            this.msg = val;
        });

组件2:
this.$bus.emit('changedFormObject',this.inputValue);//把组件2的data中的给inputValue值传给组件1

6Vue 依赖注入 - **Provide/Inject(重点)**

通常情况下,**父**组件向**孙**组件传递数据,可以采用父子`props`层层传递,也可以使用`bus`和`Vuex`直接交互。在Vue2.2.0之后,Vue还提供了`provide/inject`选项

 官网不建议在应用中直接使用该办法,理由很直接:他怕你"管不好"

//爷爷



//爸爸


//孙子

7仓库vuex(重点)

后面讲

二、笔试题 / 面试题

1、关于 Vue 组件间的参数传递,下列哪项是不正确的?

A. 若子组件给父组件传值,可使用 $emit 方法
B. 祖孙组件之间可以使用 provide 和 inject 方式跨层级相互传值
C. 若子组件使用 $emit('say') 派发事件,父组件可使用 @say 监听
D. 若父组件给子组件传值,子组件可通过 props 接受数据

选B

2、下列关于 v-model 的说法,哪项是不正确的?

A. v-model 能实现双向绑定
B. v-model 本质上是语法糖,它负责监听用户的输入事件以更新数据
C. v-model 是内置指令,不能用在自定义组件上
D. 对 input 使用 v-model,实际上是指定其 :value 和 @input

选C,能用

 

3、关于 Vue 组件间的参数传递,下列哪项是不正确的?

A. 若子组件给父组件传值,可使用 $emit 方法
B. 祖孙组件之间可以使用 provide 和 inject 方式跨层级相互传值
C. 若子组件使用 $emit('say') 派发事件,父组件可使用 @say 监听
D. 若父组件给子组件传值,子组件可通过 props 接受数据

选B

4、下列说法不正确的是哪项?

A. 可通过 this.$parent 查找当前组件的父组件
B. 可使用 this.$refs 查找命名子组件
C. 可使用 this.$children 按顺序查找当前组件的直接子组件
D. 可使用 $root 查找根组件,并可配合 children 遍历全部组件

选C  无顺序

你可能感兴趣的:(前端,javascript,开发语言,面试,vue.js)