组件间通信

  • provide 选项允许我们指定我们想要提供给后代组件的数据/方法。当多个子/孙组件需要调用同一个父组件的方法时使用。然后在任何后代组件里,我们都可以使用 inject 选项来接收指定的我们想要添加在这个实例上的属性(provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。在 Vue 2.2.1之前inject中的值在prop和data之后初始化)
// 父级组件提供 'foo'
var Provider = {
  provide: { // provide 选项应该是一个对象或返回一个对象的函数。
    foo: 'bar'
  },
  // ...
}

// 子组件注入 'foo'
var Child = {
  inject: ['foo'], 
  created () {
    console.log(this.foo) // => "bar"
  }
  // ...
}
// inject 选项应该是数组、对象(该对象的 key 是本地的绑定名,value 是搜索用的 key 或一个包含from和default属性的对象(from 属性是在可用的注入内容中搜索用的 key 、default 属性是降级情况下使用的 value))
inject:{
    myFoo:{
        from:'foo',
        default:'boy' // 与 prop 的默认值类似,你需要对非原始值(数组、对象)使用一个工厂方法
    }
}
  • 作用域插槽(从子组件传数据给父组件处理)
// 组件
<ul>
  <li
    v-for="todo in todos"
    v-bind:key="todo.id"
  >
    <!-- 我们为每个 todo 准备了一个插槽,-->
    <!-- 将 `todo` 对象作为一个插槽的 prop 传入。-->
    <slot v-bind:todo="todo">
      <!-- 回退的内容 -->
      {{ todo.text }}
    </slot>
  </li>
</ul>

// 使用(获取组件中传出的数据)
<todo-list v-bind:todos="todos">
  <!-- 将 `slotProps` 定义为插槽作用域的名字 -->
  <template slot-scope="slotProps"> // 这里可以使用解构语法{ todo }
    <!-- 为待办项自定义一个模板,-->
    <!-- 通过 `slotProps` 定制每个待办项。-->
    <span v-if="slotProps.todo.isComplete">✓</span>
    {{ slotProps.todo.text }}
  </template>
</todo-list>
  • 对一个 prop 进行“双向绑定”。
<text-document v-bind:title.sync="doc.title"></text-document>
// 实际为
<text-document
  v-bind:title="doc.title"
  v-on:update:title="doc.title = $event"  // 这里绑定的updata:title由emit触发,$event只想emit传入的第二个参数
></text-document>

...
watch:{
    title(newTitle){
        this.$emit('update:title', newTitle)
    }
}
...
  • 一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件
Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },

<base-checkbox v-model="lovingVue"></base-checkbox>
// 使用 v-model 的时候,这里的 lovingVue 的值将会传入这个名为 checked 的 prop。同时当 <base-checkbox> 触发一个 change 事件并附带一个新的值的时候,这个 lovingVue 的属性将会被更新。
  • $attrs 属性包含了传递给一个组件的特性名和特性值(即使设置了inheritAttrs: false),和inheritAttrs: false配合,可以手动决定这些特性会被赋予哪个元素。
// $attrs 返回一个绑定到该组件的属性的对象(在api中说明不包括class和style,但是在教程中却包含了class,需要验证)
{
  class: 'username-input',
  placeholder: 'Enter your username'
}

props

  • 不能使用this
  • 对一个 prop 进行“双向绑定”。
<text-document v-bind:title.sync="doc.title"></text-document>
// 实际为
<text-document
  v-bind:title="doc.title"
  v-on:update:title="doc.title = $event" 
></text-document>

