首页 > 其他分享 >vue之组件

vue之组件

时间:2023-04-12 10:11:40浏览次数:40  
标签:vue name template 组件 页面 data 定义

目录

简介

组件(component)是vue.js最强大的功能之一。组件的作用就是封装可重用的代码,通常一个组件就是一个功能体,便于在多个地方都能够调用这个功能体。 每个组件都是Vue的实例对象。 我们实例化的Vue对象就是一个组件,而且是所有组件的根组件
在工程化工发后,一个组件就是一个 xxx.vue 文件

  • 父子组件定义:一个组件中定义了一个局部组件,那么这时这个局部组件就称为这个组件的“子组件”,这个组件对于局部组件来说就称为“父组件”
  • 组件分为全局组件和局部组件
  • 父子页面之间的data是不共享的
  • 在组件中,this代指当前的组件
  • 在组件中,data是一个函数,需要有返回值(return)

全局组件

全局组件就是定义了以后,全局都可以使用的组件,就是全局组件

语法

Vue.component( # 定义一个全局组件,但是需要注意,这个组件需要写到根组件上方,写到根组件下方会不生效
'test1',  # 定义一个组件名称,调用的时候,只要写到body中的根组件中即可
{          # 除了组件名称以外,其它的内容都写到大括号中
template:`html内容`,  # 定义template(固定写法),然后在里面写html内容
data:(){return {xxx:xxx}} # 定义组件中的变量,组件中的变量需要使用return返回
methods:{}  # 除了上述部分的以外,其它的定义与根组件是相同的,比如这个methods
}
)
# 注意:多个组件使用多个Vue.component()进行定义,组件之间也可以引用,只要将定义好的组件名称以标签的形式写到template中引用即可,但是不能相互引用,否则会报错。详细可以见下面的示例。

相互引用报错图例:
image

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <test1></test1>   <!--只要使用组件定义的标签就可以了-->
    <test2></test2>   <!--多个组件只要使用标签定义即可,当然也可以调用多次-->
</div>
<script>
        // 组件必须写到new Vue({})也就是根组件的上面,写到下面会不生效
        Vue.component(  // 全局组件
        'test1',  #,   // 定义组件名称,之后在根组件调用的时候直接使用此名称的标签即可
        {
            // 定义组件的内容,这里面就是html页面内容,使用反引号的话可以换行
            template: `
              <div>
                <span style="font-size: 40px">{{test}}</span>
                <!--组件内也可以添加其它组件-->
                <test2></test2>
              </div>
            `,
            // 定义组件的变量,组件的变量必须是return出来
            data() {
                return {
                    test: '全局组件1测试',
                }
            },
            // 其它的就与根组件定义相同了,比如methods定义方法
            methods: {},
        })
        // 如果要定义多个组件,就写多个Vue.component即可
        Vue.component(  // 全局组件
        'test2',
        {
            template: `
              <div>
                <span style="font-size: 40px">{{test}}</span>
              </div>
            `,
            data() {
                return {
                    test: '全局组件2测试',
                }
            },
            methods: {},
        })
    var vm = new Vue({
        el: '#app',
        data: {
        },
        methods: {
            btnFunc() {
                this.name='Hello World'
            }
        },
    })
</script>
</body>
</html>

局部组件

局部组件就是定义在一个组件内部,只供这个组件使用,其他的组件都不能使用。

语法

# 在一个全局组件或者根组件中使用components进行定义
components:{
'组件名称':{  # 注意这里与全局变量不同,使用的是冒号
template:`html内容`,
data(){
return {变量: '变量内容'}
      }
   }
}
# 之后,在组件中就可以调用这个局部组件了。
# 如果将局部组件定义到根组件中,那么也可以直接在body下的根标签中调用

# 也可以将局部组件的内容赋值给一个变量,然后在components中使用变量即可,如下:
    var xxx = {
        template: `
          <h1>{{ name }}</h1>
        `,
        data() {
            return {name: '我是app的局部组件,测试foo赋值'}
        }
    }
    components: {xxx}  # 这样定义了以后,调用的时候使用  <xxx></xxx>  调用即可
    # 写法二
    components: {'组件名称': xxx}  # 这样定义了以后,调用的时候使用 <组件名称></组件名称>  即可
    # 组件名称可以简写:
    <组件名称/>

