Vue组件

Posted 程序员涂陌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue组件相关的知识,希望对你有一定的参考价值。


 


Vue创建组件

什么是组件

什么是组件?组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样地方功能,就可以去调用对应的组件即可。

组件化和模块化的区别:

  • 模块化:是从代码逻辑的角度进行划分的,方便代码分层开发,保证每个功能模块的只能单一;

  • 组件化:是从UI界面的角度进行划分的;前端的组件化,方便了UI组件的重用;

定义Vue组件

方式一

1、使用 Vue.extend来创建全局的Vue组件 2、通过 template属性来指定组件要展示的html结构 3、通过 Vue.component()定义全局组件 4、在HTML指定位置通过Tag标签的形式应用你的组件,组件的名称即是tag标签的名称

 
   
   
 
  1. <div id="app">

  2. <!-- 组件的名称即为对应tag标签的名称 -->

  3. <mycom1></mycom1>

  4. </div>

  5. <script>

  6. // 创建组件

  7. var com1 = Vue.extend({

  8. template: '<h3>这是使用Vue.extend 创建的组件</h3>'

  9. });

  10. // 使用Vue.component('组件的名称', 创建出来的组件模板对象),定义全局组件

  11. Vue.component('mycom1', com1);

  12. </script>

注意

  • 用 Vue.component()定义组件名称的时候有两种命名方式:1、驼峰命名: Xxx;2、 xxx。注意,使用驼峰命名时,tag标签不能使用驼峰名称,应将相应的大写字母替换为 -加小写字母,例如: Vue.component('myCom',com1),那么tag标签应为: <my-com></my-com>

方式二

 
   
   
 
  1. <!-- 组件的名称即为对应tag标签的名称 -->

  2. <mycom1></mycom1>

  3. <script>

  4. // 使用Vue.component('组件的名称', 创建出来的组件模板对象),定义全局组件

  5. Vue.component('mycom1', Vue.extend({

  6. template: '<h3>这是使用Vue.extend 创建的组件</h3>'

  7. }));

  8. </script>

方式二就像是方式一的简化版,但是注意:在 template中定义的内容只能存在一个根节点元素,即上面例子中 template中不能出现和 <h3>平级的标签。比如下面这种写法就是错误的

 
   
   
 
  1. Vue.component('mycom1', Vue.extend({

  2. template: '<h3>这是使用Vue.extend 创建的组件</h3><span></span>'

  3. }));

解决办法就是,外层嵌套一个根标签就行了:

 
   
   
 
  1. Vue.component('mycom1', Vue.extend({

  2. template: '<div><h3>这是使用Vue.extend 创建的组件</h3><span></span></div>'

  3. }));

方式三

1、javascript中仍使用 Vue.component来定义全局组件,和方式二相似,但是里面不再是 template:'HTML结构'了,而是引用一个外部标签的 id值,即 template:'id'

2、在被Vue实例控制的 app外面,定义 <templateid="id">你的HTML结构</template>>

这种方式的好处就是是就组件代码都是定义在HTML结构中的,有智能代码提示;而JavaScript中定义组件仅是写一个引用。

实例:

 
   
   
 
  1. <div id="app">

  2. <!-- 页面引用 -->

  3. </div>

  4. <template id="tmp">

  5. <!-- 比如仅存在一个根节点元素 -->

  6. <div>

  7. <h1></h1>>

  8. <h2></h2>

  9. </div>

  10. </template>

  11. //JavaScript部分

  12. Vue.component('mycom', {

  13. template: '#tmp'

  14. });

定义私有组件

除了上面讲到的定义全局组件,我们也可以定义私有组件,使用 components:{}函数。

如:

 
   
   
 
  1. <div id="app">

  2. <tem></tem>

  3. </div>

  4. <template id="tmp">

  5. <h3>这是私有组件</h3>

  6. </template>

  7. <script type="text/javascript" src="../lib/vue.js"></script>

  8. <script type="text/javascript">

  9. new Vue({

  10. el: '#app',

  11. data: {},

  12. methods: {},

  13. components: {

  14. tem: {

  15. template: '#tmp'

  16. }

  17. }

  18. });

  19. </script>

组件元素

组件的data

在组件中,同样可以有自己的data数据,但是用法和Vue实例中的data用法有所不同:

  1. 组件中的data必须是一个方法,即

 
   
   
 
  1. data: function(){ }

  1. 组件中的data方法必须返回一个Object对象

 
   
   
 
  1. data: function(){

  2. return object

  3. }

