欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

宁皓网 Vue.js:组件

学一下定义 Vue.js 框架里的组件。

仓库:https://github.com/ninghao/vue-demo
分支:vue-components
 

 
1)注册组件

你可以把想要重复使用的东西定义成组件。组件就是一些自定义的元素,你可以在上面附加一些 Vue 提供的行为。

现在这个在页面上显示的是一个按钮元素 ...上面的样式是一个CSS框架提供的 .. 这个元素用了一个 button 标签 .. 上面还用了几个 css 类 .. 里面包装了按钮上显示的文字 ..

下面我们可以去注册一个按钮组件,可以在本地范围注册,也可以是全局范围注册,先看一下在本地范围注册,本地指的就是某个特定的 Vue 实例 ...

先去定义一下组件的一些选项 ... 添加一个变量 .. 名字是 uiButton .. 它的值是一个对象 .. 里面添加一个 template 属性 .. 它的值是这个组件要使用的模板 ... 一个 button 元素 .. 加上 ui button 这两个 css 类 ... 再添加一个静态的文字 ...

然后在这个 Vue 实例里面 .. 可以添加一个 components 属性,它里面的东西就是在这个实例上可以使用的组件 .. 先是组件的名字,比如 ui-button,这种使用连字符的命名方式叫 kebab-case,肉串形式 ...

它的值是对应的这个组件的一些选项,我们可以使用上面定义的 uiButton 来表示 ...

回到 html 文档 .. 把这个 button 元素替换成刚才我们定义的 ui-button 这个组件 ... 添加一组 ui-button 标签 ...

页面上同样会显示一个有特定样式的按钮 ... 如果在浏览器上安装了 Vue 开发工具,


你可以在这里看到页面上使用的 Vue 组件 ... Root 表示应用的根 ... 下面的 UiButton 就是我们定义的组件 ..

这里我们可以再添加两个 ui-button ...

现在页面上会显示三个按钮 ...

在全局范围定义组件可以这样 ... 用一下 Vue 的 component .. 这个方法有两个参数,一个是组件的的元素名字 .. 还有一个参数就是一些选项 ...

比如这个元素的名字可以是 ui-button .. 它的一些相关的选项是一个对象 .. Vue 实例的大部分选项我们也都可以在组件的这个选项里使用 .. 这里我们可以先添加一个 template ... 设置一下这个组件的模板 ..

一组 button 标签上,上面有两个特定的 css 类 .. 再让它包装一点静态的文字 ..

页面同样会显示一些有特定样式的按钮 ... 在全局范围上定义的组件可以在任意的 Vue 实例里面使用 ...

2)组合组件

我们可以把不同的组件组合到一块儿去用 .. 它们之间一般都是父子关系,A 组件里面包装了 B 组件,A 就是 B 的爸爸 ... B 是 A 的儿子 ..

它们之间会有一种方法可以相互的沟通 ... 爸爸可以给儿子传递一些属性,也就是 Props ... 在儿子身上发生了一些事情以后,它也会通知它的爸爸 ...

这种关系可以解释成 Props down,Events up,属性向下流 .. 事件向上走 ... 爸爸通过 props 把数据往下传递给它的儿子 ... 儿子通过 events 发送信息给它的爸爸 ..

3)props:传递数据

每个组件的实例都有它自己的独立作用域。数据可以通过 props 向下传递给它的子组件 .. 一个 prop 就是一个自定义的属性,它可以在父组件上面传递信息 ... 子组件需要使用一个 props 选项,去声明一下它需要用的 props ...

比如我的这个 ui-button 组件,在它里面添加一个 props 选项 .. 声明一下它期望使用的属性 .. 一个数组 .. 里面添加一个 text ...

我们可以把这个 text 属性用作按钮上要显示的文字 ... {{ text }} ..

然后在使用这个组件的地方法,可以给它添加一个 text 属性,它的值可以传递到组件的里面 .. 再给其它的两个按钮也添加一个 text 属性 .. 然后设置一下对应的值 ...

你会看到,现在按钮上就会显示自定义的文字 .. 这些数据是通过 text 属性传递给它们的 .. 在 Vue 开发工具的上面,选中一个 UiButton 组件 .. 在右边这里会显示使用的 prop ,还有对应的值 ..