# 如果要定义多个局部组件,只需要在components中增加新的定义即可(不是增加新的components),使用逗号隔开,如下:
components:{
'组件名称1':{  # 注意这里与全局变量不同,使用的是冒号
template:`html内容`,
data(){
return {变量: '变量内容'}
      }
   },  # 使用逗号隔开
'组件名称2':{  # 注意这里与全局变量不同,使用的是冒号
template:`html内容`,
data(){
return {变量: '变量内容'}
      }
   }
}

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <jsd></jsd>
    <foo></foo>
</div>
<script>
    // 如果要定义多个组件,就写多个Vue.component即可
    Vue.component(  // 全局组件
        'test2',
        {
            template: `
              <div>
              <span style="font-size: 40px">{{ test }}</span>
              </div>
            `,
            data() {
                return {
                    test: '全局组件2测试',
                }
            },
            methods: {},
            components: {  // 在全局组件中定义局部组件
                'jsd': {
                    template: `
                      <h1>{{ name }}</h1>
                    `,
                    data() {
                        return {name: '我是app的局部组件'}
                    }
                },
                foo  // 如果要定义多个局部组件,只需要写在components中即可
            },
        })
    // 也可以将组件的内容赋值给一个变量,之后再在组件中调用这个变量即可
    var foo = {
        template: `
          <h1>{{ name }}</h1>
        `,
        data() {
            return {name: '我是app的局部组件,测试foo赋值'}
        }
    }
    var vm = new Vue({
        el: '#app',
        data: {},
        methods: {},
        components: {  // 定义局部组件
            'jsd': {
                template: `
                  <h1>{{ name }}</h1>
                `,
                data() {
                    return {name: '我是app的局部组件'}
                }
            },
            foo  // 如果要定义多个局部组件,只需要写在components中即可
        },
    })
</script>
</body>
</html>

组件间通信

因为组件之间的data是不共享的,有时候一个组件需要把数据传递给另一个组件,有三种情况:

  1. 父组件传值给子组件:使用自定义属性的方式,或使用ref属性
  2. 子组件传值给父组件:使用自定义事件的方式,或使用ref属性
  3. 跨组件传值:使用vuex或cookies/localstorage等都可以实现

父子页面通信之父传子

父传子通信需要使用自定义属性的方式。

什么是自定义属性?
自定义属性就是标签上的 style、class、id 等都属于属性,我们知道,属性是可以自定义的。

语法

# 注意:自定义属性不可以使用驼峰式写法;如果与子组件中变量冲突,子组件中的变量会被替换
# 1. 父组件传子组件
<子标签 :自定义属性名称="父组件的变量名">
# 2. 子接书父组件的值,增加一个键值对
props: ['自定义属性名称']
# 2.1 也可以限制传入的值必须是某一个类型,如Number或String类型,这样当传入的值不是指定的类型后,不会影响页面的显示,但在console中会报错。
props{自定义属性名称:值类型定义}
# 3. 在子组件中的插值语法插入的值应该为自定义属性名称,而不是变量名了
{{自定义属性名称}}

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<!--在标签中定义组件,用来将父组件中的值传入-->
<myele :my_publish="name"></myele>
</div>
<script>
    var myele = {
        template: `
          <div>
          <p>父组件的变量name:{{my_publish}}</p>
          <p>子组件的变量publish:{{publish}}</p>
          </div>
        `,
        data() {
            return {
                // 子组件中的变量
                publish: '任天堂',
            }
        },
        // 子组件接收父组件传入的值
        props: ['my_publish']
        // 如果要限定传入的值必须为一个属性,可以使用下面的方法
        props: {'my_publish': String}
        // 如果传入的值不是限定的值,这样会显示到页面,但在console中会报错,可见下图
        props: {'my_publish': Number}
    }
    new Vue({
        el: '#app',
        data: {
            // 父组件中的变量
            name: '赛尔达传说',
        },
        components: {
            myele
        }
    })
</script>
</body>
</html>
  • 限定值后的报错
    image

组件通信之子传父

子传父需要使用自定义事件的方法,自定义事件就是定义一个函数,通过函数进行传递

需求:定义一个input输入框,之后在用户输入之后,将输入的值传递给父组件并在浏览器这显示,如下图
image

语法

# 1. 定义样式
# 2. 在点击按钮时,会触发一个函数
<input type="text" v-model="name"><button @click="clickFunc">点我传递数据</button>
# 3. 函数的内容是触发父组件的一个函数,也就是sendmsg函数
clickFunc(){
    # this.$emit的是固定写法,意思是触发父组件自定义事件sendmsg的执行,并且传递一个this.name参数
    this.$emit('sendmsg', this.name)
}
# 4. 父组件定义一个sendmsg事件,用于接收子组件传递过来的参数
myevent(item){
    this.name=item
}
# 5. 父组件的name就与子组件的name的值一致了

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<p>子组件传递过来的数据: {{name}}</p>
<myele @sendmsg="myevent"></myele>
</div>
<script>
var myele={
    // 1. 子组件中,使用v-model双向数据绑定,这样输入的值会传递给name参数,之后定义点击事件,触发clickFunc函数
    template:`
    <div>
        <input type="text" v-model="name"><button @click="clickFunc">点我传递数据</button>
    </div>
    `,
    data(){
        return{
            name:''
        }
    },
    methods:{
        // 2. 因为第一步中触发函数,所以要定义一个函数供botton按钮触发
        clickFunc(){
            // 3. 函数内容是触发发父组件的函数,并将子组件的变量当作值传递给父组件
            this.$emit('sendmsg', this.name)
        }
    }
}
new Vue({
    el:'#app',
    data:{
        name: '',
    },
    methods:{
        // 4. 因为子组件触发了父组件的函数并传入了值,所以父组件需要定义一个函数供它触发,并且需要定义参数用于接收子组件传入进的值
        myevent(item){
            // 5. 让自己的变量等于传入的值,这样就完成了子传父了整个过程
            this.name=item
        }
    },
    components:{
        myele
    }
})
</script>
</body>
</html>

使用ref进行父子组件通信

vue提供了一个ref方法,可以更方便简单的进行父子组件通信
使用ref不需要关注是父传子还是子传父

方法

# 1. ref可以放到普通标签中
<div ref="mydiv">{{name}}</div>
# 2. ref也可以放到组件中
<myele ref="myele"></myele>
template: `<div><div ref="mydiv">我是局部组件的div--->{{name}}</div></div>`
# 3. 在父或子组件中进行赋值
this.name=this.$refs.myele.name

image
image

示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <!--在标签中可以定义ref-->
    <div ref="mydiv">{{name}}</div>
    <button @click="btnFunc">点我</button>
    <!--在组件中也可以定义ref-->
    <myele ref="myele"></myele>
</div>
<script>
    myele = {
        template: `<div><div ref="mydiv">我是局部组件的div--->{{name}}</div></div>`,
        data(){return{name: '局部组件的标签'}}},
    new Vue({
        el: '#app',
        data: {name: '我是全局组件的标签'},
        methods: {
            btnFunc() {
                console.log(this.$refs)
                // 可以使用this.$refs找到在body体中定义的ref标签,根据标签就可以找到标签对应的值,之后就可以根据这个进行赋值,就完成了父子组件通信
                this.name=this.$refs.myele.name
                // 下面这个就是父传子,上面的就是子传父
                this.$refs.myele.name=this.name
            },
        },
        components: {
            myele
        }
    })
</script>
</body>
</html>

动态组件(component)

实现点击一个标签,则显示对应的内容功能

  • 如下图所示,点击sheet1则显示sheet1中的内容,点击sheet2则显示sheet2中的功能
    image

普通方法实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <!--增加点击事件,如果点击相应的页面,则将值传入函数,再由函数修改show的值,用于下面的判断-->
    <span style="font-size: 40px" @click="btnFunc('sheet1')">sheet1 ||</span>
    <span style="font-size: 40px" @click="btnFunc('sheet2')">sheet2 ||</span>
    <span style="font-size: 40px" @click="btnFunc('sheet3')">sheet3</span>

    <!--设定条件,如果条件成立,则显示,如果不成立则不显示-->
    <sheet1 v-if="show=='sheet1'"></sheet1>
    <sheet2 v-else-if="show=='sheet2'"></sheet2>
    <sheet3 v-else-if="show=='sheet3'"></sheet3>
</div>
<script>
    var sheet1 = {template: `<div>我是sheet1页面,第一个页面</div>`}
    var sheet2 = {template: `<div>我是sheet2页面,第二个页面</div>`}
    var sheet3 = {template: `<div>我是sheet3页面,第三个页面</div>`}

    new Vue({
        el: '#app',
        data: {
            show: 'sheet1'
        },
        // 设定好函数,用于接收页面返回的参数,根据参数修改show的值
        methods: {
            btnFunc(item) {
                this.show = item
            }
        },
        components: {
            sheet1, sheet2, sheet3
        }
    })
</script>
</body>
</html>

使用组件component实现

使用component的话,就可以替换大量的if-else循环了,如果页面比较多的话,会节省大量的代码。

  • 如下代码所示,只修改了if-else循环部分,其他部分不需要修改
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <!--增加点击事件,如果点击相应的页面,则将值传入函数,再由函数修改show的值,用于下面的判断-->
    <span style="font-size: 40px" @click="btnFunc('sheet1')">sheet1 ||</span>
    <span style="font-size: 40px" @click="btnFunc('sheet2')">sheet2 ||</span>
    <span style="font-size: 40px" @click="btnFunc('sheet3')">sheet3</span>

    <!--使用component组件,使用is绑定一个变量,is后面的值是什么,就会显示哪个组件,与if-else相比,更加的简洁,也更好写一些-->
    <component :is="show"></component>
</div>
<script>
    var sheet1 = {template: `<div>我是sheet1页面,第一个页面</div>`}
    var sheet2 = {template: `<div>我是sheet2页面,第二个页面</div>`}
    var sheet3 = {template: `<div>我是sheet3页面,第三个页面</div>`}

    new Vue({
        el: '#app',
        data: {
            show: 'sheet1'
        },
        // 设定好函数,用于接收页面返回的参数,根据参数修改show的值
        methods: {
            btnFunc(item) {
                this.show = item
            }
        },
        components: {
            sheet1, sheet2, sheet3
        }
    })
</script>
</body>
</html>

动态组件相关keep-alive

动态组件就是当你跳转到一个标签里面后,之前的标签就会被删除掉。有这么一个需求,就是如果我的页面中有一个input输入框,我输入了一些内容后,切换了标签,之后再切换回input输入框的标签后,需要输入的内容还在。这就需要keep alive了

  • 其它代码与上一章节相同,只是增加了keep-alive标签
<keep-alive>
    <component :is="show"></component>
</keep-alive>

组件之插槽(slot)

一般情况下,编写完一个组件之后,组件的内容都是写死的,如果需要修改页面的时候,就需要去组件中修改,这样扩展性比较差。为了解决这个问题,就出现了插槽这个概念。只需要在组件中添加即可

匿名插槽

<!--先设定好组件,里面定义一个slot标签-->
var sheet1 = {template: `
<div>
<h1>我是标题</h1>
<slot></slot>
<h1>我是结尾</h1>
</div>
`}

<!--引用组件-->
<!--引用时只需要将内容写到引用的组件中即可-->
<sheet1>
    我是插槽的内容!!!
</sheet1>

image

  • 但是匿名插槽有一个问题,如果定义了多个slot标签,则会导致插入的内容会重复显示在页面中
var sheet1 = {template: `
<div>
<h1>我是标题</h1>
<slot></slot>
<h1>我是结尾</h1>
<slot></slot>
</div>
`}

image

具名插槽

为了解决上面的问题,就引出了具名插槽,指定插入到哪个slot中

<!--定义组件,并在组件中定义name属性,指定name属性的名字-->
var sheet1 = {template: `
<div>
<h1>我是标题</h1>
<slot name="s1"></slot>
<h1>我是结尾</h1>
<slot name="s2"></slot>
</div>
`}