实例:

 
   
   
 
  1. <div id="app">

  2. <mycom1></mycom1>

  3. </div>

  4. <script type="text/javascript" src="../lib/vue.js"></script>

  5. <script type="text/javascript">

  6. Vue.component('mycom1', Vue.extend({

  7. data: function(){

  8. return {

  9. msg: '这是组件的data'

  10. }

  11. },

  12. template: '<h3>这是使用Vue.extend 创建的组件-- {{msg}}</h3>'

  13. }));

  14. new Vue({

  15. el: '#app',

  16. data: {},

  17. methods: {},

  18. components: {

  19. }

  20. });

  21. </script>

组件的切换

在遇到登录注册表单时,通常我们需要对两个按钮进行切换实现显示不同的表单,那么Vue中的组件切换正符合了这个功能要求。

方式一

可以使用Vue提供的 v-if和 v-else来实现两个组件间的切换,但是,仅支持切换两个组件

实例:

 
   
   
 
  1. <div id="app">

  2. <a href="#" @click.prevent="flag=true">登录</a>

  3. <a href="#" @click.prevent="flag=false">注册</a>

  4. <login v-if="flag"></login>

  5. <register v-else="flag"></register>

  6. </div>

  7. <template id="login">

  8. <h3>这是登录表单</h3>

  9. </template>

  10. <template id="register">

  11. <h3>这是注册表单</h3>

  12. </template>

  13. <script type="text/javascript" src="../lib/vue.js"></script>

  14. <script type="text/javascript">

  15. // 创建登录组件

  16. Vue.component('login', {

  17. template: '#login'

  18. });

  19. // 创建注册组件

  20. Vue.component('register', {

  21. template: '#register'

  22. })

  23. new Vue({

  24. el: '#app',

  25. data: {

  26. flag: true

  27. },

  28. methods: {}

  29. });

  30. </script>

定义 flag参数,当flag=true就显示组件,当flar=false就隐藏组件

方式二

Vue提供了 component来展示对应名称的组件。其中 component是一个占位符, :is属性,可以用来指定要展示的组件名称

实例:

 
   
   
 
  1. <div id="app">

  2. <a href="#" @click.prevent="comName='login'">登录</a>

  3. <a href="#" @click.prevent="comName='register'">注册</a>

  4. <component :is="comName"></component>

  5. </div>

  6. <template id="login">

  7. <h3>这是登录表单</h3>

  8. </template>

  9. <template id="register">

  10. <h3>这是注册表单</h3>

  11. </template>

  12. <script type="text/javascript" src="../lib/vue.js"></script>

  13. <script type="text/javascript">

  14. // 创建登录组件

  15. Vue.component('login', {

  16. template: '#login'

  17. });

  18. // 创建注册组件

  19. Vue.component('register', {

  20. template: '#register'

  21. })

  22. new Vue({

  23. el: '#app',

  24. data: {

  25. comName: 'login'

  26. },

  27. methods: {}

  28. });

  29. </script>

即使用Vue提供的 component,它能够实现自动对组件进行展示和隐藏,通过 :is='组件名称'

父子组件间传值

父组件给子组件传值

父组件给子组件传值,即实现在子组件中调用父组件中的 methods或是获取父组件中的 data.

传参数

 
   
   
 
  1. <body>

  2. <!-- 父组件实例 -->

  3. <div id="app">

  4. <!-- 子组件实例 -->

  5. <com1></com1>

  6. </div>

  7. <script type="text/javascript" src="../lib/vue.js"></script>

  8. <script type="text/javascript">

  9. new Vue({

  10. el: '#app',

  11. data: {

  12. msg: '这是父组件data值'

  13. },

  14. methods: {

  15. show(){

  16. console.log("这是父组件的show方法");

  17. }

  18. },

  19. // 子组件

  20. components: {

  21. com1: {

  22. template: '<h2>这是子组件</h2>'

  23. }

  24. }

  25. });

  26. </script>

  27. </body>

如上,当我们直接在子组件中引用父组件 data中定义的 msg数据,将上面的修改为:

 
   
   
 
  1. com1: {

  2. template: '<h2>这是子组件--{{msg}}</h2>'

  3. }

那么就会报错。所以就证实了默认在子组件中不能访问父组件中的 data或 methods

