form最后一节。


组件基础

  • 组件的复用:  data必须是函数
  • 组织
  • 通过Prop向子组件传递data
  • 单个根元素
  • 通过event向父组件发送消息: 使用事件抛出一个value, 在组件上用v-model
  • 动态组件
  • 解析DOM模版时的⚠️.

深入组件

  • 组件注册
  • Prop
  • 自定义事件: this.$emit('my-event')用kebab-case做事件名称
  • 插槽
  • 异步组件
  • 处理边界情况


例子:

组件是可复用的 Vue 实例,且带有一个名字,如Vue.component("名字", {data..., template...})。

因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 datacomputedwatchmethods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。

组件可以复用


无限次反复用比如上例。多次使用<button-counter>, 每用一个,就创建了一个实例。

data是函数

和新建Vue中的data:{...}不一样,

data必须是函数 data: function(){...},  这是为了每个实例可以维护一份被返回对象的独立的拷贝。

即data不是共用的数据集合,它是函数,是方法,通过它每个实例都会得到各自的结果。

组件的组织


为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册和局部注册

  • Vue.component 全局注册:
  • 全局注册的组件可以用在其被注册之后的任何 (通过 new Vue) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。

(深入看: 组件注册

通过 Prop 向子组件传递数据


Prop 是你可以在组件上注册的一些自定义特性。

当一个值传递给一个 prop 特性的时候,它就变成了那个组件实例的一个属性。

可以使用 v-bind 来动态传递 prop。这在你一开始不清楚要渲染的具体内容,比如从一个 API 获取博文列表的时候,是非常有用的。

单个根元素


每个组件只能有一个根元素,一般使用<div>包裹其他元素。

否则会报错 every component must have a single root element

⚠️:

JavaScript 的模板字符串来让多行的模板更易读。

它们在 IE 下并没有被支持,所以如果你需要在不编译的情况下支持 IE,请使用折行转义字符取而代之。

什么是模版字符串:

  • 模板字符串使用反引号 (` `) 来代替普通字符串中的用双引号和单引号。
  • 模板字符串可以包含特定语法(${expression})的占位符。

折行转义字符

在多行string每行结尾加上反斜杠  \

var htmlSTring = "<div>\

 This is a string.\

</div>";

通过事件向父级组件发送消息


案例: https://codepen.io/chentianwei411/pen/EeXxrM/?editors=1010

分析:

在我们开发 <blog-post> 组件时,它的一些功能可能要求和父级组件进行沟通。

例如我们可能会引入一个可访问性的功能来放大博文的字号,同时让页面的其它部分保持默认的字号。

注意:⚠️:

1.自定义组件可以使用v-for,但必须配合使用v-bind:key

2. 任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要用 props :

<my-component
v-for="(item, index) in items"
v-bind:item="item"
v-bind:index="index"
v-bind:key="item.id"
></my-component>
  • 明确组件数据的来源能够使组件在其他场合重复使用。

3. vm.$emit( eventName, […args] )  (点击看api)关于事件的实例方法。

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

  • 监听器指v-on,用于监听当前实例上的自定义事件,事件可以由vm.$emit触发,

参数的上传:

第一种:

在监听v-on:enlarge-text用$event获得上传的参数:v-on:enlarge-text="postFontSize += $event"

第二种:

如果这个事件处理函数是一个方法,那么这个值将会作为第一个参数传入这个方法:

1. v-on:enlarge-text='onEnLargeText'

2.在nev Vue中添加这个方法:

methods: {
 onEnlargeText: function(enlargeAmount) {
  this.postFontSize += enlargeAmount
 }
}

在组件上用v-model

点击:查看(详细分析了数据的流入和流出。及相关。)

还需要⚠️:

自己写的案例分析:https://codepen.io/chentianwei411/pen/bxozoj?editors=1010

在DOM上增加了一个组件实例<custom-input>,

  • 这个组件把外部数据传给 prop特性value,
  • 有一个监听v-on:input事件。

关于$event.target.value

$event是触发的事件,这里是在输入框输入的动作。

$event.target是这个动作作用在哪个元素上。target特性返回被事件激活的元素。这里是输入框input元素。

value指的是input中的value特性,即输入的内容。

el的作用

定位html中的元素,这个元素将作为Vue实例的挂载目标。在实例挂载后,元素可以用vm.$el访问。

template: Vue实例的模版

模版会替换被挂载的html元素,被挂载的元素的内容会被忽略,除非使用inline-template。

<custom-input v-bind:value="searchText"

这是把初始化中的data属性中的数据对象和自定义的prop特性value绑定在一切。

<custom-input v-on:input='searchText = $event'

用于监听input事件,并对参数进行回调处理。

template中的 <input v-bind:value='value'>

把Props: ['value']特性的值赋予了<input>的value属性。

template中的<input v-on:input=''"$emit('input', $event.target.value)">

  1. 当监听到input这个原生HTML事件时, 执行$emit这个实例方法。
  2. $emit会触发当前Vue实例上的自定义事件input(自定义,自定义,自定义),并传递参数。
  3. Vue实例上的监听器v-on会监听到这个触发事件input,并执行预期的行为。这里是执行一条inline statement。

动态组件

根据‘组件名称’来动态的调用组件。类似动态调用方法。把动态和异步组件读完。

<component v-bind:is='组件名称'></component>

用法:

渲染‘元组件’为动态组件。 根据v-bind:is的值,来决定渲染哪个组件。

这里是根据vm的计算属性中currentTabComponent函数来得到组件的名称

内置的组件:

component

Props:

  • is - string | ComponentDefinition | ComponentConstructor
  • inline-template -boolean

在动态组件上使用keep-alive缓存组件

keep-alive

目的:提高效能:保留组件状态,或避免重新渲染。

Props:

  • include -字符串或正则表达式。 匹配的组件会被cache
  • exclude -字符串或正则表达式。任何匹配的组件都不会被cache

用法:

  • <keep-alive>包裹动态组件</keep-alive>, cache不活动的组件,不会销魂它们。
  • <keep-alive>是一个抽象组件,不会渲染DOM元素,不会出现在父组件链中。

钩子函数:(这两个钩子,放到声明组件的代码中)

  • activated: 在keep-alive组件激活时用
  • deactivated: 在keep-alive组件停用时调用。

Vue.component('tab-home', {
 template: '<div>Home component</div>',
 activated() {
  console.log('activatsse')
 },
 deactivated() {
  console.log('deactivated')
 }
})


异步组件

以工厂函数的方式定义组件。

Vue.component('async', function(resolve, reject) {  ...  })

这个工厂函数会异步解析你的组件定义。

在这个组件被渲染的时候,会触发该工厂函数,并把结构缓存起来供未来重新渲染。

工厂函数?

当一个函数返回一个对象时,并且函数没有使用new关键字,这个函数称为factory function。

不是类,也不是构造函数。

个人理解:工厂函数好像就是类,传递不同的参数,返回不同的对象,但对象们的结构都一样,只是值不一样。

const noop = () => { foo: 'bar' };
console.log(noop()); //返回 undefined, 使用大括号,JavaScript默认你想要创建一个函数体。
 
const createFoo = () => ({ foo: 'bar' });
console.log(createFoo()); //返回 { foo: "bar" },大括号外面加上小括号,大括号里面的内容被解释为表达式

将异步组件和 webpack 的 code-splitting 功能一起配合使用,未学习这个功能!!

 

Promise是什么?(点击看api)

new Promise( function(resolve, reject) {...} );

一个代表了异步操作最终完成或者失败的对象。大多数人都在使用由其他函数创建并返回的promise.

promise本质上是一个绑定了回调的对象.

  • 通过.then形式添加回调函数。
  • 通过多次调用.then,可以添加多个回调函数。
  • 链式调用,凉鞋执行多个异步操作。  

诞生的原因猜测: 传统的多重回调的写法是各地狱,因此改用promise的方式。

回调地狱:崩溃的写发和读发:

doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ' + finalResult);
}, failureCallback);
}, failureCallback);
}, failureCallback);
现代的方法:
doSomething().then(function(result) {
return doSomethingElse(result);
})
.then(function(newResult) {
return doThirdThing(newResult);
})
.then(function(finalResult) {
console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);

或者使用箭头函数:
doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => {
console.log(`Got the final result: ${finalResult}`);
})
.catch(failureCallback);



