美文网首页
阅读vue 文档学习笔记

阅读vue 文档学习笔记

作者: 风间澈618 | 来源:发表于2020-09-22 10:17 被阅读0次

    v2.6

    模板语法

    可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:
    <a v-bind:[attributeName]="url"> ... </a>
    同样地,你可以使用动态参数为一个动态的事件名绑定处理函数:
    <a v-on:[eventName]="doSomething"> ... </a>
    对动态参数的值的约束
    动态参数预期会求出一个字符串,异常情况下值为 null。
    这个特殊的 null 值可以被显性地用于移除绑定。
    任何其它非字符串类型的值都将会触发一个警告。

    计算属性缓存vs方法

    计算属性基于它们的响应式依赖进行缓存,
    这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:

    computed: {
      now: function () {
        return Date.now()
      }
    }
    
    计算属性的setter
    computed:{
    get:function(){
     return this.firstName+' '+this.lastName
    },
    set:function(newValue){
        var names=newValue.split(' ')
        this.firstName=names[0]
        this.lastName=names[names.length-1]
    }
    }
    
    侦听器

    虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。
    这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。
    当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

    class与style绑定

    绑定class
    对象绑定

    <div
      class="static"
      v-bind:class="{ active: isActive, 'text-danger': hasError }"
    ></div>
    

    和如下 data:

    data: {
      isActive: true,
      hasError: false
    }
    
    数组语法

    我们可以把一个数组传给 v-bind:class,以应用一个 class 列表:

    <div v-bind:class="[activeClass, errorClass]"></div>
    data: {
      activeClass: 'active',
      errorClass: 'text-danger'
    }
    

    在数组中使用对象
    <div v-bind:class="[{ active: isActive }, errorClass]"></div>

    绑定内联样式

    v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。
    CSS 属性名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名:

    <div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
    data: {
      activeColor: 'red',
      fontSize: 30
    }
    
    数组语法数组语法

    v-bind:style 的数组语法可以将多个样式对象应用到同一个元素上:

    <div v-bind:style="[baseStyles, overridingStyles]"></div>
    
    Vue.component('blog-post',{
        props:['title'],
        template:`<h3>{{title}}</h3>`
    })
    
    全局注册
    Vue.component('my-component-name', {
      // ... 选项 ...
    })
    
    局部注册

    在这些情况下,你可以通过一个普通的 JavaScript 对象来定义组件:

    var ComponentA = { /* ... */ }
    var ComponentB = { /* ... */ }
    var ComponentC = { /* ... */ }
    

    然后在 components 选项中定义你想要使用的组件:

    new Vue({
      el: '#app',
      components: {
        'component-a': ComponentA,
        'component-b': ComponentB
      }
    })
    
    基础组件的自动化全局注册
    import Vue from 'vue'
    import upperFirst from 'lodash/upperFirst'
    import camelCase from 'lodash/cameCase'
    const requireComponent=require.context(
       //其组件目录的相对路径
      './components',
      //是否查询其子目录
      false,
      //匹配基础组件的文件名的正则表达式
      /Base[A-Z]\w+\.(vue|js)$/
    )
    requireComponent.keys().forEach(fileName=>{
        //获取组件配置
        const componentConfig=requireComponent(fileName)
        //获取组件的PascalCase命名
        const componentName=upperFirst(
            cmaeCase(
                fileName.split('/').pop().replace(/\.\w+$/,'')
            )
        )
    //全局注册
    Vue.component(componentName,
        //如果这个组件选项是通过'export default'导出
        //那么就会优先使用'.default'
        //否则回退到使用模块的根
        componentConfig.default||componnentConfig
    )
    })
    

    传入一个对象的所有属性
    如果你想要将一个对象的所有属性都作为 prop 传入,你可以使用不带参数的 v-bind (取代 v-bind:prop-name)。例如,对于一个给定的对象 post:

    post: {
      id: 1,
      title: 'My Journey with Vue'
    }
    

    下面的模板:

    <blog-post v-bind="post"></blog-post>
    等价于:
    
    <blog-post
      v-bind:id="post.id"
      v-bind:title="post.title"
    ></blog-post>
    
    单向数据流

    所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

    额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

    这里有两种常见的试图改变一个 prop 的情形:

    这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:

    props: ['initialCounter'],
    data: function () {
      return {
        counter: this.initialCounter
      }
    }
    

    这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:

    props: ['size'],
    computed: {
      normalizedSize: function () {
        return this.size.trim().toLowerCase()
      }
    }
    

    注意在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态。

    propF:{
    validator:function(value){
     return ['success','danger'].indexOf(value)!==-1
    }
    }
    
    将原生事件绑定到组件

    在有的时候这是很有用的,不过在你尝试监听一个类似 <input> 的非常特定的元素时,这并不是个好主意。
    比如上述 <base-input> 组件可能做了如下重构,所以根元素实际上是一个 <label> 元素:

    Vue.component('base-input',{
        inheritAttrs:false,
        props:['label','value'],
        computed:{
            inputListeners:function(){
              var vm=this
              return Object.assign({},
                this.$listeners,
                //然后我们添加自定义监听器
                //或覆写一些监听器的行为
                {
                    //这里确保组件配合'v-model'的工作
                    input:function(event){
                        vm.$emit('input',event.target.value)
                    }
                }
              )
            }
        },
        template:`
          <label>
            {{label}}
            <input
                v-bind="$attrs"
                v-bind:value="value"
                v-on="inputListeners"
            >
          </label>
        `
    })
    
    具名参数
    <div class="container">
      <header>
        <slot name="header"></slot>
      </header>
      <main>
        <slot></slot>
      </main>
      <footer>
        <slot name="footer"></slot>
      </footer>
    </div>
    

    一个不带 name 的 <slot> 出口会带有隐含的名字“default”。

    在向具名插槽提供内容的时候,我们可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:

    <base-layout>
      <template v-slot:header>
        <h1>Here might be a page title</h1>
      </template>
    
      <p>A paragraph for the main content.</p>
      <p>And another one.</p>
    
      <template v-slot:footer>
        <p>Here's some contact info</p>
      </template>
    </base-layout>
    

    现在 <template> 元素中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 v-slot 的 <template> 中的内容都会被视为默认插槽的内容。

    过渡js钩子
    <transition v-on:enter="enter"></transition>
    
    状态过滤-把过渡放组件里
    Vue.component('animated-integer',{
    template:'<span>{{tweeningValue}}</span>',
    props:{
        value:{
        }
    },
    data:function(){
    },
    watch:{
    },
    mouted:function(){
    },
    methods:{
    
    }
    
    })
    <div id="example">
     <animated-integer></animated-integer>
    </div>
    new Vue({
     el:'#example',
     data:{
      firstnumber:20,
      lastnumber:40
     },
     computed:{
        result:function(){
        
        }
     }
    
    })
    
    混入
    var myMixin={
     created:function(){
      
     }
    }
    var Component=Vue.extend({
     mixins:[myMixin]
    })
    var component=new Component()
    

    选项合并
    1 数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。
    2 同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用

    全局混入

    Vue.mixin({
      created:function(){
        var myOption=this.$options.myOption
        if(myOption){
            console.log(myOption)
        }
      }
    })
    
    new Vue({
     myOption:'HELLO'
    })
    
    自定义选项合并策略

    //函数
    Vue.config.optionMergeStrategies.myOption=function(toVal,fromVal){
    //返回合并后的值
    }
    //或者使用与methods相同的合并策略

    var strategies=Vue.config.optionMergeStrategies
    strategies.myOption=strategies.methods
    
    
    const merge=Vue.config.optionMergeStrategies.computed
    Vue.config.optionMergeStragies.vux=function(toVal,fromVal){
     if(!toVal) return fromVal
     if(!fromVal) return toVal
     return {
        getters:merge(toVal.getters,fromVal.getters),
        state:merge(toVal.state,fromVal.state),
        actions:merge(toVal.actions,fromVal.actions)
     }
    }
    

    自定义指令
    全局指令

    Vue.directive('focus',{
        //当被绑定元素插入到dom时
        inserted:function(el){
            //聚焦元素
            el.focus()
        }
    })
    

    注册局部指令,组件中也接受一个directives的选项

    directives:{
        focus:{
            inserted:function(el){
                el.focus()
            }
        }
    }
    <input v-focus>
    

    一个指令定义对象可以提供如下几个钩子函数 (均为可选):

    bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

    inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

    update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。
    但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
    componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

    unbind:只调用一次,指令与元素解绑时调用。

    函数简写

    在很多时候,你可能想在 bind 和 update 时触发相同行为,而不关心其它的钩子。比如这样写:

    Vue.directive('color-swatch', function (el, binding) {
      el.style.backgroundColor = binding.value
    })
    
    渲染函数

    createElement 参数

    createElement(
      // {String | Object | Function}
      // 一个 HTML 标签名、组件选项对象,或者
      // resolve 了上述任何一种的一个 async 函数。必填项。
        'div',
        //{object} 一个与模板中属性对应的数据对象
        {
        
        },
        //子级虚拟节点(Vnode),由createElement(),构建而成
        //也可以使用字符串来生成‘文本虚拟节点’,可选
        [
         'some word',
         createElment(MyComponent,{
            props:{
                someProp:'foobar'
            }
         })
        ]
    
    )
    

    示例

    var getChildrenTextContext=function(children){
        return children.map(function(node){
            return node.children?getChildrenTextContext(node.children):
            node.text
        }).join('')
    }
    
    Vue.component('anchored-heading',{
        render:function(createElement){
            var headingId=getChildrenTextContext(this.$slots.default)
            .toLowerCase()
            .replace(/\W+/g,'-')
            .replace(/(^-|-$)/,'')
            
            return createElement(
                'h'+this.level,
                [
                  createElement('a',{
                    attrs:{
                        name:headingId,
                        href:'#'+headingId
                    }
                  },this.$slots.default)
                ]
            )
        },
        props:{
            level:{
                type:Number,
                required:true
            }
        }
        
    })
    //v-model
    props:['value'],
    render:function(createElement){
     var self=this
     return createElement('input',{
        domProps:{
            value:self.value
        },
        on:{
            input:function(event){
                self.$emit('input',event.target.value)
            }
        }
     })
    }
    
    函数式组件

    之前创建的锚点标题组件是比较简单,没有管理任何状态,也没有监听任何传递给它的状态,也没有生命周期方法。实际上,它只是一个接受一些 prop 的函数。
    在这样的场景下,我们可以将组件标记为 functional,这意味它无状态 (没有响应式数据),也没有实例 (没有 this 上下文)。

    Vue.component('my-component',{
     functional:true,
     props:{
        
     },
     render:function(createElement,content){
     
     }
    })
    
    插件

    插件通常用来为 Vue 添加全局功能。插件的功能范围没有严格的限制——一般有下面几种:

    添加全局方法或者属性。如: vue-custom-element

    添加全局资源:指令/过滤器/过渡等。如 vue-touch

    通过全局混入来添加一些组件选项。如 vue-router

    添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。

    一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router

    Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:

    MyPlugin.install=function(Vue,options){
        //全局方法或属性
        Vue.myGlobalMethod=function(){
        
        }
        //添加全局资源
        Vue.directive('my-directive',{
            bind(el,binding,vnode,oldVnode){
            
            }
        })
        //注入组件选项
        Vue.mixin({
            created:function(){
            
            }
            
        })
        //添加实例方法
        Vue.prototype.$myMethod=function(methodOptions){
        
        }
    }
    

    相关文章

      网友评论

          本文标题:阅读vue 文档学习笔记

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