<!--在引用的时候,定义一个slot属性,并在slot属性中指定要引用哪个slot标签-->
<sheet1>
    <div slot="s2">我是2号插槽的内容</div>
    <div slot="s1">我是1号插槽的内容</div>
</sheet1>
  • 效果如下:

image

标签:vue,name,template,组件,页面,data,定义
From: https://www.cnblogs.com/smyz/p/17305723.html

相关文章

  • delphi 如何给自开发的组件设置图标?
    经过其他老师指点,自己摸索,发现如何实现,现说明如下,供大家参考。一、建立图标文件1、建立一个24X24的256色BMP格式文件。2、文件命名为该组件的名称。二、建立资源文件:Project→Resource and Images,点击Add将BMP格式图标文件加入,Resource Identifiler 设为组件的名称......
  • 1.Vue的基本原理
    当一个Vue实例创建时,Vue会遍历data中的属性,用Object.defineProperty(vue3.0使用proxy)将它们转为getter/setter,并且在内部追踪相关依赖,在属性被访问和修改时通知变化。每个组件实例都有相应的watcher程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的setter被调用时,会......
  • Vue3快速上手
    Vue3快速上手1.Vue3简介2020年9月18日,Vue.js发布3.0版本,代号:OnePiece(海贼王)耗时2年多、2600+次提交、30+个RFC、600+次PR、99位贡献者github上的tags地址:https://github.com/vuejs/vue-next/releases/tag/v3.0.02.Vue3带来了什么1.性能的提升打包大小减少41%初次......
  • 1.Vue的基本原理
    当一个Vue实例创建时,Vue会遍历data中的属性,用Object.defineProperty(vue3.0使用proxy)将它们转为getter/setter,并且在内部追踪相关依赖,在属性被访问和修改时通知变化。每个组件实例都有相应的watcher程序实例,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的setter被调用......
  • (一)初始vue
    data属性data属性是传入一个函数,并且该函数需要返回一个对象:在Vue2的时候,也可以传入一个对象在Vue3的时候,必须传入一个函数,否则报错data中返回的对象会被vue的响应式系统劫持,之后对该对象的修改或者访问都会在劫持中被处理:所有我们在template或者app通过{{counter}},访问......
  • #yyds干货盘点 springboot和vue搭建前后端项目实现员工的增删改查
    前言我是歌谣今天继续带来前后端项目的开发上次已经开发了部门管理,今天继续开发员工管理后端第一步empcontroller代码packagecom.itheima.controller;importcom.itheima.pojo.Emp;importcom.itheima.pojo.PageBean;importcom.itheima.pojo.Result;importcom.itheima.s......
  • Vue动态创建组件实例并挂载到body
    方式一importVuefrom'vue'/***@paramComponent组件实例的选项对象*@paramprops组件实例中的prop*/exportfunctioncreate(Component,props){constcomp=new(Vue.extend(Component))({propsData:props}).$mount()document.body.appendChild(......
  • 一个 OpenTiny,Vue2 Vue3 都支持!
    大家好,我是Kagol,OpenTiny 开源社区运营,TinyVue 跨端、跨框架组件库核心贡献者,专注于前端组件库建设和开源社区运营。今天给大家介绍如何同时在Vue2和Vue3项目中使用 TinyVue。TinyVue是一套跨端、跨框架的企业级UI组件库,支持Vue2和Vue3,支持PC端和移动端。......
  • vue3使用elmentui-plus中的图标
    按照官网这样直接引入使用,不知道为啥行不通:import{Document,MenuasIconMenu,Location,Setting,}from'@element-plus/icons-vue'使用时,需要<script>import{UserFilled}from'@element-plus/icons-vue'//使用的时候需要单独引入这个图标从......
  • vue项目中webpack编译glsl文件的配置
    1、 安装webpack-glsl-loader npminstallwebpack-glsl-loader2、修改vue.config.js配置,添加内容如下module.exports=defineConfig({configureWebpack:(config)=>{config.module.rules.push({test:/\.glsl$/,use:[......