解析 DOM 模板时的注意事项

部分HTML标签限制子元素的标签类型,

如<ul>内部只能是<li>,如果在里面用自定义组件则会渲染报错。

可以使用is特性,进行变通:

<table>
<tr is="blog-post-row"></tr>
</table>

但是⚠️,如果从以下来源使用模板的话,这条限制是不存在的:

案例: 列表渲染一章,最下面


Class用在组件上

  • 可以直接在组件上写:

    <my-component class="baz boo"></my-component>
  • 也可以用在v-bind:class='{active: isActive}'上面, 当isActive是true时,类加上active.
<p class="foo bar active">Hi</p>

深入Prop

camelCase vs kebab-case

当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:

<!-- 在 HTML 中是 kebab-case 的 -->
<blog-post post-title="hello!"></blog-post>

当定义组件的时候,即在JavaScript中用:props: ['postTitle']

Prop类型:

  • 使用字符串数组的形式:

    props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
  • 使用对象形式
  • 使用对象形式:可以进行Prop的验证。
    • type,  可以是任意类型null, 多个类型的任意一种(用数组)
    • required: true/false  是否必须填
    • default,默认可以是值,也可以是function(){ return ...}
    • 自定义验证函数validator。
  • 用到这个组件的时候,传入的数据必须符合prop指定的类型,并通过验证,否则browser的控制台会提示❌)
