Vue组件介绍

#基本示例

Vue组件的定义:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>这是Vue组件的学习</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <!-- 这是Vue组件的学 -->
        <h1>这是Vue组件的学习</h1>
        <!-- 这里是使用-->
        <!-- 怎么用呢? -->
        <!-- 需要Vue实例 -->
        <div id="app1">
            <!-- 这里解决 Vue定的组件的加载问题 -->

            为了能在模板中使用,这些组件必须先注册以便Vue能够识别.
            这里有两种组件的祖册类型:全局注册和局部祖册.
            至此,我们的组件都只是通过 Vue.component 全局注册的:
            Vue.component('my-component-name',{
            //options
            })

            全局注册的组件可以用在其被注册之后的任何(通过new Vue)新创建的Vue跟实例,也包括其组件树中的所有子组件的模板中.
            
            <!-- 所以,注册的组件 在下面可以直接使用,Vue的实例 负责解析并呈现 最终效果 -->
            <button-counter></button-counter>
        </div>

        <script>
            // 这是注释
            // 定义一个组件
            // 组件的定义样式是:
            // Vue.component('name',{vue object})

            Vue.component('button-counter', {
                data: function() {
                    // 返回一个<object>
                    //object>
                    return {
                        count: 0
                    }

                },
                template: `<button v-on:click ="count++">点击按钮{{count}}次</button>`
            });

            // 定义vue 实例
            var vm = new Vue({
                el: '#app1',
                // 可以没有初始化数据
                data: {

                },
            })
        </script>

    </body>
</html>

#data 必须是一个函数

component (组件)中的data ,必须是个函数,这是因为 组件是需要复用的,每次的复用,都相当于创建了一个新的实例.

这种情况跟 类(java)的实例情况类似. 否则将会出现不同组件公用 一个变量的情况,出现混淆及相互影响.

#通过 Prop 向子组件传递数据

prop的作用:类似组件的attribute,实现向组件中传值!

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>组件 prop 的学习</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <h1>组件prop的学习</h1>
        <h1>-------------------使用组件渲染的-----------------------</h1>
        <div id="app">
            <blog-post title="这是360中心情的其实篇"></blog-post>
            <!-- 一下是 组件的复用 -->
            <blog-post title="某一篇的测试文档"></blog-post>
            <blog-post title="这是第三篇"></blog-post>

            <h2>
                我们来看上面组件的特点.
            </h2>
            <p>比如,我们使用html元素显示文本的时候,实在符号中间插入文本,比如 <>{在这个位置插入数据}</>
            </p>
            <p>而blog-post的数据.是写在 <span style="font-weight: bolder;color: red;"> 属性位置</span></p>
            <!-- 来看 -->
            <blog-post title="三百六十五个夜晚!"></blog-post>

        </div>

        <h1>-------------------使用for 循环来渲染组件!-----------------------</h1>
        <div id="#app2">
            <!-- 使用for 循环来展示帖子 -->
            <blog-post v-for="post in posts" v-bind:title="post.title" v-bind:key="post.id"></blog-post>
            <p>我们来看 for 循环渲染的方式,与小程序的渲染方式的区别?</p>
            <!-- 下面试小程序的渲染方式 -->
            <view wx:for='{{posts}}' wx:for-item='post' wx:for-index='index' >{{index}},{{post.id}} ,{{post.title}}</view>
            <p>形式不同,中心思想是一致的.== '套路是一致的'</p>
        </div>

        <script>
            // 定义组件
            Vue.component('blog-post', {
                // 定义props
                props: ['title'],
                template: `<h4>{{title}}</h4>`
            })
            //
            var vm = new Vue({
                el: '#app',
                data: {
                    // 可以为空
                },
                // 下面的也可以不用定义
            })

            var vm2 = new Vue({
                el: '#app2',
                data: {
                    posts: [{
                            id: 1,
                            title: 'My journey with Vue'
                        },
                        {
                            id: 2,
                            title: 'Blogging with Vue'
                        },
                        {
                            id: 3,
                            title: 'Why Vue is so fun'
                        }
                    ]
                }


            })
        </script>


    </body>
</html>

#监听子组件事件

监听子组件的事件,关键是 组件内部的触发按钮的事件,需要在 组件中进行监听,并在 当前Vue实例中进行处理.

