文章内容由蚊子的前端博客进行发布,或许你想看看他其他的文章呢: www.xiabingbao.com
官网上已经有的内容,我就不再赘述了,直接在官网上查看即可,这里蚊子想换个角度来讲解下vue的组件。
组件,顾名思义,就是把一个相对独立,而且会多次使用的功能抽象出来,成为一个组件!如果我们要把某个功能抽象为一个组件时,要做到这个组件对其他人来说是个黑盒子,他们不用关心里面是怎么实现的,只需要根据约定的接口调用即可!
我用一张图稍微总结了下Vue中组件的构成:
可以看到组件中包含的东西还是蛮多的,而且,还有很多的点没有列出来,这里面的每一个知识点能都展开讲很多。不过我们这里不讲原理,只讲使用。
我们以一个tips弹窗为例,来综合运用下组件的知识点。tips弹窗,几乎所有的框架或者类库,都会有弹窗这个组件,因为弹窗这个功能平时非常普遍,而且模块解耦度高!
我们先来看下demo: 【 www.xiabingbao.com/demo/vue-co… 】。
我们这里实现的弹窗,能用到的知识点有:props, event, slot, ref等。这里我们也能看到各个知识点是怎么运用的。
- /**
- * modal 模态接口参数
- * @param {string} modal.title 模态框标题
- * @param {string} modal.text 模态框内容
- * @param {boolean} modal.showbtn 是否显示按钮
- * @param {string} modal.btnText 按钮文字
- */
- Vue.component('tips', {
- props: ['tipsOptions'],
- template: '#tips',
- data() {
- return {
- show: false
- }
- },
- computed: {
- tips: {
- get() {
- let tips = this.tipsOptions || {};
- tips = {
- title: tips.title || '提示',
- text: tips.text || '',
- showbtn: tips.showbtn || true,
- btnText: tips.btnText || '确定'
- };
- // console.log(tips);
- return tips;
- }
- }
- }
- })
tips组件相对来说实现的比较简单,仅用作提示用户的简单弹层。
模板:
- <
- div
- class
- =
- "tips"
- v-show
- =
- "show"
- transition
- =
- "fade"
- >
- <
- div
- class
- =
- "tips-close"
- @
- click
- =
- "closeTips"
- >
- x</div>
- <div class="tips-header">
- <slot name="header">
- <p class="title">{{tips.title}}</p>
- </slot>
- </div>
- <div class="tips-body">
- <slot name="body">
- <p class="notice">{{tips.text}}</p>
- </slot>
- </div>
- <div class="tips-footer">
- <
- a
- href
- =
- "javascript:;"
- v-if
- =
- "tips.showbtn"
- @
- click
- =
- "yes"
- >
- {{tips.btnText}}</a>
- </div>
- </div>
模板中将结构分成了三部分,标题、内容和操作区域。这里既可以使用props传递字符串,也可以使用slot进行定制。
tips样式:
- .tips {
- position: fixed;
- left: 10px;
- bottom: 10px;
- z-index: 1001;
- -webkit-overflow-scrolling: touch;
- max-width: 690px;
- width: 260px;
- padding: 10px;
- background: #fff;
- box-shadow: 0 0 10px #888;
- border-radius: 4px;
- }
- .tips-close{
- position: absolute;
- top: 0;
- right: 0;
- width: 20px;
- height: 20px;
- line-height: 20px;
- text-align: center;
- }
- .tips-header{
- text-align: center;
- font-size: 25px;
- }
组件内的方法:
- methods:{
- closeTips(){
- this.show = false;
- },
- yes : function(){
- this.show = false;
- this.$emit('yes', {name:'wenzi', age:36}); // 触发yes事件
- },
- showTips(){
- var self = this;
- self.show = true;
- setTimeout(function(){
- // self.show = false;
- }, 2000)
- }
- }
首先我们开始渲染组件:
- <div class="app">
- <
- a
- href
- =
- "javascript:;"
- @
- click
- =
- "showtips"
- >
- 显示</a>
- <
- tips
- :tips-options
- =
- "tipsOptions"
- ref
- =
- "dialog"
- @
- yes
- =
- "yes"
- v-cloak
- >
- <h3 slot="header">提示标题</h3>
- <div slot="body">
- <p>hello world</p>
- <p>wenzi</p>
- </div>
- </tips>
- </div>
点击显示按钮后展示tips:
- var app = new Vue({
- el: '.app',
- data: {
- tipsOptions: {
- title: 'tip'
- }
- }
- methods: {
- // 监听从组件内传递出来的事件
- yes(args) {
- // console.log( args );
- alert(JSON.stringify(args));
- },
- // 显示tips
- showtips() {
- // console.log( this.$refs );
- this.$refs.dialog.showTips();
- }
- }
- })
在这个简单的tips组件里,我们实现了用props传递参数,用$emit向外传递参数,用slot插槽来定制内容。
需要注意的是:组件props是单向绑定,即父组件的属性发生变化时,子组件能接收到相应的数据变化,但是反过来就会出错。即不能在子组件中修改props传过来的数据,来达到修改父组件属性的目的。这是为了防止子组件无意修改了父组件的状态。
另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着你不应该在子组件内部改变 prop。如果你这么做了,Vue 会在控制台给出警告。如果真的需要在子组件里进行修改,可以用这两种方法应对:
定义一个局部变量,并用 prop 的值初始化它:
- props: ['initialCounter'],
- data: function () {
- return { counter: this.initialCounter }
- }
定义一个计算属性,处理 prop 的值并返回。
- props: ['size'],
- computed: {
- normalizedSize: function() {
- return this.size.trim().toLowerCase()
- }
- }
当然,这只是单页面中组件的实现,更复杂的组件后续我们也会实现。
文章内容由蚊子的前端博客进行发布,或许你想看看他其他的文章呢: www.xiabingbao.com
来源: https://juejin.im/entry/59f855cff265da43052dec07