Vue 常用 API 整理 1 - 组件属性与方法

1. 单文件组件说明

.vue 文件是一个自定义的文件类型,用类HTML语法描述一个Vue组件。每个 .vue 文件包含三种类型的顶级语言块

    <template>
        <!-- 
            HTML 代码,
            每个 .vue 文件对多包含一个<template> 
            内容将会被提取为字符串,将编译并用作Vue组件的template选项
        -->
    </template>

    <script>
        /*
            javascript 代码,
            每个 .vue 文件对多包含一个<script>,
            可以通过 require、import、export 引入或者导出其他模块
            导出的对象为 vue组件对象
        */ 
    </script>

    <style>
        /* 
            样式代码
            一个 .vue文件可以包含多个 <style>,
            通过设置 style 标签的 lang属性 可以配置预处理器 sass less,
            当 style 标签有 scoped 属性时,他的 css 只作用于组件中的元素
        */
    </style>

项目中通过安装 vue-loader 来解析这种文件,它会提取每个语言快,经过相应的 loader 处理,最后组成一个 CommonJs 模块,输出一个 Vue组件对象

如果习惯于将 结构、表现、行为分离,可以分割 .vue 文件为多个文件,通过 src 引用

    <template src="./template.html"></template>

    <script src="./script.js"></script>

    <style src="./style.css"></style>

2. 创建Vue实例

每个 Vue 应用都是他通过 Vue 函数创建一个新的 Vue 实例开始的,创建实例时,可以传入一个选项对象,这些选项对象用来配置你想要的行为

    var vm = new Vue({
        data: {},
    })

在大型项目中,一个应用只需要一个 他通过 new Vue() 创建的根实例,其他部分通过嵌套组件来完成

3. 实例属性、组件的属性

Vue 实例暴露了一些有用的实例属性与方法,他们在创建实例时,写在配置对象中,创建实例后可以通过
添加前缀 $ 后的属性名调用,以便与用户定义的属性区分

    vm.$data => data
    vm.$props => props
    vm.$el => el
    ...
1. data

实例或者、组件的数据对象,数据类型为对象或者函数(必须返回值为对象),组件的 data 只能是含有对象返回值的函数

Vue 实例代理了 data 对象上的所有属性

    // 创建 Vue 实例
    const vm = new Vue({
        data: {
            count: 1
        }
    });

    // vm.$data 可以访问 data 实例上的属性
    console.log(vm);
    console.log(vm.count === vm.$data.count); // true

    // 组件
    const Component = Vue.extend({
        data () {
            return {
                num: 20
            };
        }
    }); 

data 中数据(创建时存在的属性)是响应式的,数据改变时,视图会重绘

    const vm = new Vue({
        data: {
            count: 1
        }
    });

    // 以下两种改变的 data 都是响应式的
    vm.$data.count = 2;
    vm.count = 3;

    // 如果是创建时不存在 data 中的属性,则不会有响应式
    vm.num = 4; 

对比 : 类似于 react 组件中定义的 this.state 保存组件的状态,组件状态改变后触发组件更新

2. computed

计算属性,Vue 的模板中允许使用 javascript 的表达式进行简单计算,但是对于需要复杂的计算的属性,需要使用 computed 将逻辑提取出来,便于管理维护

计算属性的绑定与 data 中的普通属性一致,他返回一个值,如果这个值的计算依赖于 其他具有 响应式 的属性(props|data),那么 Vue 会在它所依赖的属性改变时,更新这个计算属性

    export default {
        data () {
            return {
                text: 'home-basic-container'
            };
        },
        computed: {
            computedText() {
                return this.text.split('-').reverse().pop();
            }
        },
    }

以上声明的 computed 计算属性(数据类型为函数)实际将会作为对象 getter 函数(默认),我们也可以显式的设定他的 setter 函数

    data () {
        return {
            text: 'home-basic-container'
        };
    },
    computed: {
        computedText: {
            get () {
                return this.text.split('-').reverse().pop();
            },
            set (newVal) {
                this.text = newVal.toUpperCase();
            }
        }
    },
    methods: {
        handleClick() {
            // 如果没有设置 setter 会报错 [Vue warn]: Computed property "computedText" was assigned to but it has no setter.
            this.computedText = 'onClick';

            // 更改 computedText 后 this.text 也相应的改变
            console.log(this.text, this.computedText); // ONCLICK ONCLICK
        }
    }

对比:react 中使用 jsx 语法,复杂的计算可以提取出函数来处理,更加灵活,而在 vue 中,使用了 computed 计算属性,将赋值和计算分离

3. props

props 可以是数组或者对象,用于接收来自父组件的数据,如果是对象类型,可以用来配置类型检验,设置默认值等高级功能 。

真实传入 props 是在父组件中调用子组件时,但是在子组件中需要显式的用 props 选项声明它预期的数据,更多验证规则

非 Prop 特性,指的是 直接传入组件,组件中不声明相应的 prop,这种方式定义的props,在子组件中不方便使用,但是会直接添加到 子组件的根元素上

    <template>
       <div class="home-container" @click="handleClick" >
          <HomeBasic propText="this is props" test-props="111"></HomeBasic>
       </div>
    </template>
    export default {
       name: 'HomeBasic',
       data () {
          return {};
       },
       props: {
            // 没有 声明 test-props 属性
            propText: {
                type: String,
                default: '',
                required: true
            }
       },
       methods: {
          handleClick() {
            // 通过 this.$attrs 可以获取 父组件进来的绑定
             console.log(this.$attrs); 
             // {propText: "this is props", test-props: "111"}
          }
       }
    };

