search
HomeWeb Front-endJS TutorialTake you through Vue.js components in minutes

Introduction to components

The component system is one of the important concepts of Vue.js. It provides an abstraction that allows us to use independent and reusable small components to build large applications. Any type of application interface can be abstracted into a Component tree:

Take you through Vue.js components in minutes

So what are components?
Components can extend HTML elements and encapsulate reusable HTML code. We can think of components as custom HTML elements.

Creation and registration of components

Basic steps
There are three steps to use Vue.js components: create component constructor, register component and use component.

Take you through Vue.js components in minutes

The following code demonstrates these 3 steps:

<!DOCTYPE html>
<html>
 <body>
 <p id="app">
  <!-- 3. #app是Vue实例挂载的元素,应该在挂载元素范围内使用组件-->
  <my-component></my-component>
 </p>
 </body>
 <script src="js/vue.js"></script>
 <script>
 
 // 1.创建一个组件构造器
 var myComponent = Vue.extend({
  template: &#39;<p>This is my first component!</p>&#39;
 })
 
 // 2.注册组件,并指定组件的标签,组件的HTML标签为<my-component>
 Vue.component(&#39;my-component&#39;, myComponent)
 
 new Vue({
  el: &#39;#app&#39;
 });
 
 </script>
</html>

The running results are as follows:

Take you through Vue.js components in minutes

As you can see, there is no difference between using components and using ordinary HTML elements.

Understanding the creation and registration of components

We use the following steps to understand the creation and registration of components:
1. Vue.extend() is an extension of the Vue constructor. Calling Vue.extend() creates a A component constructor, rather than a concrete component instance.
2. The Vue.extend() constructor has an options object, and the template attribute of the option object is used to define the HTML to be rendered by the component.
3. When using Vue.component() to register a component, you need to provide 2 parameters. The first parameter is the label of the component, and the second parameter is the component constructor.
4. The Vue.component() method internally calls the component constructor to create a component instance.
5. The component should be mounted to a Vue instance, otherwise it will not take effect.

Please note point 5. The following code uses the my-component tag in 3 places, but only the my-component tags under #app1 and #app2 work.

<!DOCTYPE html>
<html>
 <body>
 <p id="app1">
  <my-component></my-component>
 </p>
 
 <p id="app2">
  <my-component></my-component>
 </p>
 
 <!--该组件不会被渲染-->
 <my-component></my-component>
 </body>
 <script src="js/vue.js"></script>
 <script>
 var myComponent = Vue.extend({
  template: &#39;<p>This is a component!</p>&#39;
 })
 
 Vue.component(&#39;my-component&#39;, myComponent)
 
 var app1 = new Vue({
  el: &#39;#app1&#39;
 });
 
 var app2 = new Vue({
  el: &#39;#app2&#39;
 })
 </script>
</html>

Take you through Vue.js components in minutes

Global registration and local registration

When calling Vue.component() to register a component, the component's registration is global, which means that the component can be used under any Vue example.
If you do not need global registration, or if you want the component to be used in other components, you can use the components attribute of the options object to implement local registration.

The above example can be changed to local registration:

<!DOCTYPE html>
<html>
 <body>
 <p id="app">
  <!-- 3. my-component只能在#app下使用-->
  <my-component></my-component>
 </p>
 </body>
 <script src="js/vue.js"></script>
 <script>
 // 1.创建一个组件构造器
 var myComponent = Vue.extend({
  template: &#39;<p>This is my first component!</p>&#39;
 })
 
 new Vue({
  el: &#39;#app&#39;,
  components: {
  // 2. 将myComponent组件注册到Vue实例下
  &#39;my-component&#39; : myComponent
  }
 });
 </script>
</html>
 
由于my-component组件是注册在#app元素对应的Vue实例下的,所以它不能在其它Vue实例下使用。
 
<p id="app2">
 <!-- 不能使用my-component组件,因为my-component是一个局部组件,它属于#app-->
 <my-component></my-component>
</p>
 
<script>
 new Vue({
 el: &#39;#app2&#39;
 });
 </script>

If you do this, the browser will prompt an error:

Take you through Vue.js components in minutes

Parent and child components

We can define and use other components in the component , which constitutes the relationship between parent and child components.

<!DOCTYPE html>
<html>
 <body>
 <p id="app">
  <parent-component>
  </parent-component>
 </p>
 </body>
 <script src="js/vue.js"></script>
 <script>
 
 var Child = Vue.extend({
  template: &#39;<p>This is a child component!</p>&#39;
 })
 
 var Parent = Vue.extend({
  // 在Parent组件内使用<child-component>标签
  template :&#39;<p>This is a Parent component</p><child-component></child-component>&#39;,
  components: {
  // 局部注册Child组件,该组件只能在Parent组件内使用
  &#39;child-component&#39;: Child
  }
 })
 
 // 全局注册Parent组件
 Vue.component(&#39;parent-component&#39;, Parent)
 
 new Vue({
  el: &#39;#app&#39;
 })
 
 </script>
</html>

The running results of this code are as follows:

Take you through Vue.js components in minutes

We take several steps to understand this code:

We take several steps to understand this code:

var Child = Vue.extend(…)定义一了个Child组件构造器
var Parent = Vue.extend(…)定义一个Parent组件构造器
components: { ‘child-component&#39;: Child },将Child组件注册到Parent组件,
并将Child组件的标签设置为child-component。
template :&#39;<p>This is a Parent component</p>
<child-component></child-component>&#39;,在Parent组件内以标签的形式使用Child组件。
Vue.component(‘parent-component&#39;, Parent) 全局注册Parent组件

Use tags to render Parent in the page The content of the component, while the content of the Child component is also rendered

Take you through Vue.js components in minutes

The Child component is registered in the Parent component, and it can only be used in the Parent component. To be precise: child components can only be used in the Parent component. used in template.

Please note that the following two ways of using sub-components are wrong:

1. Use

<p id="app">
 <parent-component>
 <child-component></child-component>
 </parent-component>
</p>

in the parent component as a child tag


Why is this method invalid? Because when a child component is registered to a parent component, Vue.js will compile the template of the parent component, and the content of the template has already determined the HTML that the parent component will render.

parent-component is equivalent to runtime. Some of its child tags will only be executed as ordinary HTML. child-component is not a standard HTML tag and will be directly ignored by the browser.

2. Use the child component

<p id="app">
 <parent-component>
 </parent-component>
 <child-component>
 </child-component>
</p>

outside the parent component tag to run this code, the browser will prompt the following error

Take you through Vue.js components in minutes

Syntax sugar for component registration

The above component registration method is a bit cumbersome, Vue.js simplifies it This process provides registration syntax sugar.

Use Vue.component() to create and register components directly:

// 全局注册,my-component1是标签名称
Vue.component(&#39;my-component1&#39;,{
 template: &#39;<p>This is the first component!</p>&#39;
})
 
var vm1 = new Vue({
 el: &#39;#app1&#39;
})

The first parameter of Vue.component() is the label name, and the second parameter is an option object. Use the template attribute of the option object to define the component template .
Using this method, Vue will automatically call Vue.extend() behind the scenes.

Implement local registration in the components attribute of the options object:

var vm2 = new Vue({
 el: &#39;#app2&#39;,
 components: {
 // 局部注册,my-component2是标签名称
 &#39;my-component2&#39;: {
  template: &#39;<p>This is the second component!</p>&#39;
 },
 // 局部注册,my-component3是标签名称
 &#39;my-component3&#39;: {
  template: &#39;<p>This is the third component!</p>&#39;
 }
 }
})


Use script or template tag

尽管语法糖简化了组件注册,但在template选项中拼接HTML元素比较麻烦,这也导致了HTML和JavaScript的高耦合性。 
庆幸的是,Vue.js提供了两种方式将定义在JavaScript中的HTML模板分离出来

使用script标签

<!DOCTYPE html>
<html>
 <body>
 <p id="app">
  <my-component></my-component>
 </p>
 
 <script type="text/x-template" id="myComponent">
  <p>This is a component!</p>
 </script>
 </body>
 <script src="js/vue.js"></script>
 <script>
 
 Vue.component(&#39;my-component&#39;,{
  template: &#39;#myComponent&#39;
 })
 
 new Vue({
  el: &#39;#app&#39;
 })
 
 </script>
</html>


template选项现在不再是HTML元素,而是一个id,Vue.js根据这个id查找对应的元素,然后将这个元素内的HTML作为模板进行编译。 

Take you through Vue.js components in minutes

注意:使用script标签时,type指定为text/x-template,意在告诉浏览器这不是一段js脚本,浏览器在解析HTML文档时会忽略script标签内定义的内容。 

Take you through Vue.js components in minutes

使用template标签 

如果使用template>标签,则不需要指定type属性。

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title></title>
 </head>
 <body>
 <p id="app">
  <my-component></my-component>
 </p>
 
 <template id="myComponent">
  <p>This is a component!</p>
 </template>
 </body>
 <script src="js/vue.js"></script>
 <script>
 
 Vue.component(&#39;my-component&#39;,{
  template: &#39;#myComponent&#39;
 })
 
 new Vue({
  el: &#39;#app&#39;
 })
 
 </script>
