【Vue】学习笔记:Vue组件

简介: 【Vue】学习笔记:Vue组件

文末有我看的这个视频的链接。

目录

组件注册


全局注册

全局注册的组件可以在注册后用于任意实例或者组件中

Vue.component('组件名',{/*选项对象*/})

全局注册必须设置在跟Vue实例之前

实例

<div id="root">
      <input-search></input-search>
    </div>
    <script>
        Vue.config.productionTip=false//隐藏控制台提示
        Vue.component('input-search',{
            template:' <input class="control" type="text" placeholder="请输入要搜索的关键字">'
        })
        const vm = new Vue({
            el:'#root',
            data(){
             return{
             }
            }
        })  
        vm.$mount('#root')
    </script>

组件基础

组件命名规则

  • kebab-case:'my-component'
  • PascalCase:'MyComponent'
Vue.component('my-component-a',{/**/})
Vue.component('MyComponentB',{/**/})

无论使用哪种命名方式,在DOM中都只有第一种命名方式可以使用

<div id="root">
      <input-search></input-search>
      <just-play></just-play>
    </div>
    <script>
        Vue.config.productionTip=false//隐藏控制台提示
        Vue.component('input-search',{
            template:' <input class="control" type="text" placeholder="请输入要搜索的关键字">'
        })
        Vue.component('JustPlay',{
            template:'<a href="https://mllt.cc">Just play</a>'
        })
        const vm = new Vue({
            el:'#root',
            data(){
             return{
             }
            }
        })  
        vm.$mount('#root')
    </script>

q3.png

template选项

该选项用于设置组件的结构,最终被引入根实例或者其他组件中

单项数据流

父子组件间所有prop数据应当存储在data中后操作

<div id="root">
      <my-component :initial-title="title"></my-component>
    </div>
    <script>
        Vue.config.productionTip=false//隐藏控制台提示
        Vue.component('my-component',{
            props:['initialTitle'],
            template:`
            <div>{{title}}</div>
            `,
            data(){
                return {
                    title:this.initialTitle
                }
            }
        });
        const vm = new Vue({
            el:'#root',
            data(){
             return{
                 title:"Just Play?"
             }
            }
        })  
        vm.$mount('#root')
    </script>

q2.png

<div id="root">
      <my-component :initial-title="title"></my-component>
    </div>
    <script>
        Vue.config.productionTip=false//隐藏控制台提示
        Vue.component('my-component',{
            props:['initialTitle'],
            template:`
            <div>{{title}}
                <button @click="fn">按一下</button>
                </div>
            `,
            data(){
                return {
                    title:this.initialTitle
                }
            },
            methods:{
                fn(){
                    console.log(this);
                    this.title="It's new title"
                }
            }
        });
        const vm = new Vue({
            el:'#root',
            data(){
             return{
                 title:"Just Play?"
             }
            }
        })  
        vm.$mount('#root')
    </script>

如果prop为数组或对象时,子组件操作将会影响到父组件的状态

<div id="root">
      <my-component 
      :initial-title="title" 
      :obj="obj"></my-component>
    </div>
    <script>
        Vue.config.productionTip=false//隐藏控制台提示
        Vue.component('my-component',{
            props:['initialTitle','obj'],
            template:`
            <div>{{title}}
                <button @click="fn">按一下</button>
                </div>
            `,
            data(){
                return {
                    title:this.initialTitle
                }
            },
            methods:{
                fn(){
                    console.log(this);
                    // this.title="It's new title"
                    this.obj.name="萌狼蓝天";
                }
            }
        });
        const vm = new Vue({
            el:'#root',
            data(){
             return{
                 title:"Just Play?",
                 obj:{
                     name:"xiaoming",
                     age:18,
                 }
             }
            }
        })  
        vm.$mount('#root')
    </script>

q1.png

data选项

data选项用于存储组件的数据,与根实例不同,组件的data选项必须为函数,数据设置在返回值对象中

<div id="root">
      <my-com-a></my-com-a>
    </div>
    <script>
        Vue.config.productionTip=false//隐藏控制台提示
        Vue.component('MyComA',{
            template:`
            <div>
                <h3>{{title}}</h3>
                <p>{{content}}</p>
            </div>
            `,
            data(){
                return{
                    title:'Biao ti ya',
                    content:"nei rong ya"
                }
            }
        })
        const vm = new Vue({
            el:'#root',
            data(){
             return{
             }
            }
        })  
        vm.$mount('#root')
    </script>

这种喷那个实现方式为了确保每个组件实例可以维护一份被返回对象的独立拷贝,不会相互影响

局部注册

局部注册的组建只能用在当前实例或组件中

<div id="root">
      <my-com-a></my-com-a>
      <my-com-b></my-com-b>
    </div>
    <script>
        Vue.config.productionTip=false//隐藏控制台提示
        const vm = new Vue({
            el:'#root',
            data(){
             return{
             }  
            },
             components:{
                'MyComA':{
                    template:`
                        <div>
                            <h3>{{title}}</h3>
                            <p>{{content}}</p>
                        </div>
                    `, 
                    data(){
                        return{
                            title:'Biao ti ya',
                            content:"nei rong ya"
                        }
                    }
                },
                'MyComB':{
                    template:`
                        <div>
                            <h3>{{title}}</h3>
                            <p>{{content}}</p>
                        </div>
                    `, 
                    data(){
                        return{
                            title:'Biao ti ya2',
                            content:"nei rong ya2"
                        }
                    }
                },
             }
        })  
        vm.$mount('#root')
    </script>

单独配置组件的选项对象

var MyComponentA={/*……*/}
var MyComponentB={/*……*/}
new Vue({
  el:'#app',
  components:{
    'my-component-a':MyComponentA,
    'my-component-b':MyComponentB,
  }
});

ES6对象属性简写

new Vue({
  el:'#app',
  components:{
    MyComponentA,
    MyComponentB
  }
});

q4.png

<div id="root">
        <my-com-a></my-com-a>
        <my-com-b></my-com-b>
    </div>
    <script>
        Vue.config.productionTip = false //隐藏控制台提示
        var MyComA = {
            template: `
                <div>
                    <h3>{{title}}</h3>
                    <p>{{content}}</p>
                </div>
            `,
            data() {
                return {
                    title: 'Biao ti ya',
                    content: "nei rong ya"
                }
            }
        };
        var MyComB = {
            template: `
                <div>
                    <h3>{{title}}</h3>
                    <p>{{content}}</p>
                </div>
            `,
            data() {
                return {
                    title: 'Biao ti ya2',
                    content: "nei rong ya2",
                }
            }
        };
        const vm = new Vue({
            el: '#root',
            data() {
                return {}
            },
            components: {
                'MyComA': MyComA,//写法1
                MyComB,//写法2
            }
        })
        vm.$mount('#root')
    </script>

<div id="root">
        <!-- 静态属性设置 -->
        <my-component-a
        title="静态标题"
        content="静态内容"
        ></my-component-a>
        <!-- 动态属性绑定 -->
        <my-component-a
        v-bind:title="'zhe shi jing tai biao ti'"
        :content="'zhe sh jing tai nei rong'"
        ></my-component-a>
        <!-- 动态属性绑定常用操作 -->
        <my-component-a
        :title="item.title"
        :conent="item.content"
        ></my-component-a>
    </div>
    <script>
        Vue.config.productionTip=false//隐藏控制台提示
        //创建子组件
        Vue.component('my-component-a',{
            props:['title','content'],
            template:`
            <div>
                <h3>{{title}}</h3>
                <p>{{content}}</p>
            </div>
            `
        })
        const vm = new Vue({
            el:'#root',
            data(){
             return{
                 item:{
                    title:'Biaoti',
                    content:'neirong',
                 }  
             }
            }
        })  
        vm.$mount('#root')
    </script>

组件通信

在组件间传递数据的操作,称为组件通信

父组件向子组件传值

组件传值

通过子组件的props选项接收父组件的传值

Vue.component('my-component',{
  props:['title'],
  template:'<h2>{{title}}</h2>'
})

注意:props不要与data存在同名属性

父组件设置如下

<div id="app">
  <my-component title="例1"></my-component>
  <my-component :title="例2"></my-component>
  <my-component :title="item.title"></my-component>
</div>
new Vue({
  el:'#app',
  data:{
    item:{
      title:'父组件中的数据'
    }
  }
})

Props命名规则

建议prop命名使用cameCase,父组件绑定时使用kebab-case

<div id="root">
      <my-component
      :item-title='item.title'
      :item-content="item.content"
      ></my-component>
    </div>
    <script>
       Vue.config.productionTip=false//隐藏控制台提示
       Vue.component('my-component',{
           props:['itemTitle','itemContent'],
           template:`
                 <div>
                    <h3>{{itemTitle}}</h3>
                    <p>{{itemContent}}</p>
                </div>
           `
       })
        const vm = new Vue({
            el:'#root',
            data(){
             return{
                 item:{
                     title:'Biao Ti is',
                     content:'Nei Rong is'
                 }
             }
            }
        })  
        vm.$mount('#root')
    </script>

练习:通过v-for创建组件

<div id="root">
      <!-- 通过v-for遍历数据items,创建组件并生成内容 -->
      <demo-item
          v-for="item in items"
          :item-title="item.title"
          :item-content="item.content"
          :key = "item.title"
          :item="item"
      ></demo-item>
    </div>
    <script>
        Vue.config.productionTip=false//隐藏控制台提示
        Vue.component('demoItem',{
            props:['itemTitle','itemContent','item'],
            template:`
                <div>
                    <h3>{{itemTitle}}</h3>
                    <p>{{itemContent}}</p>
                </div>
            `
        })
        const vm = new Vue({
            el:'#root',
            data(){
             return{
                items:[
                    {
                        title:'Biao Ti is',
                        content:'Nei Rong is'
                    },
                    {
                        title:'Biao Ti is2',
                        content:'Nei Rong is2'
                    },
                    {
                        title:'Biao Ti is3',
                        content:'Nei Rong is3'
                    }
                ]
             }
            }
        })  
        vm.$mount('#root')
    </script>

子组件向父组件传值

组件传值

子向父传值需要通过自定义事件实现

例如:商品为子组件,购物车为父组件,父组件需要统计商品个数,就需要在子组件个数变化时传值给父组件。

q3.png

q2.png

<div id="root">
      <product-item
      v-for="product in products"
      :key = "product.id"
      :title="product.title"
      ></product-item>
    </div>
    <script>
        Vue.config.productionTip=false//隐藏控制台提示
        Vue.component('ProductItem',{
            props:['title'],
            template:`
            <div>
                <span>商品名称:{{title}},商品个数:{{count}}</span>
                <button @click="countIns">+1</button>
                <button @click="countInsf">-1</button>
            </div>
            `,
            data(){
                return{
                    count:0
                }
            },
            methods:{
                countIns(){
                    this.count++;
                },
                countInsf(){
                    if(this.count<=0) alert("已经清空啦")
                    else this.count--;
                },
            }
        })
        const vm = new Vue({
            el:'#root',
            data(){
             return{
               products:[
                   {
                       id:1,
                       title:'苹果11斤'
                   },
                   {
                       id:2,
                       title:'香蕉12斤'
                   },
                   {
                       id:3,
                       title:'橙子13斤'
                   },
               ],
               totalCount:0  
             }
            }
        })  
        vm.$mount('#root')
    </script>

子组件数据变化时,通过$emit()触发自定义事件

Vue.component('product-item',{
  ……
  methods:{
    countIns(){
    this.$emit('count-change');
    this.count++;
    }
  }
});

自定义事件名称建议使用kebab-case

父组件监听子组件的自定义事件,并设置处理程序

<div id="app">
  ……
  <product-item
  ……
  @count-change = "totalCount++"
  ></product-item>
  ……
</div>

q1.png

<div id="root">
      <product-item
      v-for="product in products"
      :key = "product.id"
      :title="product.title"
      @count-change-add="totalCount++"
      @count-change-jianshao="totalCount--"
      ></product-item>
    <p>商品总数为:{{totalCount}}</p>
    </div>
    <script>
        Vue.config.productionTip=false//隐藏控制台提示
        Vue.component('ProductItem',{
            props:['title'],
            template:`
            <div>
                <span>商品名称:{{title}},商品个数:{{count}}</span>
                <button @click="countIns">+1</button>
                <button @click="countInsf">-1</button>
            </div>
            `,
            data(){
                return{
                    count:0
                }
            },
            methods:{
                countIns(){
                    this.$emit('count-change-add');
                    this.count++;
                },
                countInsf(){
                    if(this.count<=0) alert("已经清空啦")
                    else{
                        this.$emit('count-change-jianshao');
                        this.count--;
                    }
                },
            }
        })
        const vm = new Vue({
            el:'#root',
            data(){
             return{
               products:[
                   {
                       id:1,
                       title:'苹果11斤'
                   },
                   {
                       id:2,
                       title:'香蕉12斤'
                   },
                   {
                       id:3,
                       title:'橙子13斤'
                   },
               ],
               totalCount:0  
             }
            }
        })  
        vm.$mount('#root')
    </script>

自定义事件传值

子组件触发事件时可以向父组件传值

非父子组件传值

非父子组件:兄弟组件或完全无关的两个组件

其他通信方式

组件插槽


内置组件


观看的教程链接

【白嫖】3小时带你搞定 Vue 组件 - 拉勾教育出品_哔哩哔哩_bilibili

相关文章
|
6天前
|
JavaScript
vue消息订阅与发布
vue消息订阅与发布
|
3天前
|
JavaScript
理解 Vue 的 setup 应用程序钩子
【10月更文挑战第3天】`setup` 函数是 Vue 3 中的新组件选项,在组件创建前调用,作为初始化逻辑的入口。它接收 `props` 和 `context` 两个参数,内部定义的变量和函数需通过 `return` 暴露给模板。`props` 包含父组件传入的属性,`context` 包含组件上下文信息。`setup` 可替代 `beforeCreate` 和 `created` 钩子,并提供类似 `data`、`computed` 和 `methods` 的功能,支持逻辑复用和 TypeScript 类型定义。
20 11
|
5天前
|
JavaScript
vue尚品汇商城项目-day07【vue插件-50.(了解)表单校验插件】
vue尚品汇商城项目-day07【vue插件-50.(了解)表单校验插件】
15 4
|
5天前
|
JavaScript
vue尚品汇商城项目-day07【51.路由懒加载】
vue尚品汇商城项目-day07【51.路由懒加载】
16 4
|
6天前
|
JavaScript 前端开发
Vue学习笔记8:解决Vue学习笔记7中用v-for指令渲染列表遇到两个问题
Vue学习笔记8:解决Vue学习笔记7中用v-for指令渲染列表遇到两个问题
|
5天前
|
JavaScript
vue尚品汇商城项目-day07【vue插件-54.(了解)生成二维码插件】
vue尚品汇商城项目-day07【vue插件-54.(了解)生成二维码插件】
15 2
|
JavaScript 测试技术 容器
Vue2+VueRouter2+webpack 构建项目
1). 安装Node环境和npm包管理工具 检测版本 node -v npm -v 图1.png 2). 安装vue-cli(vue脚手架) npm install -g vue-cli --registry=https://registry.
1039 0
|
8天前
|
JavaScript
vue组件中的插槽
本文介绍了Vue中组件的插槽使用,包括单个插槽和多个具名插槽的定义及在父组件中的使用方法,展示了如何通过插槽将父组件的内容插入到子组件的指定位置。
|
7天前
|
JavaScript 前端开发 IDE
Vue学习笔记5:用Vue的事件监听 实现数据更新的实时视图显示
Vue学习笔记5:用Vue的事件监听 实现数据更新的实时视图显示
|
7天前
|
JavaScript 前端开发 API
Vue学习笔记4:用reactive() 实现数据更新的实时视图显示
Vue学习笔记4:用reactive() 实现数据更新的实时视图显示