对比:与 react 中 props 类似,都是在父组件中写作子组件的属性,但是 vue 中需要显式的列出,需要的 props

4. methods

methods 与其他属性一样将被混入到 Vue 实例中,可以通过 vm 实例访问这些方法,或者在指令表达式中使用,方法中的 this 自动绑定为 Vue 实例(非 => 函数)

   <div class="home-basic-container" @click="handleClick">
      this is {{text}}
   </div>
    methods: {
      handleClick(e) {
         // 通过 this 调用
         console.log(e);
         this.change();
      },
      change() {
         this.text = 'onClick';

         console.log(this.text);
      }
   }

对比:相比于 react 将所有函数写在配置在最外层,vue 将组件的生命周期函数与普通函数分开,使得逻辑更清晰

5. watch

观察 Vue 实例变化的一个表达式或者计算属性,值为一个接受旧值和新值的函数,或者方法名,Vue 实例会在 实例化时期调用

可以用于,监听某个状态变化,变化后做出相应的响应或者操作

    export default {
        name: 'HomeBasic',
        data () {
            return {
             text: 'home-basic-container'
            };
        },
        methods: {
            handleClick() {
                this.text = 'onClick';

                console.log(this.text);
            }
            watchTextChange(newVal, oldVal) {
                console.log(newVal, oldVal);
            }
        },
        watch: { // 一下是三种 书写格式
          text(newVal, oldVal) {
              console.log(newVal, oldVal);
          },
          text: 'watchTextChange',
          text: { // 可以用对象来进行配置
             handler(newVal, oldVal) {
                console.log(newVal, oldVal);
             },
             deep: true 
          }
        }
    };

对比:react 中没有专门对应的Api 但是在组件的 componentWillReceiveProps 等生命周期中还是可以进行类似操作的。

6. el

只有在 new 创建的实例中才会使用,提供一个在页面上已存在的 DOM 元素,作为Vue的挂载目标,可以是 css 选择器,也可以是 html 实例

    const vm = new Vue({
        el: '#app'
    });

    vm.$el; // <div id="app"></div>

对比:react 中注册应用,也会用到这样一个挂载目标

7. template

一个字符串模板作为Vue实例的标识所用,模板将会替换挂载的元素,挂载元素的内容都将被忽略,除非模板的内容有分发插槽

如果 Vue 选项中包含渲染函数,模板将会被忽略

使用 .vue 单文件组件,<temptate></template> 标签中的内容会被渲染为 vue实例的 tempalte 属性

对比:这个属性对应 react 组件中的 render 方法。

8. render

template 的 替代方案,在这里允许使用 jsx 语法,创建组件, render 函数由两个参数 createElement, context

对比:对应 react 中的 render 函数,但是又有些不同, 具体查看这里

9. components

包含 Vue 实例可用组件的哈希表,组件可以扩展 HTML 元素,封装可重用的代码

注册组件需要在初始化实例之前注册

   <div class="home-basic-container" @click="handleClick">
      <golbal-component></golbal-component>
      <local-component></local-component>
   </div>
  // 全局注册
  Vue.component('golbal-component', {
     template: '<div>this is golbal-component</div>'
  });

  // 局部注册
  const localComponent = {
    template: '<div>this is localComponent</div>'
  };


  // 创建实例
  new Vue({
     el: '#app',
     components: {
        localComponent, // 局部注册,写在模板中可以是 小写 + ‘-’ 的格式 <local-component />
        // golbal-component // 全局注册不用引入
     } 
  });
10. extends

允许声明扩展另一个组件

  import HomeBasic from './HomeBasic';

  export default {
     extends: HomeBasic,
     methods: {  
        change() { // 覆盖掉 HomeBasic 组件中的 change 函数
           this.text = 'on extend click';

           console.log(this.text);
        },
     }
  };

尝试在 .vue 单文件组件中继承另外一个单文件组件,只能继承到另一个组件的<script><template><style> 还需要手动添加引用,如果这个组件定义在一个 .js 文件中,那么他所继承的就是一个完整的组件。

对比:react 中组件间可以在创建时 class NewComponent extends OldComponent {} 这样来继承

11. mixins

mixins(混合) 是一种分发 Vue 组件中可复用功能的非常灵活的方式,混合对象可以包含任意组件选项

  • 混合对象中如果有生命周期的钩子函数则会在 组件自身钩子之前调用
  • 混合对象中值为对象的选项 如 methods components,将会被合并为同一个对象,键名冲突时以组件中定义的为准
  • 如果有多个混合对象,且有键名冲突,则 优先级为 组件中键值对 > mixins属性中靠后的Mixin中的键值对 > mixins属性中靠前的Mixin中的键值对

  const mixin1 = {
     created() {
        console.log('mixin created');
     },
     methods: {
        change() {
           console.log('mixin change');
        },
        log() {
           console.log('mixin1 log');
        }
     }
  };

  const mixin2 = {
     methods: {
        log() {
           console.log('mixin2 log');
        }
     }
  };

  export default {
     name: 'HomeBasic',
     mixins: [mixin1, mixin2],
     created() {
        console.log('self created');
     },
     methods: {
        handleClick() {
           this.change();
           this.log();
        },
        change() {
           console.log('self change');
        }
     }
  };

  // mixin created
  // self created

  // self change
  // mixin2 log

对比:react 中原含有 mixin 后放弃,改为使用高阶组件实现同样功能

12. name

只有组件中有用,主要用于 组件自身递归调用以及方便调试

相关文章

Logo

前往低代码交流专区

更多推荐