另外就是,子组件的数据传递问题,因为emit('function-name',args),中的args 很重要,这是针对不同item进行区别处理的关键参数.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>博文</title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    </head>
    <body>
        <div id="app">
            <!-- 内容 -->
            <div v-bind:style="{fontSize:postFontSize + 'em'}">
                <blog v-for="post in posts" v-bind:key='post.id' v-bind:post="post"
                    v-on:enlarge-text='enlargeText'
                    v-on:audit='auditPost'>
                </blog>
            </div>
        </div>

        <!-- vue -->
        <script>
            // 定义组件
            Vue.component('blog', {
                props: ['post'],
                // 这里面需要有数据吗?
                template: `
                <div class="blog-post">
                    <h3>{{post.title}}</h3>
                    <div v-html='post.content'></div>
                    <button v-on:click="$emit('enlarge-text')" >放大字号</button>
                    <button v-on:click="$emit('audit',post.id)">审核通过</button>
                </div>`
            })

            var vm = new Vue({
                el: '#app',
                // 初始化数据
                // 这里需要传入文章

                data: {
                    postFontSize:1,
                    posts: [{
                            'id': 1,
                            'title': '资本论',
                            'content': '<p>这是由马克思写的一本书,我们来看看</p>'
                        },
                        {
                            'id': 2,
                            'title': '贫穷的本质',
                            'content': '<p>这是现代社会写的一本书</p>'
                        }
                    ]

                },
                // 下面还可以有方法
                methods: {
                    enlargeText: function() {
                        console.log('放大文章字号!')
                        this.postFontSize += 0.1
                    },
                    // 针对不同的帖子,需要进行不同的处理,这事需要进行特定数据的传递,就可以使用 emit('functionname',args)
                    // 形式进行内容传递
                    auditPost:function(e){
                        console.log('审核功能触发')
                        console.log(e)
                        // 通过获取的post id ,可以进行 更多针对帖子的操作.
                    }
                }
            })
        </script>
    </body>
</html>

 

#组件注册

前文讲过,组件注册有两种形式,一是 全局注册,另一个 局部注册!

#全局注册

形式:

Vue.component('my-component-name', {
  // ... 选项 ...
})

 

#局部注册

var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }

new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

对于 components 对象中的每个 property 来说,其 property 名就是自定义元素的名字,其 property 值就是这个组件的选项对象。

注,简单理解如下:

 'component-a' 是组件的名称,

 ComponentA 是组件对象.

 

注意局部注册的组件在其子组件中不可用。例如,如果你希望 ComponentA 在 ComponentB 中可用,则你需要这样写:

var ComponentA = { /* ... */ }

var ComponentB = {
  components: {
    'component-a': ComponentA
  },
  // ...
}

上例的意思就是,局部组件A,要在组件B中使用,就需要 首先在 B组件中注册(或者定义).

跟正常使用局部组件 情况一样!

 

#Prop

这是一个组件的能够鲜活并灵活使用的灵魂属性.

#Prop 类型

prop 可以是任何类型,-------------->意味着可以是object类型.为什么object类型这么重要呢?因为在进行项目开发的时候,每一个 数据表中的每一行数据,从数据库获得的时候,都可以认为是 一个object类型.它的所有字段,都是一个属性值.这项就方便进行动态的绑定处理.

props:[
    String,
    Number,
    Boolean,
    Array,
    Object,
    Function,
    Promise
    //or any other constructor
]

#Prop 验证

我们可以为组件的 prop 指定验证要求,例如你知道的这些类型。如果有一个需求没有被满足,则 Vue 会在浏览器控制台中警告你。这在开发一个会被别人用到的组件时尤其有帮助。

Vue.component('my-component', {
  props: {
    // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
    propA: Number,
    // 多个可能的类型
    propB: [String, Number],
    // 必填的字符串
    propC: {
      type: String,
      required: true
    },
    // 带有默认值的数字
    propD: {
      type: Number,
      default: 100
    },
    // 带有默认值的对象
    propE: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        // 这个值必须匹配下列字符串中的一个
        return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
  }
})
posted @ 2021-03-07 23:18  疯人院code  阅读(307)  评论(0编辑  收藏  举报