</html>

在理解了组件的创建和注册过程后,我建议使用script>或template>标签来定义组件的HTML模板。 
这使得HTML代码和JavaScript代码是分离的,便于阅读和维护。 
另外,在Vue.js中,可创建.vue后缀的文件,在.vue文件中定义组件,这个内容我会在后面的文章介绍

组件的el和data选项

传入Vue构造器的多数选项也可以用在 Vue.extend() 或Vue.component()中,不过有两个特例: data 和el。 
Vue.js规定:在定义组件的选项时,data和el选项必须使用函数。

下面的代码在执行时,浏览器会提出一个错误

Vue.component(&#39;my-component&#39;, {
 data: {
 a: 1
 }
})

   Take you through Vue.js components in minutes

另外,如果data选项指向某个对象,这意味着所有的组件实例共用一个data。 
我们应当使用一个函数作为 data 选项,让这个函数返回一个新对象:

Vue.component(&#39;my-component&#39;, {
 data: function(){
 return {a : 1}
 }
})

  

使用props

组件实例的作用域是孤立的。这意味着不能并且不应该在子组件的模板内直接引用父组件的数据。可以使用 props 把数据传给子组件。

props基础示例 
下面的代码定义了一个子组件my-component,在Vue实例中定义了data选项。

var vm = new Vue({
 el: &#39;#app&#39;,
 data: {
 name: &#39;keepfool&#39;,
 age: 28
 },
 components: {
 &#39;my-component&#39;: {
  template: &#39;#myComponent&#39;,
  props: [&#39;myName&#39;, &#39;myAge&#39;]
 }
 }
})