我们也可以在组件的上面动态的绑定一些数据 .. 可以使用 v-bind .. 简写形式就是一个冒号,后面加上绑定的属性的名字,这里就是 text,给它绑定一个 published ,我们可以根据这个数据的值动态的显示按钮上的文字,如果这个值是 true 的话,就显示一个 unpublish ,如果是 false ,就显示一个 publish ... 然后在应用里添加一个 published 数据 .. 先把它的值设置成 false ..

现在这个按钮上显示的文字是 publish,因为给它的 text 属性绑定的数据 published 的值,现在是 false ... 再去设置一下这个数据值 ... 让它等于 true ... 这样按钮上的文字就会变成 unpublish ...

再把它设置成 false ... 按钮上的文字又会变成 publish ...

4)验证属性

我们定义的 ui-button 这个组件里的 props 的值,现在是一个数组,我们可以把它换成一个对象 .. 这样你可以为每个属性去添加一些验证 ...

先在这个对象里添加一个 text 属性,它的值又是一个对象 ... 然后添加一个 type 属性,设置一下这个 text 属性的值的类型,String 表示字符串,Number 是数字,Boolean 是布尔值,Function 是函数,Object 是对象,Array 是数组 .. 这里把它设置成 String ..

然后再添加一个 default,可以设置一下这个属性的默认的值 ... 如果 text 的值是一个对象或者数组的话,这个 default 应该是一个函数,在函数的内部你可以返回对象或者数组的值 .. 这里我们先用一个字符串 .. 让它等于 button ..

找到一个使用了这个组件的地方,去掉它上面的 text,你会发现,这个按钮上显示的就是我们给 text 设置的默认的值 ..

如果你希望属性是必须的,可以添加一个 required,把它设置成 true .. 这样在使用这个组件的时候不指定这个属性的值,就会在控制台上出现提示 ...

Missing require prop .. 再给这个组件添加一个 text 属性 .. 设置一个值 ... 这样缺少必填属性的错误就不见了 ...

如果想自定义一个验证器,可以在这个属性的对象里添加一个 validator 方法 ... 添加一个 value 参数,return 一下 .. 看看 value 的 length 属性的值是不是大于 3 ... 也就是现在 text 属性的值的字符长度要大于 3 ..

现在控制台上会出现一个错误,custom validator check failed ... 自定义验证器检查出一个错误来 ... 因为现在中间这个按钮的 text 属性的长度小于 3 .. 修改一下这个按钮上的 text 属性的值 .. 这样刚才我们在控制台上看到的错误就不见了 ..

5)自定义事件

爸爸可以通过 props 把数据交给它的孩子 .. 孩子有什么事儿的时候可以通过事件告诉它们的爸爸 .. 每个 Vue 实例都实施了一个事件接口,也就是我们可以使用 $on 去监听事件,用 $emit 去触发自定义的事件 .. 先去做一个简单的小实验,理解一下自定义的事件 ..

在控制台上,用一下 vm 实例的 $on 方法去监听一个自定义的事件 .. 名字是 hi .. 第二个参数是一个函数,接收一个参数名字是 msg ,表示信息 ... 要做的事就是在控制台上输出这个 msg 的值 ..

vm.$on('hi',function(msg){ console.log(msg)});

然后再去用一下 vm 实例的 $emit 方法 ... 触发一个自定义事件,事件的名字是 hi ... 带个信息,值是 hello ...

vm.$emit('hi','hello')

执行一下 .. 你会发现在控制台上会输出一个 hello .. 因为我们监听了这个自定义的 hi 事件 ..

发生它以后要做的事情就是在控制台上输出传递给它的信息 ...

6)应用自定义事件

先定义一个简单的按钮组件 .. 按钮上的文字给它绑定一个动态的数据 .. 名字是 counter .. 在这个组件里我们可以去添加这个数据 .. 这个数据要在一个 data 方法里返回 .. 添加一个 data 方法 .. return 一个对象 .. 里面添加一个 counter 数据,先让它的值等于 0 ..