props: {
title: null,         #type可以任意类型,用null
likes: [Number, String, Date] #可以设置多个类型。
isPublished: Boolean,
commentIds: Array,
author: [Object, Function, Symbol]
}

传递静态或者动态Prop类型:

需要用 v-bind, 即使数据是静态的,仍然需要 v-bind来告诉Vue:

<blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post>

或者用一个变量进行动态赋值:

<blog-post v-bind:comment-ids="post.commentIds"></blog-post>

⚠️(即使加了双括号v-bind="xxxxx"这还是Javascript表达式)

可以传递任何类型的值给一个prop。每个类型略有使用区别:

  • 传入一个数字:
  • 传入一个boolean:
  • 传入一个数组:
  • 传入一个对象:
  • 传入一个对象的所有属性。绑定对象名即可 v-bind:prop-name

父子组件中的prop的数据流动是单向的:

但⚠️: JS中对象和数组是通过引用传入的。所以对这两种类型的prop, 在子组件中改变这个对象或数组,改变的是对象和数组本身,因此会影响到父组件的状态。

非Prop的特性

一个非prop特性是:传向一个组件的特性,但该组件没有对应prop定义的特性。

这个非prop特性会添加到这个组件的根元素上。

因为组件的作者不能遇见组件会被什么场景使用,为了让组件更加的灵活,所以组件可以接受任意的特性。

禁用特性继承

Vue.component('my-component', {
inheritAttrs: false,
// ...
})

自定义事件

推荐你始终使用 kebab-case 的事件名。

自定义组件v-model: 见上面用v-model案例,或者api。其实就是语法糖。

将原生事件绑定到组件

在v-on上使用修饰符.native,它用于监听根元素上的原生事件。

base-input v-on:focus.native="onFocus"></base-input>

案例:

JS对象知识点)知识点:

A Javascript object is a collection of named values

Object是mutable: 对象的地址是引用的,不是by value。

JS variable是by value的。

Object.assign(target, ..sources) 返回一个新的Object,他的值包括target和sources,但不重复同时value会被覆盖。

vm.$listeners,

一个对象,包含父作用域(不含.native)的事件监听器。

