Vue初学之——构造选项

402 阅读4分钟

Vue官方文档——构造选项

Vue的构造选项options(也就是new Vue实例时的输入参数),options一共有五类属性,作为初学者首先重点学习其中的四类,分别是:

  • 数据:dataprops、propsData、computed、methods、watch
  • DOM:el、template、render、renderError
  • 生命周期钩子:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、activated、deacticated、beforeDestroy、destroyed、errorCaptured
  • 资源:directives、filters、components

数据

data(内部数据)

  • 类型:Object | Function
  • 限制:组件的定义只接受function 在定义一个组件的时候,data必须声明为一个返回初始数据对象的函数,因为组件有可能会被用来创建多个实例。

在JS中,对象是存放在内存中的堆区的,当组件创建了多个实例时,每一个实例都有属性data,而这些实例的data属性的值均指向data对象的内存地址,那么我们在修改A实例的data属性时,相当于直接在内存的对应位置修改了data对象的内容,内存中的data对象被A实例覆写了,因为B实例的data属性是对内存中data对象的引用,所以会造成引用传递,导致该组件创建的B实例的data数据被影响了。

把data声明为有返回值的函数时,每次创建一个新的实例后,data()函数被调用,返回的初始数据会生成一个全新的副本数据对象,每个实例之间的数据对象互相不影响,杜绝了同一个组件创建的不同实例互相影响的风险。

  • 用法:
// vue.js完整版为例
console.log(window.Vue)
const Vue = window.Vue
Vue.config.productionTip = false

new Vue({
  /* data是对象
  data:{
    n:0
  },  */
  data(){ // data是函数
    return{
      n:0
    }
  },
  template:`
    <div>
    {{ n }}
    <button @click="add">+1</button>
    </div>
  `,
  methods:{
    add(){
      this.n += 1
    }
  }
}).$mount('#app')

props(外部数据)

  • 类型:Array<string> | Object
  • 详细:props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值。
  • 用法:
//main.js(相当于父组件)
const Vue = window.Vue
Vue.config.productionTip = false
import Demo from './Demo.vue'   //引入子组件Demo

new Vue({
  components:{Demo},
  data:{
    n:0
  },
  template:`
  <div>
  {{n}}
  <Demo :fn="add" :message="n"/>
  <button @click="add">+1</button>
  </div>
  `,
  /*这里的fn和message前面的:表示冒号后面的是JS代码,
    如果不加:,写成 <Demo fn="add" message="n"/>,
    则add和n都以字符串的形式传给Demo组件*/
  methods:{
    add(){
      this.n+=1
    }
  }
}).$mount('#lee')

父组件实例点击button,触发add()函数,父组件实例的n加1,并且把add()函数和n变量传递给子组件Demo的实例

//子组件Demo
<template>
    <div>
        这里是Demo的内部
        {{message}}        
    </div>
</template>

<script>
export default{
    props:['message','fn'] 
    /*通过设置props接收父组件传进来的数据,
    父组件通过<Demo :message=   :n=/>的形式向子组件传数据*/
}
</script>

子组件的实例通过message和fn两个名字获取到了父组件实例传输过来的add()函数和n变量,父组件实例点击button时触发add()函数,因为子组件实例也有一个从父组件实例传过来的add(),所以子组件实例的add()也被触发,所以子组件实例的n变量值也会随着父组件实例的点击事件而递增。

1.gif

methods(方法)

  • 类型:{[key: string]: Function}
  • 详细:事件处理函数或者是普通函数
  • 用法:
// 事件处理函数
new Vue({
  data() {
    return{
      n: 0   
    }
  },
  template:`
    <div>
    {{ n }}
    <button @click="add">+1</button>
    </div>
  `,
  methods: {
    add() {
      // 方法中的this自动绑定为Vue实例
      this.n += 1
    }
  }
}).$mount('#app')

// 普通函数,可以代替filter
new Vue({
  data() {
    return{
      n: 0,
      array: [1,2,3,4,5,6,7,8]
    }
  },
  template:`
    <div>
    {{ n }}
    <button @click="add">+1</button>
    <hr>
    {{filter()}}
    </div>
  `,
  methods: {
    add() {
      // 方法中的this自动绑定为Vue实例
      this.n += 1
    },
    filter(){
    //不使用Vue options的filter属性,而是用普通函数代替
      return this.array.filter(i => i % 2 === 0)
    }  
  }
}).$mount('#app')

注意,不应该使用箭头函数来定义 method 函数 (例如 plus: () => this.a++)。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.a 将是 undefined。

DOM

el(挂载点)

  • 类型:string | Element
  • 限制:只在用new创建实例时生效
  • 详细:与$mount有替换关系。 提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。可以是 CSS 选择器,也可以是一个 HTMLElement 实例。

在实例挂载之后,元素可以用 vm.$el 访问。

如果在实例化时存在这个选项,实例将立即进入编译过程,否则,需要显式调用 vm.$mount() 手动开启编译。

生命周期钩子

Vue实例生命周期图示:

lifecycle.png

created(实例出现在内存中)

  • 类型:Function

  • 详细:

    在实例创建完成后被立即同步调用。在这一步中,实例已完成对选项的处理,意味着以下内容已被配置完毕:数据侦听、计算属性、方法、事件/侦听器的回调函数。然而,挂载阶段还没开始,且 $el property 目前尚不可用。

mounted(实例出现在页面中)

  • 类型:Function

  • 详细:

    实例被挂载后调用,这时 el 被新创建的 vm.$el 替换了。如果根实例挂载到了一个文档内的元素上,当 mounted 被调用时 vm.$el 也在文档内。

updated(实例更新了)

  • 类型:Function

  • 详细:

    在数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用。

    当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。

destroyed(实例从页面和内存中消亡)

  • 类型:Function

  • 详细:

    实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。

    该钩子在服务器端渲染期间不被调用。

资源

components(组件)

三种声明方式:

  • 引用外部组件,使用components声明,取名为Demo,在template中使用<Demo />引用。
new Vue({
	components:{
    	Demo: DemoComponent
    },
    template:`
    	<div>
            <Demo />
        </div>
    `,
})
  • 使用Vue.components中进行全局声明,值为该组件的options对象,在template中使用<Demo />引用。
Vue.component('Demo',{
    template:`
    <div>这是Demo组件内容</div>
    `
})

new Vue({
    template:`
    	<div>
            <Demo />
        </div>
    `,	
})
  • 结合前面两种方法,直接在components中声明,值为该组件的options对象,在template中使用<Demo />引用。
new Vue({
	components:{
    	Demo:{
            data(){
                return {n:0}
            },
            template:`
                <div>Demo组件的内容n的值为{{n}}</div>
            `
        }
    },
    template:`
    	<div>
           <Demo />
        </div>
    `,
})

★★★★★★★★★★★★★考虑到模块化,最好使用第一种方法★★★★★★★★★★★★