然后在这个组件的模板的 button 元素上,给它绑定一个点击事件 ... 发生它的时候可以使用 increment 这个方法来处理 .. 在这个组件里面再添加一个 methods 属性 ... 里面定义一个 increment 方法 ... 在方法里可以让这个组件里的 counter 数据的值增加 1 ..

再去用一下这个组件 ... 添加两个自定义的 ui-button 元素 ... 页面上会显示两个按钮 .. 按钮上的文字是 counter 的值 ..

点击其中的一个按钮,会让它的 counter 的值增加 1,这两个按钮元素是不同的作用域,所以不会影响到彼此的 counter 的值 ...

现在我想让点击这两个按钮以后增加应用里的某个数据的值 ... 在应用的数据里,添加一个 total ... 让它的值等于 0 .. 在页面上再绑定一下这个数据 ...

再找到这个按钮组件 ... 我们可以在这个 increment 方法里,用一下 $emit 方法,去触发一个自定义的事件 ... 名字可以是 increment ...

我们可以在使用这个按钮组件的地方,用一下 v-on 指令监听一下发生的 increment 这个自定义事件 ... 发生它的时候,可以用 incrementTotal 这个方法来处理 ...

在这个 Vue 实例里,再添加一个 methods .. 在它里面定义一个 incrementTotal 方法 ... 在方法里可以让 total 的值增加 1 ...

这样不管点击哪个按钮,都会发生一个 increment 事件,我们监听了这个事件,把它交给 incrementTotal 方法来处理,它会让 total 这个数据的值增加 1 ...

随便点击页面上的某个按钮 ... 你会发现这个 total 的值都会增加 1 ..

7)内容分发:slot

下面我们可以试一下用 slot 去分发内容 ... 先定义一个简单的组件 .. 名字是 segment .. 提供一些选项 .. 用一个 template 属性,定义一下组件用的模板 .. 一组 div 上面加上点 css 类 ... ui.stacked.segment ...

如果模板有多行内容可以在内容的结尾添加一个向前倒的斜线 .. 这组 div 的里面,添加一组 slot .. 在这个 slot 里面包装的内容是默认的内容 ..

在文档上用一下这个组件 ... 现在会显示 segment 这个组件 ... 默认里面有一个笑脸符号 .. 在使用这个组件的时候在它里面提供一些内容 ... 一组标题标签 ... 再添加一个段落文字 ...

因为在组件的模板里用了 slot ,所以父内容会替换掉组件模板里的那个 slot ..

8)带名字的 slot

再试一下有名字的 slot ... 定义一个组件 .. 名字是 card .. 提供一些选项 .. 添加一个 template 设置一下模板 .. 一组 div ,上面加上 ui card 这两个 css 类 .

它里面再包装一个 div ,上面加上 image 这个类 .. 它里面应该是一张图片 .. 这个内容可以从爸爸那里传递过来 ... 用一组 slot .. 上面加上一个 name 属性,设置一下这个 slot 的名字 .. 可以是 image .. 标签的中间可以加点默认的东西 ..

跟这个带 image 类同级别的位置上再添加一个 div ,上面加上 content 这个类 .. 它里面再包装一个 div ,上面有个 header 类 .. 在这个标签里面可以包装一个 slot ,添加一个 name 设置一下它的名字 .. 可以是 header .. 跟这个元素同一级别的地方,再添加一个包装 .. 上面加上一个 meta 类 ..

里面再用一个 slot 分发一个叫 meta 的内容 ...

回到这个 html 文档 .. 用一下刚才定义的这个 card 组件 .. 再这个组件的里面,我们可以为组件里的 slot 提供一些内容 ... 一个 img 标签 ... 添加一个 slot 属性,设置一下这个内容是给谁的 .. 名字是 image

再给这个图像标签添加一个 src,指定一个要显示的图像的地址 ..

再添加一个大标题 .. 用一个 slot ,说明一下这个标题的内容要分发给谁,这里就是 header ... 设置一下这个标题里的内容 ...

然后再用一组 div ... 它可以给 meta 这个 slot ... 里面再添加点文字 ..

现在页面上显示的就是一个 card 组件 ...

来自 https://ninghao.net/course/4298#toc
普通分类: