IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> Vue.js第三篇:组件和路由 -> 正文阅读

[JavaScript知识库]Vue.js第三篇:组件和路由

一、组件(最基本的能力)

1、vue组件的定义

在页面引入的组件同时也是Vue的实例(如:<mycom1></mycom1>

  • 什么是模块化:模块化从代码角度出发,分析项目,把项目中功能类似的代码抽离为一个个小的模块,为了以相同的方式去封装模块,于是就创造了模块化的规范(CommonJS规范)
  • 优点:方便项目的开发,方便后期的维护和扩展 ,提高开发效率
  • 什么是组件化:从UI的角度出发,把页面上有重用性的UI结构和样式,单独抽离出来,封装为一个单独的组件(封装的是HTML元素),每个组件是一个自定义的元素
  • 优点:随着项目的发展,组件会越来越多,今后一个界面的UI几乎都可以从现成的组件拼接出来,方便项目的开发和维护
  • 注意:组件也有自己的生命周期函数,这些函数与vm实例的生命周期一致
  • 最常用.vue文件来使用组件(单独一个组件文件,实现组件化)

2、全局组件定义的方式

第一种:

(1)使用Vue.component注册一个组件:

// Vue.component的第二个参数,即接收一个组件的构造函数,也接收一个对象
Vue.component('mycom2',{
	template:'<h2>这是直接使用Vue.component创建出的组件</h2>'
});

(2)把注册好的全局组件标签以标签的形式引入到页面中

<div id="app">
<!-- 如何引入一个全局的Vue组件?直接把组件的名称,以标签的形式,放到页面中 -->
    <mycom1></mycom1>
</div>
第二种:

(1)使用template标签定义一个模板的代码结构:

<!-- 使用Vue提供的template标签,可以定义组件的UI模板结构 -->
<template id="tmpl">
    <h3>哈哈哈,这是在外界定义的组件UI结构</h3>
</template>

注意:

  • template标签应该放在与id='app’的盒子平级的地方
  • template如果放在#app里面,则组件会被注册两次,元素会被渲染两次
  • 如果直接写为下面这样,则没有效果(因为组件已经不在Vue实例vm控制的区域内)
<mycom3></mycom3>
<template id="tmpl">
    <h3>哈哈哈,这是在外界定义的组件UI结构</h3>
</template>

(2)使用Vue.component注册组件:

Vue.component('mycom3',{
    template:'#tmpl'
})

(3)把注册好的全局组件标签以标签的形式引入到页面中

3、定义私有组件

(1)在Vue实例中的定义私有组件(包含组件的名称和组件的结构):

components:{  // 定义实例中的私有组件  包含组件的名称和组件的结构
    'mycom4':{
        template:"<h6>这是定义的私有组件</h6>"
    }
}

(2)把注册好的全局组件标签以标签的形式引入到页面中

4、在组件中定义私有数据和方法(组件中展示数据和响应事件)

Vue.component('mycom',{
     template:"<h3 v-on:click='show'>这是自定义的组件{{msg}}</h3>",
     data:function(){ 
         return {
             msg:'hhh'
         }
     },
     methods:{
         show(){
             console.log('触发了组件的show方法');
         }
     }
})

注意:

  • 添加data属性时,data必须定义为function且必须返回一个对象
  • 为什么必须定义成function呢?
    因为这样的话,每当我们在页面中引用一次组件,必须会先调用这个data:function,从而得到一个当前组件私有的数据对象(保证每个组件的data是私有的)
  • 为什么必须返回一个对象?
    每创建一个实例时调用function,返回一个新对象,新对象与之前创建的实例指向的对象无关系。如果返回的是在全局定义的对象,则每次创建的实例都会指向这个对象,即共用一个返回对象,其中一个实例的指向的对象的值改变时,所有实例指向的对象的值都会随之改变(数据联动)

5、组件的切换

1.两个组件的简单切换:
使用v-ifv-else、标识符、布尔值结合实现两个组件的切换
2.多个组件的切换

6、父组件与子组件传值问题

1.父组件向子组件传递普通数据:

(1)把要传递给子组件的数据作为自定义属性,通过v-bind绑定到子组件身上:

<com1 :msg="parentMsg"></com1>

(2)在子组件中不能直接使用父组件传递过来的数据,需要使用props将数据接收一下:

// 要传递的数据:
data:{
     parentMsg:"哈哈哈,你是想笑死我,然后继承我的蚂蚁花呗吗?"
},
components:{
     'com1':{   // 在Vue中默认子组件无法直接获取父组件中的数据
         template:`<div>
             <h3>这是子组件中的标题{{msg}}</h3>
             </div>`,
         // 在数组中定义一下msg
         props:['msg']   // 在Vue中只有props是数组,其他以-s结尾的是对象
     }
}

注意:

  • 在接收父组件传递过来props时候,接受的名称一定要和父组件传递过来的自定义属性名称保持一致

2.父组件向子组件传递对象:

  • props:['msgobj']接收

3.父组件向子组件传递方法:

  • this.$emit('func')接收

注意:

  • 如果要向子组件传递data中的数据,则使用属性绑定的形式v-bind
  • 如果要向子组件传递methods中的数据,则使用事件绑定的形式v-on

4.子组件向父组件传值:

子组件向父组件传值,本质上,还是调用了父组件传递过来的方法(show方法),只不过,子组件在调用的时候,把数据当作参数传给了这个方法(show方法)
(1)把要传递给子组件的方法作为事件,通过v-on绑定到子组件身上:

<com1 @func='show'></com1>  
<!--func是随便取的名字-->

(2)为子组件添加自己的触发事件,并传值给父组件:

// 父组件要传递给子组件的方法:
methods:{
    show(){
        console.log("有人调用了父组件中的show方法");
    }
},
components:{
    'com1':{
         template:`<div>
         <input type='button' value='点击子组件' @click="btnClick">
         </div>`,
		 data:function(){
			return{sonMsg:"这是子组件中的值"}
		 }
         methods:{
             	this.$emit('func',sonMsg); // 第二个位置后面的是子组件向父组件传递的值
         	}
     	}
    }
}