...
watch:{
    title(newTitle){
        this.$emit('update:title', newTitle) 
    }
}
...
  • 当我们用一个对象同时设置多个 prop 的时候,也可以使用<text-document v-bind="doc"></text-document>。但是不允许绑定字面量对象,例如v-bind=”{ title: doc.title }”无法正常工作
  • 可以传入一个未定义的prop,会自动添加到的根元素上(不一定会添加到根元素上,组件可以通过设置inheritAttrs来禁止绑定,同时还可以通过$attrs来获取绑定到组件上的属性)。对于绝大多数特性来说,从外部提供给组件的值会替换掉组件内部设置好的值。所以如果传入 type="text" 就会替换掉 type="date" 并把它破坏!庆幸的是,class 和 style 特性会稍微智能一些,即两边的值会被合并起来,从而得到最终的值
  • 验证,props 会在一个组件实例创建之前进行验证,所以实例的属性 (如 data、computed 等) 在 default(默认值,当是数组或对象是需要函数返回) 或 validator(传入值校验) 函数中是不可用的。
props: {
    propA:{
        type: Number,
        default: 100, // 对象或数组默认值必须从一个工厂函数获取
        required: true, // 必传
        validator: function (value) { // 自定义验证函数
            // 这个值必须匹配下列字符串中的一个
            return ['success', 'warning', 'danger'].indexOf(value) !== -1
        }
    }
}
  • 如果你想要将一个对象的所有属性都作为 prop 传入,你可以使用不带参数的 v-bind (取代 v-bind:prop-name)
<blog-post v-bind="post"></blog-post>
// 等价于
<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>
  • type可以是下列原生构造函数中的一个String、Number、Boolean、Array、Object、Date、Function、Symbol,还可以是一个自定义的构造函数,并且通过 instanceof 来进行检查确认。prop 的值是否是通过 new Person 创建的。
function Person (firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}

Vue.component('blog-post', {
  props: {
    author: Person
  }
})
// 类同于
propA: Number

provide / inject

  • provide 选项允许我们指定我们想要提供给后代组件的数据/方法。当多个子/孙组件需要调用同一个父组件的方法时使用。然后在任何后代组件里,我们都可以使用 inject 选项来接收指定的我们想要添加在这个实例上的属性(provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。在 Vue 2.2.1之前inject中的值在prop和data之后初始化)
// 父级组件提供 'foo'
var Provider = {
  provide: { // provide 选项应该是一个对象或返回一个对象的函数。
    foo: 'bar'
  },
  // ...
}

// 子组件注入 'foo'
var Child = {
  inject: ['foo'], 
  created () {
    console.log(this.foo) // => "bar"
  }
  // ...
}
// inject 选项应该是数组、对象(该对象的 key 是本地的绑定名,value 是搜索用的 key 或一个包含from和default属性的对象(from 属性是在可用的注入内容中搜索用的 key 、default 属性是降级情况下使用的 value))
inject:{
    myFoo:{
        from:'foo',
        default:'boy' // 与 prop 的默认值类似,你需要对非原始值(数组、对象)使用一个工厂方法
    }
}

v-bind

  • 当绑定为布尔值flase时,该特性不会绑定给元素
  • 当 v-bind:style 使用需要添加浏览器引擎前缀的 CSS 属性时,如 transform,Vue.js 会自动侦测并添加相应的前缀。所以尽量使用
  • 从 2.3.0 起你可以为 style 绑定中的属性提供一个包含多个值的数组,这样写只会渲染数组中最后一个被浏览器支持的值。
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
  • 如果你想要将一个对象的所有属性都作为 prop 传入,你可以使用不带参数的 v-bind
post = {
    id:' ',
    title:' '
}
<blog-post v-bind="post"></blog-post>
// 等价于
<blog-post
  v-bind:id="post.id"
  v-bind:title="post.title"
></blog-post>

v-model

  • 在inpu中,可以使用修饰符.lazy(使用 change 事件进行输入数据同步).number(自动将用户的输入值转为数值类型,原生中即使在 type="number" 时,HTML 输入元素的值也总会返回字符串).trim(自动过滤用户输入的首尾空白字符)
  • 下拉菜单选项的value可以绑定为任意内存对象,不一定要是字符串。只要传入相同键值的对象就能够选中下拉项(测试来源于饿了吗组件)
  • select下拉菜单,单选为文本,多选为文本数组(option有value时优先绑定)。如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此,更推荐提供一个值为空的禁用选项。
