Vue核心知识

 

VUE实例

  • vue实例的创建和作用
  • vue实例的属性
  • vue实例的方法

1. vue实例的创建和作用

new Vue({
    render: (h) => h(App)   
    //vue在创建Vue实例时,通过调用render方法来渲染实例的DOM树,也就是这个组件渲染的是App的内容
    //vue在调用render方法时,会传入一个createElement函数作为参数,也就是这里的h的实参是createElement函数,然后createElement会以App为参数进行调用
}).$mount(root) //挂载html的root节点下面

2.vue实例的属性

  • $data:Vue 实例观察的数据对象。Vue 实例代理了对其 data 对象属性的访问。
  • $props:当前组件接收到的 props 对象。Vue 实例代理了对其 props 对象属性的访问。
  • $el: Vue实例使用的根 DOM 元素。
  • $options: 用于当前 Vue 实例的初始化选项。需要在选项中包含自定义属性时会有用处:
new Vue({
  customOption: 'foo',
  created: function () {
    console.log(this.$options.customOption) // => 'foo'
  }
})
  • $parent: 父实例,如果当前实例有的话。
  • $root: 当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。
  • $chardren: 当前实例的直接子组件。需要注意 $children 并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 $children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源。
  • $slots: 用来访问被插槽分发的内容。每个具名插槽 有其相应的属性 (例如:v-slot:foo 中的内容将会在 vm.$slots.foo 中被找到)。default 属性包括了所有没有被包含在具名插槽中的节点,或 v-slot:default 的内容。
  • $scopedSlots: 用来访问作用域插槽。对于包括 默认 slot 在内的每一个插槽,该对象都包含一个返回相应 VNode 的函数。vm.$scopedSlots 在使用渲染函数开发一个组件时特别有用。
  • $refs: 一个对象,持有注册过 ref 特性 的所有 DOM 元素和组件实例。(帮助我们快速定位这个模板中某一个节点或者组件)
  • $isServer: 当前 Vue 实例是否运行于服务器。
  • $attrs: 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
  • $listeners: 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。

3. vue实例的方法

方法--数据

  • $watch: 观察 Vue 实例变化的一个表达式或计算属性函数。回调函数得到的参数为新值和旧值。表达式只接受监督的键路径。对于更复杂的表达式,用一个函数取代。

       

  • $set:这是全局 Vue.set 的别名

        

  •  $delete: 这是全局 Vue.delete 的别名

       

方法-事件

  • $on: 监听当前实例上的自定义事件。事件可以由vm.$emit触发。回调函数会接收所有传入事件触发函数的额外参数。

      

     

vm.$on('test', function (msg) {
  console.log(msg)
})
vm.$emit('test', 'hi')
// => "hi"
  • $once: 监听一个自定义事件,但是只触发一次,在第一次触发之后移除监听器。

    

  • $off: 移除自定义事件监听器。
  1. 如果没有提供参数,则移除所有的事件监听器;

  2. 如果只提供了事件,则移除该事件所有的监听器;

  3. 如果同时提供了事件与回调,则只移除这个回调的监听器。

     

  • $emit: 触发当前实例上的事件。附加参数都会传给监听器回调。

     

方法-生命周期

  • $mount: 如果 Vue 实例在实例化时没有收到 el 选项,则它处于“未挂载”状态,没有关联的 DOM 元素。可用 vm.$mount() 手动地挂载一个未挂载的实例。如果没有提供 elementOrSelector 参数,模板将被渲染为文档之外的的元素,并且你必须使用原生 DOM API 把它插入文档中。

    这个方法返回实例自身,因而可以链式调用其它实例方法。

         

    示例:

var MyComponent = Vue.extend({
  template: '<div>Hello!</div>'
})

// 创建并挂载到 #app (会替换 #app)
new MyComponent().$mount('#app')

// 同上
new MyComponent({ el: '#app' })

// 或者,在文档之外渲染并且随后挂载
var component = new MyComponent().$mount()
document.getElementById('app').appendChild(component.$el)
  • $forceUpdate: 迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。(不建议使用)
  • $nextTick: 将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。 

      示例:

new Vue({
  // ...
  methods: {
    // ...
    example: function () {
      // 修改数据
      this.message = 'changed'
      // DOM 还没有更新
      this.$nextTick(function () {
        // DOM 现在更新了
        // `this` 绑定到当前实例
        this.doSomethingElse()
      })
    }
  }
})
  • $destory: 完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。触发 beforeDestroy 和 destroyed 的钩子。