可以通过v-on='$listeners'把它传入内部组件,即父组件上的事件监听,也可以用在内部组件中了。

vm.$attrs(没有案例,不是很懂。)

类型: { |key: string|: string}

详细: 包含了父作用域中不作为prop被识别获取的特性绑定。可以用v-bind='$attrs'传入内部组件。

inheritAttrs选项和$attrs是一对儿。同时出现在2.4版本

选项/其他 #inheritAttrs

类型 boolean

详细:当写包裹一个目标元素(或另一个组件)的组件时,目标元素(或子组件)不能得到父作用域的非prop特性绑定。这些特性会‘回退’并且作为普通的HTML特性应用在目标元素上(或子组件的根元素上)。

去掉这个默认行为,可以使用inheritAttrs: false。不继承属性。

想要继承特性绑定,可以使用v-bind='$attrs',把这些特性绑定到目标元素(非根元素)上。

inheritAttrs选项和$attrs是一对儿。同时出现在2.4版本


.sync修饰符 没有看。


<solt>插槽

通过slot可以分发内容。

Vue自定义的标签。见:插槽

理解: 组件实例内的html会被保留。

<solt> 有一个特别的name特性,用于和其他solt区别

  • 可以在父组件的<template>元素上使用slot的name特性
  • 可以直接用在一个普通的元素上

插槽的默认内容

可以为solt提供默认内容。如在template中有一个插槽

  • 如果组件实例内没有html内容就会使用插槽默认内容。
  • 如果父组件为这个插槽提供了内容,默认的内容就会被替换掉。

编译作用域 (不是很理解,没有案例)

<navigation-link url="/profile">
Logged in as {{ user.name }}
</navigation-link>

可以在组件实例中的插槽位置加上{{xxx}},来插入数据。

但不能访问url, 这属于<navigation-link> 的作用域。

  • 父组件模板的所有东西都会在父级作用域内编译;
  • 子组件模板的所有东西都会在子级作用域内编译。

作用域slot


处理边界情况(特殊情况)

访问元素/组件

有些特定情况,需要触及另一个组件实例内部,或手动操作DOM元素。

访问子组件实例/子元素

除了prop,event, 有时需要在JS中直接访问一个子组件。

方法:

通过使用ref特性,为子组件/元素赋予一个id引用。

例如,这个子组件:

<base-input ref="username"></base-input>

然后,用this.$refs.username来访问组件实例。

注意⚠️: ref的使用是非响应式的,并且只会在组件渲染完成后生效。所以尽量避免使用它。

可以用于从父组件聚焦一个输入框:

<input ref="input">

然后添加一个方法:
methods: {
// 用来从父级组件聚焦输入框
focus: function () {
this.$refs.input.focus()
}
}