(3)父组件接收这个参数(值):

data:{
   msgFromSon:''
},
methods:{
   show(arg1){
      // 把子组件传递过来的数据,保存到父组件的data中
      this.msgFromSon = arg1;
      console.log(this.msgFromSon);
   }
},

5.在Vue组件中data和props的区别:

  • 1、data在组件要定义成function并返回一个对象
  • 2、props在组件中定义成数组,数组的值都是字符串名,表示父组件传递过来的数据
  • 3、props的数据不要直接拿来修改,如果想要修改,必须在data上重新顶一个属性,然后把属性的值从this.props拿过来修改
  • 4、data上的数据都是组件私有的,data上的数据都是可读可写的
  • 5、props上的数据都是外界传过来的数据,只能读不能写

二、路由

1、什么是路由?

  • 1、对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源
  • 2、对于单页面的程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容,所以,单页面程序中的页面跳转主要用hash实现
  • 3、在单页面程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由)
  • 4、前端路由就是根据不同的hash地址展示不同的组件
  • 5、后短路由:把后端地址URL地址与处理函数之间做一层对应关系
  • 6、#叫做hash,不会刷新页面,也不会发起新的HTTP请求,只是实现客户端页面的定位的(因为#后面的值不会传给服务端)
  • 7、#可以修改浏览器端的历史访问记录

2、Vue中的路由:v-router

路由的基本使用:
(1)在导入vue包后导入vue-router的包:

<script src="./lib/vue-router-v3.0.1.js"></script>

(2)创建对应的组件:

const login = {
    template:'<h3>登陆组件</h3>'
}
const reg = {
    template:'<h3>注册组件</h3>'
}

注意:

  • 不能再利用之前的方法创建组件了,因为之前创建的组件的组件名仅限于以标签的形式引入页面中,不能用于匹配路由规则,所以把对象单独拎出来

(3)创建路由对象:

const router = new VueRouter({
    routes:[
       {path:"/login", component:login},  // 路由规则
       {path:"/reg", component:reg}  
    ]
})

注意:

  • routes:是固定属性,表示路由规则数组----把hash值和组件做对应关系,且每个对象都表示一个路由规则
  • 对象中的属性:path 表示要匹配的hash值,component 表示对应的hash要展示的组件对象
  • component的属性不能传字符串,只能传一个对象
  • 匹配到的路由组件如果想要展示在页面上,需要在页面上放一个标签router-view(路由的坑)

(4)将路由对象挂载在Vue实例中
(5)利用路由的坑(容器),将对应的路由组件填到坑中:

<div id="app">
        <router-link to="/login">登录</router-link>
        <router-link to="/reg">注册</router-link>
        <router-view></router-view>
</div>

注意:

  • router-link:路由链接,默认渲染为a标签,也有tag属性
  • router-view:默认不会被渲染为元素

总结:
路由匹配过程:点击不同的路由标签修改hash值,hash值被修改后,被路由规则监听到,然后匹配对应的路由规则
路由的目的:监听hash值的改变,根据路由规则,匹配对应的路由规则,展示对应的路由组件

3、在路由中传参

(1)query传参:优点:不需要修改路由规则

<router-link to="/login?id=10">登录</router-link>

获取参数:

template:'<h3>登陆组件----{{$route.query.id}}</h3>',

(2)/ 传参:需要修改路由规则,与node的express的传参和获取参数一致

<router-link to="/login/10/zs">登录</router-link>

修改路由规则:

{path:'/login/:id/:name', component: login}

获取参数:

template:'<h3>登陆组件----{{$route.params.id}}----{{$route.params.name}}</h3>',

(3)/传参时为了方便使用props获取参数:

在组件中使用$route会使参数和对应的路由形成高度的耦合
使用props解耦:

const login = {
    props:['id','name'],
    template:'<h3>登陆组件----{{id}}----{{name}}</h3>',
}
const router = new VueRouter({
    routes:[
        {path:'/login/:id/:name', component:login, props:true},  // 此写法与express完全一致

4、vue-router的重点内容

  • v-router是实现前端路由的
  • 什么是前端路由:根据不同的hash地址,在页面上切换不同的组件(hash地址和组件的对应关系)
  • 什么是后端路由:是URL地址和处理函数之间的对应关系
  • 前端路由的目的:为了做单页面应用程序(Single Page Application)
  • 学习前端框架的主要目的:就是利用这些现成的框架,方便我们快速进行单页面程序的开发【实现单页面应用程序的基本前提:要有vue的路由、组件】

5、使用路由规则的children属性实现路由和组件的嵌套

实现路由组件的嵌套:

(1)在父路由的组件中创建子路由链接和子路由容器

const account = {
   template:`<div class='account'>
      <h1>这是Account账号组件</h1>

      <!--创建子路由链接-->
      <router-link to="/account/login">登录</router-link>  
      <router-link to="/account/reg">注册</router-link>
      <!--子路由容器-->
      <router-view></router-view>
              
</div>`
        }

(2)创建account路由规则的子路由规则:

const router = new VueRouter({
	routes:[
        {path:'/account', component:account, children:[
             {path:'login',component:login},  // account路由规则的子路由规则
             {path:'reg',component:reg},
             // 注意:使用children属性创建的路由规则。path的值前面不要加/
        ]},  // 展示账号组件的路由匹配规则
   ]
})

注意:

  • 如果账号组件和登陆组件的路由规则是平级的,则会在页面的同一个路由的容器中显示,不会形成嵌套
    如:
 routes:[
    {path:'/account',component:account},  // 展示账号组件的路由匹配规则
    {path:'/account/login',component:login},  // 展示登陆组件的路由匹配规则
  • 通过路由规则的children属性,实现路由规则的嵌套,这样,组件之间也有了嵌套关系

6、命名视图

  • 为什么需要命名视图:在之前的路由规则,当匹配带一个路由规则时,只能在页面的路由的容器中放置唯一一个组件(因为一个路径无法展示多个组件),此时需要命名视图,在一个URL地址中展示多个组件
  • 什么时候用到命名视图:当在一层路由规则中需要展示多个组件时

(1)使用components

{path:'/',components:{
     // 组件名称:组件对象
     'top':header,
     'left':sidebar,
     'right':content,
     'bottom':footer
}}

(2)在router-view中使用name属性为不同组件命名:

<!-- 路由的容器 -->
<router-view name='top'></router-view>
   <div class="container">
       <router-view name='left'></router-view>
       <router-view name='right'></router-view>
   </div>
<router-view name='bottom'></router-view>
}}

(2)在router-view中使用name属性为不同组件命名:

<!-- 路由的容器 -->
<router-view name='top'></router-view>
   <div class="container">
       <router-view name='left'></router-view>
       <router-view name='right'></router-view>
   </div>
<router-view name='bottom'></router-view>
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-11-19 17:32:40  更:2021-11-19 17:33:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 0:55:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码