Vue组件的生命周期

生命周期可以看我的另外一篇文章:Vue的生命周期

需要思考:

  • 有哪些生命周期方法
  • 生命周期方法的调用顺序
  • 生命周期中VUE实例有哪些区别

没有暴露出来的,vue内部的渲染函数:

  • render:就是render function将template编译的过程
  • renderError:帮助我们调试项目,当runder function报错的时候就会执行(当前组件的render function报错才报错,不管父组件和子组件的render function报错)
new Vue({
  render (h) {
    throw new Error('oops')
  },
  renderError (h, err) {
    return h('pre', { style: { color: 'red' }}, err.stack)
  }
}).$mount('#app')
  • errorCaptured:帮助我们收集线上的错误,如果在根组件定义了这个,然后所以的子组件报错都可以捕获到(会向上冒泡,并且正式环境可以使用)

Vue的数据绑定

class的动态绑定和style的动态绑定:vue中修改css样式和添加CSS样式

data、props、propsData、computed和watch使用场景和方法

  • data

类型Object | Function

限制:组件的定义只接受 function

Vue 实例的数据对象。Vue 将会递归将 data 的属性转换为 getter/setter,从而让 data 的属性能够响应数据变化。对象必须是纯粹的对象 (含有零个或多个的 key/value 对):浏览器 API 创建的原生对象,原型上的属性会被忽略。大概来说,data 应该只能是数据 - 不推荐观察拥有状态行为的对象。

一旦观察过,不需要再次在数据对象上添加响应式属性。因此推荐在创建实例之前,就声明所有的根级响应式属性。

实例创建之后,可以通过 vm.$data 访问原始数据对象。Vue 实例也代理了 data 对象上所有的属性,因此访问 vm.a 等价于访问 vm.$data.a

以 _ 或 $ 开头的属性 不会 被 Vue 实例代理,因为它们可能和 Vue 内置的属性、API 方法冲突。你可以使用例如 vm.$data._property 的方式访问这些属性。

当一个组件被定义,data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。

如果需要,可以通过将 vm.$data 传入 JSON.parse(JSON.stringify(...)) 得到深拷贝的原始数据对象。

  • props

类型Array<string> | Object

详细

props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值。

你可以基于对象的语法使用以下选项:

  1. type: 可以是下列原生构造函数中的一种:StringNumberBooleanArrayObjectDateFunctionSymbol、任何自定义构造函数、或上述内容组成的数组。会检查一个 prop 是否是给定的类型,否则抛出警告。Prop 类型的更多信息在此
  2. defaultany
    为该 prop 指定一个默认值。如果该 prop 没有被传入,则换做用这个值。对象或数组的默认值必须从一个工厂函数返回。
  3. requiredBoolean
    定义该 prop 是否是必填项。在非生产环境中,如果这个值为 truthy 且该 prop 没有被传入的,则一个控制台警告将会被抛出。
  4. validatorFunction
    自定义验证函数会将该 prop 的值作为唯一的参数代入。在非生产环境下,如果该函数返回一个 falsy 的值 (也就是验证失败),一个控制台警告将会被抛出。你可以在这里查阅更多 prop 验证的相关信息。
  • propsData

类型{ [key: string]: any }

限制:只用于 new 创建的实例中。

详细

创建实例时传递 props。主要作用是方便测试。

示例

var Comp = Vue.extend({
  props: ['msg'],
  template: '<div>{{ msg }}</div>'
})

var vm = new Comp({
  propsData: {
    msg: 'hello'
  }
})

类型{ [key: string]: Function | { get: Function, set: Function } }

详细

计算属性将被混入到 Vue 实例中。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例。

注意如果你为一个计算属性使用了箭头函数,则 this 不会指向这个组件的实例,不过你仍然可以将其实例作为函数的第一个参数来访问。

computed: {
  aDouble: vm => vm.a * 2
}

计算属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。注意,如果某个依赖 (比如非响应式属性) 在该实例范畴之外,则计算属性是不会被更新的。

  • watch

类型{ [key: string]: string | Function | Object | Array }

详细

一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。

示例