为了解决子组件获取父组件数据,Vue提供了以下方式获取:

  • 1、父组件在引用子组件的时候,通过属性绑定的方式 v-bind:,把需要传递给子组件的数据以属性绑定的形式传递到子组件内部,供子组件使用。

  • 2、在子组件中,通过 props:[]获取到父组件传递过来的数据;这样就完成了父组件向子组件传值

实例

 
   
   
 
  1. <body>

  2. <!-- 父组件实例 -->

  3. <div id="app">

  4. <!-- 子组件实例 -->

  5. <com1 :fatoson="msg"></com1>

  6. </div>

  7. <script type="text/javascript" src="../lib/vue.js"></script>

  8. <script type="text/javascript">

  9. new Vue({

  10. el: '#app',

  11. data: {

  12. msg: '这是父组件data值'

  13. },

  14. methods: {},

  15. // 子组件

  16. components: {

  17. com1: {

  18. template: '<h2>这是子组件--{{fatoson}}</h2>',

  19. props: ['fatoson']

  20. }

  21. }

  22. });

  23. </script>

  24. </body>

如上,我们在子组件实例中使用了 v-bind绑定了一个参数 fatoson,其值是: msg即在父组件data中定义的值;那么就相当于父组件的一个data数据被Vue绑定到了子组件实例中,且父组件data值的别名是 fatoson,那么在子组件中通过 props:[]属性就能获取到这个别名,然后就实现了父组件向子组件传值。需要注意以下:

  • 1、我们可以将为子组件绑定的参数名称是父组件值的别名。即此时 msg相当于 fatoson

  • 2、注意命名中若是驼峰命名,在HTML中必须用 -替换。

  • 3、注意 props是Vue为父组将向子组件传值提供的一个参数,且他是唯一的数组类型的。

  • 4、注意子组件通过 props获取到的父组件的值是只读的,即不能修改。

传方法

上面讲了父组件给子组件传递普通的参数,下面我们将了解到父组件怎样给子组件传递方法。

 
   
   
 
  1. <body>

  2. <!-- 父组件实例 -->

  3. <div id="app">

  4. <!-- 子组件实例 -->

  5. <com1 @open="show"></com1>

  6. </div>

  7. <template id="tmp">

  8. <div>

  9. <h2>这是子组件</h2>

  10. <input type="button" @click="myclick" value="子组件按钮,点击触发父组件方法"/>

  11. </div>

  12. </template>

  13. <script type="text/javascript" src="../lib/vue.js"></script>

  14. <script type="text/javascript">

  15. new Vue({

  16. el: '#app',

  17. data: {

  18. msg: '这是父组件data值'

  19. },

  20. methods: {

  21. show(){

  22. console.log("这是父组件的show方法");

  23. }

  24. },

  25. // 子组件

  26. components: {

  27. com1: {

  28. template: '#tmp',

  29. props: ['fatoson'],

  30. methods: {

  31. myclick(){

  32. this.$emit('open');

  33. }

  34. }

  35. }

  36. }

  37. });

  38. </script>

  39. </body>

解释:

  • 1、这里子组件的 template数据引用外部的 <template></template>中的HTML代码。

  • 2、与传值思路相同,传递方法也需要在子组件实例中使用 v-on即 @来绑定方法,方法别名 @open,方法的值是 show是在父组件中定义的方法名。

  • 3、与传值思路相同,传值使用了 props来接受传递的参数,那么传方法提供了 $emit()元素

综合

上面讲的父组件向子组件传递方法,那么既然是方法就肯定能传递方法参数。我们只需要在父组件方法中指定值名称即可

 
   
   
 
  1. @子组件接收的方法别名="父组件中的方法(父组件中的参数值或data)"

 
   
   
 
  1. <body>

  2. <!-- 父组件实例 -->

  3. <div id="app">

  4. <!-- 子组件实例 -->

  5. <com1 @open="show(fatosonval)"></com1>

  6. </div>

  7. <template id="tmp">

  8. <div>

  9. <h2>这是子组件</h2>

  10. <input type="button" @click="myclick" value="子组件按钮,点击触发父组件方法"/>

  11. </div>

  12. </template>

  13. <script type="text/javascript" src="../lib/vue.js"></script>

  14. <script type="text/javascript">

  15. new Vue({

  16. el: '#app',

  17. data: {

  18. fatosonval: {

  19. id: '1',

  20. name: '涂陌'

  21. }

  22. },

  23. methods: {

  24. show(data){

  25. console.log(data);

  26. }

  27. },

  28. // 子组件

  29. components: {

  30. com1: {

  31. template: '#tmp',

  32. methods: {

  33. myclick(){

  34. this.$emit('open');

  35. }

  36. }

  37. }

  38. }

  39. });

  40. </script>

  41. </body>