Vue组件(知识)的更多相关文章

  1. vue组件知识总结

    vue组件化开发 将一个页面分割成若干个组件,一个页面js+css+html,将自己类容分割出来,方便开发,更好了维护我们的代码,每个组件封装自己的js+html+css,样式命名冲突 组件分类 页面 ...

  2. JS组件系列——又一款MVVM组件:Vue(二:构建自己的Vue组件)

    前言:转眼距离上篇 JS组件系列——又一款MVVM组件:Vue(一:30分钟搞定前端增删改查) 已有好几个月了,今天打算将它捡起来,发现好久不用,Vue相关技术点都生疏不少.经过这几个月的时间,Vue ...

  3. Vue组件库的那些事儿,你都知道吗?

    前段时间一直在研究Vue组件库,终于在组内派上了用场.来给大家贡献一篇关于Vue组件库的相关知识.经验不多,如果有不合理的地方还请多多指出哦--- 回想一下,在你们公司或者你们小组是否有一个以上的项目 ...

  4. vue初级知识总结

    从我第一篇博客的搭建环境开始,就开始学习vue了,一直想将这些基本知识点整理出来,但是一直不知如何下手,今天刚好实战了两个小demo,所以就想趁这机会将以前的一起整理出来,这是vue最基础的知识,我有 ...

  5. Vue基础知识简介

    基础知识: vue的生命周期: beforeCreate/created.beforeMount/mounted.beforeUpdate/updated.beforeDestory/destorye ...

  6. 阿里oss上传图片react组件alioss-react,vue组件alioss-vue (不用我先收藏着,后端看下前端处理方法)

    1.介绍 最近开发了一个项目,其中需要一个上传图片到阿里云的 oss 上面,就是上传图片到阿里云的 oss 上面. 因为之前开发过 vue 的阿里云 oss 上传,所以直接复制粘 vue 的组件. 因 ...

  7. angular里使用vue/vue组件怎么在angular里用

    欢迎加入前端交流群交流知识&&获取视频资料:749539640 如何在angularjs(1)中使用vue参考: https://medium.com/@graphicbeacon/h ...

  8. vue路由知识整理

    vue路由知识整理 对于单页应用,官方提供了vue-router进行路由跳转的处理.我们已经可以通过组合组件来组成应用程序,当你要把 vue-router 添加进来,我们需要做的是,将组件(compo ...

  9. 认识Vue组件

    前言 Vue.js是一套构建用户界面的渐进式框架(官方说明).通俗点来说,Vue.js是一个轻量级的,易上手易使用的,便捷,灵活性强的前端MVVM框架.简洁的API,良好健全的中文文档,使开发者能够较 ...

随机推荐

  1. NOSQL学习之二:MongoDB

    MongoDB是一个高性能,开源,无模式的文档型数据库,它在许多场景下可用于替代传统的关系型数据库或键/值存储方式,是当前NoSQL数据库中比较热门的一种. MongoDB使用C++开发.不支持SQL ...

  2. 【Redis学习之二】Redis:redis.conf 配置详解

    参数说明redis.conf 配置项说明如下:1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程  daemonize no2. 当Redis以守护进程方式运行 ...

  3. tomcat启动失败问题排除及解决办法 Server Tomcat v7.0 Server at localhost failed to start.

    tomcat启动失败问题排除及解决办法 Server Tomcat v7.0 Server at localhost failed to start. 导致上面问题的原因可能有很多种,每种的解决办法都 ...

  4. Shell脚本实现检测某ip网络畅通情况,实战用例

    Shell脚本实现检测某ip网络畅通情况,实战用例 环境准备,linux shell 发送email 邮件:1.安装sendmailyum -y install sendmail安装好sendmail ...

  5. P3498 [POI2010]KOR-Beads

    P3498 [POI2010]KOR-Beads 题解 hash+hash表+调和级数 关于调和级数(from baidu百科): 调和级数发散的速度非常缓慢.举例来说,调和序列前10项的和还不足10 ...

  6. 根据wsdl,基于wsimport生成代码的客户端

    根据wsdl,基于wsimport生成代码的客户端 wsimport是jdk自带的命令,可以根据wsdl文档生成客户端中间代码,基于生成的代码编写客户端,可以省很多麻烦. 局限性:wsimport   ...

  7. 20145208 蔡野《网络对抗》Exp3 Advanced 恶意代码伪装技术实践

    20145208 蔡野<网络对抗>Exp3 Advanced 恶意代码伪装技术实践 木马化正常软件 思路: 在正常软件包中将原本的程序主文件(平时打开程序用的exe文件)改成dll后缀(或 ...

  8. np.tile 和np.newaxis

    output   array([[ 0.24747071, -0.43886742],   [-0.03916734, -0.70580089],   [ 0.00462337, -0.5143158 ...

  9. tf.truncated_normal的用法

    tf.truncated_normal(shape, mean, stddev) :shape表示生成张量的维度,mean是均值,stddev是标准差.这个函数产生正太分布,均值和标准差自己设定.这是 ...

  10. 如何解析读取excel数据

    简介 前段时间完成了一个输出excel的任务,感觉挺开心的,用的就是Apache POI的jar包,Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Mic ...