<div id="example-5">
  <select v-model="selected">
    <option disabled value="">请选择</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
  • 单选按钮绑定value值
  • 复选框可以单独设置选中和未选中时的值
<input
  type="checkbox"
  v-model="toggle"
  true-value="yes"
  false-value="no"
>
  • 多个复选框,绑定到同一个数组:
<div id='example-3'>
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
</div>

new Vue({
  el: '#example-3',
  data: {
    checkedNames: []    //=>['Jack','John']
  }
})
  • 单个复选框,绑定到布尔值:<input type="checkbox" id="checkbox" v-model="checked">选中时checked为true,否则为false。不需要value
  • 对于需要使用输入法 (如中文、日文、韩文等) 的语言,你会发现 v-model 不会在输入法组合文字过程中得到更新。如果你也想处理这个过程,请使用 input 事件。当用输入法时能够捕获输入的每个拼音字母
  • 一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件
Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },

<base-checkbox v-model="lovingVue"></base-checkbox>
// 使用 v-model 的时候,这里的 lovingVue 的值将会传入这个名为 checked 的 prop。同时当 <base-checkbox> 触发一个 change 事件并附带一个新的值的时候,这个 lovingVue 的属性将会被更新。
  • 在组件中使用v-model
// input中
<input v-model="searchText">
// 等价于
<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>

// 组件中
<custom-input v-model="searchText"></custom-input>
// 等价于
<custom-input
  v-bind:value="searchText"
  v-on:input="searchText = $event"
></custom-input>

// 组件内部定义
Vue.component('custom-input', {
  props: ['value'],
  template: `
    <input
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)" // $event.target指向时间对象,input对象有value属性
    >
  `
})

slot-scope

  • 作用域插槽(从子组件传数据给父组件处理)
// 组件
<ul>
  <li
    v-for="todo in todos"
    v-bind:key="todo.id"
  >
    <!-- 我们为每个 todo 准备了一个插槽,-->
    <!-- 将 `todo` 对象作为一个插槽的 prop 传入。-->
    <slot v-bind:todo="todo">
      <!-- 回退的内容 -->
      {{ todo.text }}
    </slot>
  </li>
</ul>

// 使用(获取组件中传出的数据)
<todo-list v-bind:todos="todos">
  <!-- 将 `slotProps` 定义为插槽作用域的名字 -->
  <template slot-scope="slotProps"> // 这里可以使用解构语法{ todo }
    <!-- 为待办项自定义一个模板,-->
    <!-- 通过 `slotProps` 定制每个待办项。-->
    <span v-if="slotProps.todo.isComplete">✓</span>
    {{ slotProps.todo.text }}
  </template>
</todo-list>

slot

  • 作用域插槽(从子组件传数据给父组件处理)
// 组件
<ul>
  <li
    v-for="todo in todos"
    v-bind:key="todo.id"
  >
    <!-- 我们为每个 todo 准备了一个插槽,-->
    <!-- 将 `todo` 对象作为一个插槽的 prop 传入。-->
    <slot v-bind:todo="todo">
      <!-- 回退的内容 -->
      {{ todo.text }}
    </slot>
  </li>
</ul>

// 使用(获取组件中传出的数据)
<todo-list v-bind:todos="todos">
  <!-- 将 `slotProps` 定义为插槽作用域的名字 -->
  <template slot-scope="slotProps"> // 这里可以使用解构语法{ todo }
    <!-- 为待办项自定义一个模板,-->
    <!-- 通过 `slotProps` 定制每个待办项。-->
    <span v-if="slotProps.todo.isComplete">✓</span>
    {{ slotProps.todo.text }}
  </template>
</todo-list>

猜你喜欢

转载自www.cnblogs.com/qq3279338858/p/10282271.html