为了便于理解,你可以将这个Vue实例看作my-component的父组件。 
如果我们想使用父组件的数据,则必须先在子组件中定义props属性,也就是props: [‘myName', ‘myAge']这行代码。

定义子组件的HTML模板:

 <template id="myComponent">
 <table>
 <tr>
  <th colspan="2">
  子组件数据
  </th>
 </tr>
 <tr>
  <td>my name</td>
  <td>{{ myName }}</td>
 </tr>
 <tr>
  <td>my age</td>
  <td>{{ myAge }}</td>
 </tr>
 </table>
</template>

将父组件数据通过已定义好的props属性传递给子组件:

<p id="app">
 <my-component v-bind:my-name="name" v-bind:my-age="age"></my-component>
</p>

注意:在子组件中定义prop时,使用了camelCase命名法。由于HTML特性不区分大小写,camelCase的prop用于特性时,需要转为 kebab-case(短横线隔开)。例如,在prop中定义的myName,在用作特性时需要转换为my-name。

这段程序的运行结果如下: 


Take you through Vue.js components in minutes

父组件是如何将数据传给子组件的呢?相信看了下面这图,也许你就能很好地理解了。

Take you through Vue.js components in minutes

在父组件中使用子组件时,通过以下语法将数据传递给子组件:

<child-component v-bind:子组件prop="父组件数据属性"></child-component>