(三)Vue组件

子组件给父组件传值

即实现在父组件中调用子组件中的方法

 
   
   
 
  1. <body>

  2. <!-- 父组件实例 -->

  3. <div id="app">

  4. <!-- 子组件实例 -->

  5. <com1 @open="show"></com1>

  6. </div>

  7. <template id="tmp">

  8. <div>

  9. <h2>这是子组件</h2>

  10. <input type="button" @click="myclick" value="子组件按钮,点击触发父组件方法"/>

  11. </div>

  12. </template>

  13. <script type="text/javascript" src="../lib/vue.js"></script>

  14. <script type="text/javascript">

  15. new Vue({

  16. el: '#app',

  17. data: {

  18. fatosonval: null

  19. },

  20. methods: {

  21. show(data){

  22. console.log(data);

  23. }

  24. },

  25. // 子组件

  26. components: {

  27. com1: {

  28. template: '#tmp',

  29. data(){

  30. return {

  31. sonval: { name: 'TyCoding', age: 19 }

  32. }

  33. },

  34. methods: {

  35. myclick(){

  36. this.$emit('open', this.sonval);

  37. }

  38. }

  39. }

  40. }

  41. });

  42. </script>

  43. </body>

之前我们实现父组件向子组件传值的时候,需要在 @open()中指定父组件中的 data,而子组件给父组件传值的时候就不需要再指定了,而是直接在调用子组件中的 open(这是父组件方法的别名),将子组件的值写进 $emit('方法别名',data参数)中即可。

(三)Vue组件

Vue获取DOM元素和组件

首先我们需要明白的就是Vue并不提倡我们操作DOM元素,Vue的宗旨就是让我们只关心业务逻辑。

那么通常我们需要获取一个如 <h2></h2>中的值,采用原生JS通常需要先为tag标签定义一个id属性,然后通过JS代码 document.getElementById('id').innterText来获取到 <h2>中的文本数据,而Vue也实现了操作原生DOM的功能:

 
   
   
 
  1. * 在需要获取的HTML标签中指定`ref`属性,其值可自定义。

  2. * Vue实例中,使用`this.$refs.指定的值`来获取DOM对象,进行操作。

 
   
   
 
  1. <h2 ref="h2">这是h2的文本数据</h2>>

  2. console.log(this.$refs.h2.innerText);

通过$refs还能轻易获取子组件中的data和methods数据

首先需要为子组件引用实例定义 ref="com1"属性,然后在Vue实例中通过 this.$refs.com1即可获取子组件中的所有对象,即还能获取到子组件中的 data和 methods

实例:

 
   
   
 
  1. <body>

  2. <!-- 父组件实例 -->

  3. <div id="app">

  4. <!-- 子组件实例 -->

  5. <com1 ref="com1"></com1>

  6. <input type="button" @click="show" value="获取元素">

  7. <h2 ref="h2">这是父组件</h2>

  8. </div>

  9. <template id="tmp">

  10. <div>

  11. <h2>这是子组件</h2>

  12. </div>

  13. </template>

  14. <script type="text/javascript" src="../lib/vue.js"></script>

  15. <script type="text/javascript">

  16. new Vue({

  17. el: '#app',

  18. methods: {

  19. show(){

  20. // console.log(this.$refs.h2.innerText);

  21. // console.log(this.$refs.com1); //获取子组件中的所有实例对象

  22. // console.log(this.$refs.com1.sonval); //获取子组件中定义的data值

  23. console.log(this.$refs.com1.sonshow()); //调用子组件中定义的方法

  24. }

  25. },

  26. // 子组件

  27. components: {

  28. com1: {

  29. template: '#tmp',

  30. data() {

  31. return {

  32. sonval: { name: 'TyCoding', age: 19 }

  33. }

  34. },

  35. methods: {

  36. sonshow() {

  37. console.log('子组件的方法');

  38. }

  39. }

  40. }

  41. }

  42. });

  43. </script>

  44. </body>





/ 往期推荐 /






END

     







以上是关于Vue组件的主要内容,如果未能解决你的问题,请参考以下文章

vue3中的fragment(片段)组件

vue.js 2 - 将单个文件组件的 html 片段提取到独立文件中

Vue组件之全局组件与局部组件

Vue组件之全局组件与局部组件

vue-个人学习----组件

vue视频学习笔记05