var vm = new Vue({
  data: {
    a: 1,
    b: 2,
    c: 3,
    d: 4,
    e: {
      f: {
        g: 5
      }
    }
  },
  watch: {
    a: function (val, oldVal) {
      console.log('new: %s, old: %s', val, oldVal)
    },
    // 方法名
    b: 'someMethod',
    // 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
    c: {
      handler: function (val, oldVal) { /* ... */ },
      deep: true
    },
    // 该回调将会在侦听开始之后被立即调用
    d: {
      handler: 'someMethod',
      immediate: true
    },
    e: [
      'handle1',
      function handle2 (val, oldVal) { /* ... */ },
      {
        handler: function handle3 (val, oldVal) { /* ... */ },
        /* ... */
      }
    ],
    // watch vm.e.f's value: {g: 5}
    'e.f': function (val, oldVal) { /* ... */ }
  }
})
vm.a = 2 // => new: 2, old: 1

deep:true对深层监听对象的每一个属性有用

Vue的原生指令

vue的指令:vue的指令

  • v-text
<span v-text="msg"></span>
<!-- 和下面的一样 -->
<span>{{msg}}</span>
  • v-html

更新元素的 innerHTML 。注意:内容按普通 HTML 插入 - 不会作为 Vue 模板进行编译 。如果试图使用 v-html 组合模板,可以重新考虑是否通过使用组件来替代。

  • v-show

根据表达式之真假值,切换元素的 display CSS 属性。

当条件变化时该指令触发过渡效果。

  • v-if

根据表达式的值的真假条件渲染元素。在切换时元素及它的数据绑定 / 组件被销毁并重建。如果元素是 <template> ,将提出它的内容作为条件块。

当条件变化时该指令触发过渡效果。

  • v-else

不需要表达式

限制:前一兄弟元素必须有 v-if 或 v-else-if

用法

为 v-if 或者 v-else-if 添加“else 块”。

<div v-if="Math.random() > 0.5">
  Now you see me
</div>
<div v-else>
  Now you don't
</div>
  • v-else-if

限制:前一兄弟元素必须有 v-if 或 v-else-if

用法

表示 v-if 的 “else if 块”。可以链式调用。

<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>
  • v-for

预期Array | Object | number | string | Iterable (2.6 新增)

  • v-on

    

用法

绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。

用在普通元素上时,只能监听原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件

在监听原生 DOM 事件时,方法以事件为唯一的参数。如果使用内联语句,语句可以访问一个 $event 属性:v-on:click="handle('ok', $event)"

从 2.4.0 开始,v-on 同样支持不带参数绑定一个事件/监听器键值对的对象。注意当使用对象语法时,是不支持任何修饰器的。

示例

<!-- 方法处理器 -->
<button v-on:click="doThis"></button>

<!-- 动态事件 (2.6.0+) -->
<button v-on:[event]="doThis"></button>

<!-- 内联语句 -->
<button v-on:click="doThat('hello', $event)"></button>

<!-- 缩写 -->
<button @click="doThis"></button>

<!-- 动态事件缩写 (2.6.0+) -->
<button @[event]="doThis"></button>

<!-- 停止冒泡 -->
<button @click.stop="doThis"></button>

<!-- 阻止默认行为 -->
<button @click.prevent="doThis"></button>

<!-- 阻止默认行为,没有表达式 -->
<form @submit.prevent></form>

<!--  串联修饰符 -->
<button @click.stop.prevent="doThis"></button>

<!-- 键修饰符,键别名 -->
<input @keyup.enter="onEnter">

<!-- 键修饰符,键代码 -->
<input @keyup.13="onEnter">

<!-- 点击回调只会触发一次 -->
<button v-on:click.once="doThis"></button>

<!-- 对象语法 (2.4.0+) -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>

 

  • v-bind

    

示例: 

<!-- 绑定一个属性 -->
<img v-bind:src="imageSrc">

<!-- 动态特性名 (2.6.0+) -->
<button v-bind:[key]="value"></button>

<!-- 缩写 -->
<img :src="imageSrc">

<!-- 动态特性名缩写 (2.6.0+) -->
<button :[key]="value"></button>

<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName">

<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]">

<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>

<!-- 绑定一个有属性的对象 -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

<!-- 通过 prop 修饰符绑定 DOM 属性 -->
<div v-bind:text-content.prop="text"></div>

<!-- prop 绑定。“prop”必须在 my-component 中声明。-->
<my-component :prop="someThing"></my-component>

<!-- 通过 $props 将父组件的 props 一起传给子组件 -->
<child-component v-bind="$props"></child-component>