prop的绑定类型

单向绑定 

既然父组件将数据传递给了子组件,那么如果子组件修改了数据,对父组件是否会有所影响呢? 
我们将子组件模板和页面HTML稍作更改:

<p id="app">
 
 <table>
  <tr>
   <th colspan="3">父组件数据</td>
  </tr>
  <tr>
   <td>name</td>
   <td>{{ name }}</td>
   <td><input type="text" v-model="name" /></td>
  </tr>
  <tr>
   <td>age</td>
   <td>{{ age }}</td>
   <td><input type="text" v-model="age" /></td>
  </tr>
 </table>
 
 <my-component v-bind:my-name="name" v-bind:my-age="age"></my-component>
</p>
 
<template id="myComponent">
 <table>
  <tr>
   <th colspan="3">子组件数据</td>
  </tr>
  <tr>
   <td>my name</td>
   <td>{{ myName }}</td>
   <td><input type="text" v-model="myName" /></td>
  </tr>
  <tr>
   <td>my age</td>
   <td>{{ myAge }}</td>
   <td><input type="text" v-model="myAge" /></td>
  </tr>
 </table>
</template>

运行这个页面,我们做两个小试验: 

1. 在页面上修改子组件的数据 

Take you through Vue.js components in minutes

修改了子组件的数据,没有影响父组件的数据。 

2. 在页面上修改父组件的数据 

Take you through Vue.js components in minutes

修改了父组件的数据,同时影响了子组件。 

prop默认是单向绑定:当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意修改了父组件的状态

双向绑定 

可以使用.sync显式地指定双向绑定,这使得子组件的数据修改会回传给父组件。

Take you through Vue.js components in minutes

单次绑定 

可以使用.once显式地指定单次绑定,单次绑定在建立之后不会同步之后的变化,这意味着即使父组件修改了数据,也不会传导给子组件。

Take you through Vue.js components in minutes

示例

为了尽快消化这些知识,我们来做一个小示例吧。

