zoukankan      html  css  js  c++  java
  • 数据绑定 / 组件通信

    • 当前函数运行造成传递的数据改变的执行顺序:1、执行完当前函数(这个时候调用子组件中的方法拿到的值依然是旧的,因为还未传递到子组件中)。 2、传递数据到子组件中。3、执行页面更新
    // 父组件
    <my-components :commonData='commonData' @changeCommonData='changeCommonData'></my-components>
    changeCommonData(data){
        this.commonData = data
    }
    
    // my-components子组件中
    doSome(){
        this.$emit('changeCommonData',data) // data === 2,这时父组件中的commonData已经更改为2,但是子组件的响应,要等待当前函数执行完后响应
        console.log(this.commonData) // 原始值是1,
    }
    

    —————————————————————————————————————————————————————————

    组件内

    props

    • 使用some-propssomeProps的命名方式,外部都可以通过some-propssomeProps赋值,在内部只能通过this.someProps获得
      • 内部使用驼峰式命名
      • 外部视使用情况是否使用驼峰式
    • 不能使用this
    • .sync对一个 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,会自动添加到的根元素上(不一定会添加到根元素上,组件可以通过设置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
            }
        }
    }
    
    • 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
    

    inheritAttrs

    • 可以传入一个未定义的prop,会自动添加到的根元素上(不一定会添加到根元素上,组件可以通过设置inheritAttrs来禁止绑定,同时还可以通过$attrs来获取绑定到组件上的属性)。对于绝大多数特性来说,从外部提供给组件的值会替换掉组件内部设置好的值。所以如果传入 type="text" 就会替换掉 type="date" 并把它破坏!庆幸的是,class 和 style 特性会稍微智能一些,即两边的值会被合并起来,从而得到最终的值
    • 如果你不希望组件的根元素继承特性,你可以设置在组件的选项中设置
    Vue.component('my-component', {
      inheritAttrs: false,
      // ...
    })
    

    —————————————————————————————————————————————————————————

    组件外

    v-bind

    • 当在一个自定义组件上使用 class 属性时,这些类将被添加到该组件的根元素上面。这个元素上已经存在的类不会被覆盖。
    • 当绑定为布尔值flase时,该特性不会绑定给元素
    • 当 v-bind:style 使用需要添加浏览器引擎前缀的 CSS 属性时,如 transform,Vue.js 会自动侦测并添加相应的前缀。所以尽量使用(需要browserslist目标浏览器支持吗?)
    • 从 2.3.0 起你可以为 style 绑定中的属性提供一个包含多个值的数组,这样写只会渲染数组中最后一个被浏览器支持的值。(需要browserslist目标浏览器支持吗?)
    <div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
    
    • 如果你想要将一个对象的所有属性都作为 prop 传入,你可以使用不带参数的 v-bind (取代 v-bind:prop-name)。但是不允许绑定字面量对象,例如v-bind=”{ title: doc.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(自动过滤用户输入的首尾空白字符)

    • 对于需要使用输入法 (如中文、日文、韩文等) 的语言,你会发现 v-model 不会在输入法组合文字过程中得到更新。如果你也想处理这个过程,请使用 input 事件。当用输入法时能够捕获输入的每个拼音字母

    • 下拉菜单选项的value可以绑定为任意内存对象,不一定要是字符串。只要传入相同键值的对象就能够选中下拉项(测试来源于饿了吗组件)

    • select下拉菜单,单选为文本,多选为文本数组(option有value时优先绑定)。如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。因此,更推荐提供一个值为空的禁用选项。

    <div id="example-5">
      <select v-model="selected"> // selected 默认为''
        <option disabled value="">请选择</option>
        <option>A</option>
        <option>B</option>
        <option>C</option>
      </select>
      <span>Selected: {{ selected }}</span>
    </div>
    
    • 单选按钮绑定value值
    <input type="radio" id="huey" name="drone" value="huey" checked>    // checked初始被选中
    
    • 复选框可以单独设置选中和未选中时的值
    <input
      type="checkbox"
      v-model="toggle"
      true-value="yes"
      false-value="no"
    >
    
    • 单个复选框,绑定到布尔值:<input type="checkbox" id="checkbox" v-model="checked">选中时checked为true,否则为false。不需要value
    • 多个复选框,绑定到同一个数组:
    <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']
      }
    })
    
    • 在组件中使用v-model
    // input中
    <input v-model="searchText">
    // 等价于
    <input
      v-bind:value="searchText"
      v-on:input="searchText = $event.target.value"    // 这里的$event是事件对象
    >
    
    
    // 组件中
    // 组件外部使用
    <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属性
        >
      `
    })
    
    • 一个组件上的 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 的属性将会被更新。
    

    —————————————————————————————————————————————————————————

    插槽通讯

    slot和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(非作用域插槽)可以传入多个子元素

    <template>

    • v-show 不支持 <template> 元素。如果需要非常频繁地切换,则使用 v-show 较好;

    —————————————————————————————————————————————————————————

    后代组件通讯

    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:{
        myFoo1:'foo',
        myFoo:{
            from:'foo',
            default:'boy' // 与 prop 的默认值类似,你需要对非原始值(数组、对象)使用一个工厂方法
        }
    }
    

    bus只是一种解决方案并不是vue提供的官方示例

    • 局部bus
    // 组件1
    import Bus from './Bus'
    
    export default {
        data() {
            return {
                .........
                }
          },
      methods: {
            ....
            Bus.$emit('log', 120)
        },
    
      } 
    
    // 组件2
    import Bus from './Bus'
    
    export default {
        data() {
            return {
                .........
                }
          },
        mounted () {
           Bus.$on('log', content => { 
              console.log(content)
            });    
        }    
    } 
    
    • 全局bus
    import Vue from 'vue'
    const Bus = new Vue()
    
    var app= new Vue({
        el:'#app',
       data:{
        Bus
        }  
    
    })
    
  • 相关阅读:
    Sql的基础知识(一)
    Django--分页功能
    django--基础操作
    CSRF攻击与防御(转载)
    谈谈CSRF
    浅谈Dom遍历
    node50行代码实现壁纸爬取
    node解决request中文乱码问题
    数组去重方法(转载)
    淘宝dns解析错误导致首页打不开
  • 原文地址:https://www.cnblogs.com/qq3279338858/p/10282271.html
Copyright © 2011-2022 走看看