<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>

 

  • v-model

   

  • v-slot
  • v-pre

   

  • v-cloak
  • v-once

Vue的组件之组件的定义

定义全局组件:

使用index.js将全部需要全局定义的组件引入:

示例代码:

/*所有的自定义全局组件在此注册*/
import Vue from 'vue'

function registerEachComponent(item) {
  Vue.component(item.name,item.component);
}
function registerComponents(components) {
  components.map((item)=>{
    registerEachComponent(item)
  })
}

let components = [
  {
    name: 'common-layout',
    component: resolve => require(['./common-layout/common-layout.vue'], resolve)
  },
  {
    name: 'common-section',
    component: resolve => require(['./common-section/index.vue'], resolve)
  },
  {
    name: 'commonInquire',
    component: resolve => require(['./commonInquire/index.vue'], resolve)
  },
  {
    name: 'CommonTable',
    component: resolve => require(['./commonTable/index.vue'], resolve)
  },
];

registerComponents(components);

在main.js中引入:

/*引入全局注册的组件*/
import './components/global/index.js'

局部组件:

将定义的组件在需要使用的地方引入并通过components定义

组件定义配置:

  • props:不应该主动修改props的内容,
  •  emit:子组件通过emit来让父组件监听子组件的事件

Vue的组件之组件的继承

extends:将一个能在多个项目中使用的组件通过extends来实现继承,通过覆盖和新增新功能实现对原有组件的使用和拓展

示例:

// 假设component是通用的组件

const component2 = {
    extends: component,
    data () {
        text: 1
    },
    mounted () {
        console.log('comp2 mounted')
    }
}

注意:如果父组件在mounted定义了事件,然后你在子组件也定义了事件,这样会是父组件的事件先触发,子组件的事件后触发

parent:通过parent可以查看父组件的一些属性和方法(不建议通过parent修改父组件的属性值和方法)

 Vue的组件之自定义双向绑定

使用v-model来实现组件的自定义双向绑定

1.通过在子组件中的props得到值,然后将新的值emit出去,这就实现了双向绑定

2.在内部组件使用model

model: {
    prop: 'value1',
    event: 'change'
},
props: ['value1']

参考文章:Vue父子组件如何双向绑定传值

Vue的组件之高级属性

slot

定义组件compOne:

<div>
    <div class="header">
        <slot name="header"></slot>
    </div>
    <div>
        <slot name="body"></slot>
    </div>
</div>

使用:

<comp-one>
    <span slot="header">this is header</span>
    <span slot="body">this is body</span>
</comp-one>

文档:v-slot

slot-scope

使用组件中的属性

定义:

 <div>
    <slot value="456" aaa="111"></slot>
 </div>

使用:

<comp-one>
      <span slot-scope="props">{{props.value}}{{props.aaa}}</span>
</comp-one>

注意:ref用在组件和原生标签上的区别,在组件上是指向VueCompone,在原生标签上是一个html节点

provide和inject的使用

Vue.js 不建议在业务中使用这对 API,而是在插件 / 组件库

假设有两个组件: A.vue 和 B.vue,B 是 A 的子组件。

// A.vue
export default {
  provide: {
    name: 'Aresn'
  }
}

// B.vue
export default {
  inject: ['name'],
  mounted () {
    console.log(this.name);  // Aresn
  }
}

可以看到,在 A.vue 里,我们设置了一个 provide: name,值为 Aresn,它的作用就是将 name 这个变量提供给它的所有子组件。而在 B.vue 中,通过 inject 注入了从 A 组件中提供的 name 变量,那么在组件 B 中,就可以直接通过 this.name 访问这个变量了,它的值也是 Aresn。这就是 provide / inject API 最核心的用法。

只要一个组件使用了 provide 向下提供数据,那其下所有的子组件都可以通过 inject 来注入,不管中间隔了多少代,而且可以注入多个来自不同父级提供的数据。需要注意的是,一旦注入了某个数据,比如上面示例中的 app,那这个组件中就不能再声明 app 这个数据了,因为它已经被父级占有。

Vue的组件之render function

<comp-one ref="comp">
    <span ref="span">
        {{value}}
    </span>
</comp-one>

上面的代码通过render函数来实现:

render (createElement) {
    return createElement('comp-one',{
    ref: 'comp'
    },[
        createElement('span', {
            ref: 'span
        },this.value)
    ])
}

vue将template编译成一个render,形成一个虚拟的DOM

文档:JSX

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值