<!DOCTYPE html>
<html>
 
 <head>
  <meta charset="UTF-8">
  <title></title>
  <link rel="stylesheet" href="styles/demo.css" />
 </head>
 
 <body>
  <p id="app">
   <p id="searchBar">
    Search <input type="text" v-model="searchQuery" />
   </p>
   <simple-grid :data="gridData" :columns="gridColumns" :filter-key="searchQuery">
   </simple-grid>
  </p>
 
  <template id="grid-template">
   <table>
    <thead>
     <tr>
      <th v-for="col in columns">
       {{ col | capitalize}}
      </th>
     </tr>
    </thead>
    <tbody>
     <tr v-for="entry in data | filterBy filterKey">
      <td v-for="col in columns">
       {{entry[col]}}
      </td>
     </tr>
    </tbody>
   </table>
  </template>
 
 </body>
 <script src="js/vue.js"></script>
 <script>
  Vue.component(&#39;simple-grid&#39;, {
   template: &#39;#grid-template&#39;,
   props: {
    data: Array,
    columns: Array,
    filterKey: String
   }
  })
 
  var demo = new Vue({
   el: &#39;#app&#39;,
   data: {
    searchQuery: &#39;&#39;,
    gridColumns: [&#39;name&#39;, &#39;age&#39;, &#39;sex&#39;],
    gridData: [{
     name: &#39;Jack&#39;,
     age: 30,
     sex: &#39;Male&#39;
    }, {
     name: &#39;Bill&#39;,
     age: 26,
     sex: &#39;Male&#39;
    }, {
     name: &#39;Tracy&#39;,
     age: 22,
     sex: &#39;Female&#39;
    }, {
     name: &#39;Chris&#39;,
     age: 36,
     sex: &#39;Male&#39;
    }]
   }
  })
 </script>
 
</html>

   


除了以上介绍的知识点,这个示例还用到了两个知识点: 

1. prop验证

props: {
 data: Array,
 columns: Array,
 filterKey: String
}

   


这段代码表示:父组件传递过来的data和columns必须是Array类型,filterKey必须是字符串类型。 
更多prop验证的介绍,请参考:官方文档prop验证

2. filterBy过滤器 
可以根据指定的字符串过滤数据。 

Take you through Vue.js components in minutes

总结

使用组件的前提是创建并注册组件,本篇文章详细介绍了组件从创建到使用的步骤,并介绍了几种不同的方式去创建和注册组件;然后介绍了组件的props选项,它用于将父组件的数据传递给子组件,最后我们用一个小的示例演示了这些知识点。

相关文章:

图文详解Vue.js开发环境快速搭建方法

使用vue.js编写好玩的拼图小游戏实例代码

使用require.js+vue开发微信上传图片组件方法

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Vue常见面试题汇总(附答案解析)Vue常见面试题汇总(附答案解析)Apr 08, 2021 pm 07:54 PM

本篇文章给大家分享一些Vue面试题(附答案解析)。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

5 款适合国内使用的 Vue 移动端 UI 组件库5 款适合国内使用的 Vue 移动端 UI 组件库May 05, 2022 pm 09:11 PM

本篇文章给大家分享5 款适合国内使用的 Vue 移动端 UI 组件库,希望对大家有所帮助!

vue中props可以传递函数吗vue中props可以传递函数吗Jun 16, 2022 am 10:39 AM

vue中props可以传递函数;vue中可以将字符串、数组、数字和对象作为props传递,props主要用于组件的传值,目的为了接收外面传过来的数据,语法为“export default {methods: {myFunction() {// ...}}};”。

手把手带你利用vue3.x绘制流程图手把手带你利用vue3.x绘制流程图Jun 08, 2022 am 11:57 AM

利用vue3.x怎么绘制流程图?下面本篇文章给大家分享基于 vue3.x 的流程图绘制方法,希望对大家有所帮助!

如何覆盖组件库样式?React和Vue项目的解决方法浅析如何覆盖组件库样式?React和Vue项目的解决方法浅析May 16, 2022 am 11:15 AM

如何覆盖组件库样式?下面本篇文章给大家介绍一下React和Vue项目中优雅地覆盖组件库样式的方法,希望对大家有所帮助!

聊聊vue指令中的修饰符,常用事件修饰符总结聊聊vue指令中的修饰符,常用事件修饰符总结May 09, 2022 am 11:07 AM

本篇文章带大家聊聊vue指令中的修饰符,对比一下vue中的指令修饰符和dom事件中的event对象,介绍一下常用的事件修饰符,希望对大家有所帮助!

通过9个Vue3 组件库,看看聊前端的流行趋势!通过9个Vue3 组件库,看看聊前端的流行趋势!May 07, 2022 am 11:31 AM

本篇文章给大家分享9个开源的 Vue3 组件库,通过它们聊聊发现的前端的流行趋势,希望对大家有所帮助!

react与vue的虚拟dom有什么区别react与vue的虚拟dom有什么区别Apr 22, 2022 am 11:11 AM

react与vue的虚拟dom没有区别;react和vue的虚拟dom都是用js对象来模拟真实DOM,用虚拟DOM的diff来最小化更新真实DOM,可以减小不必要的性能损耗,按颗粒度分为不同的类型比较同层级dom节点,进行增、删、移的操作。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!