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>
        
        <h1>这是Vue组件的学习h1>
        
        
        
        <div id="app1">
            

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

            全局注册的组件可以用在其被注册之后的任何(通过new Vue)新创建的Vue跟实例,也包括其组件树中的所有子组件的模板中.
            
            
            <button-counter>button-counter>
        div>

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

            Vue.component('button-counter', {
                data: function() {
                    // 返回一个
                    //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">
            
            <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>

        
        <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': '

这是由马克思写的一本书,我们来看看

' }, { 'id': 2, 'title': '贫穷的本质', 'content': '

这是现代社会写的一本书

' } ] }, // 下面还可以有方法 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
      }
    }
  }
})
vue