Vue
12. Vue中组件(Component)
12.1 组件作用
组件作用:
用来减少Vue实例对象中代码量,日后在使用Vue开发过程中,可以根据 不能业务功能将页面中划分不同的多个组件,然后由多个组件去完成整个页面的布局,便于日后使用Vue进行开发时页面管理,方便开发人员维护。
12.2 组件使用
12.2.1 全局组件注册
说明:全局组件注册给Vue实例,日后可以在任意Vue实例的范围内使用该组件
他将全局组件注册到vue.js中
//1.全局组件注册
//Vue的component属性:(参数1:组件名称 ; 参数2:{组件配置对象} template属性:用来书写组件的html代码(注意:在template中必须只存放一个容器)
Vue.component('login',{
template:'<div><h1>用户登录</h1></div>'
})
//2.使用全局组件 在Vue实例范围内【组件名 + 标签】
<login></login>
- 页面效果↓
# 注意:
1.Vue.component用来开发全局组件 参数1: 组件的名称 参数2: 组件配置{} template:''用来书写组件的html代码 template中必须有且只有一个root元素
2.使用时需要在Vue的作用范围内根据组件名使用全局组件
3.如果在注册组件过程中使用 【驼峰命名】组件的方式
在使用组件时,必须将驼峰的所有单词小写加入-线进行使用
12.2.2 局部组件注册
说明:通过将组件注册给对应Vue实例中一个components属性来完成组件注册,这种方式不会对Vue实例造成累加
- 第一种开发方式
let login = {
template:'<div><h1>用户登录<h1></div>'
}
const app = new Vue({
el: "#app",
data: {
},
methods: {
},
components:{
//用来注册局部组件
login:login //注册局部组件
}
});
//局部组件使用 在Vue实例范围内
<login></login>
-
第二种开发方式
//1.声明局部组件模板 template 标签 注意:【在Vue实例作用范围外声明】 <template id="loginTemplate"> <h1>用户登录</h1> </template> //2.定义变量用来保存模板配置对象 let login ={ //具体局部组件名称 template:'#loginTemplate' //通过使用id选择器,使用自定义template标签选择器即可 }; //3.注册组件 const app = new Vue({ el: "#app", data: { }, methods: { }, components:{ //用来注册局部组件 login:login //注册局部组件 //如果组件名和保存模板配置对象名一样,可以直接使用名字即可 //login } }); //4.局部组件使用 在Vue实例范围内 <login></login>
12.3 Prop的使用
作用:props用来给组件传递相应静态数据或者是动态数据的
12.3.1 通过在组件上声明【静态数据传递】给组件内部
<body>
<div id="app">
<!--0.5、使用组件
1、给组件上定义name属性,值为'阿昌'
-->
<login name="阿昌" age="23"></login>
</div>
<!--引入vue-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//声明一个组件配置对象
let login = {
//3、通过{
{name}}来获取,下面 通过props属性获取上面组件定义的name属性
template:"<div><h1>欢迎{
{name}},{
{age}}</h1></div>",
//2、通过props属性,通过数组,定义上面同名的name属性,用来接收
props:['name','age']
}
const app = new Vue({
el: "#app",
data: {
},
methods: {
},
components:{
login //0、注册组件; 此处组件配置对象名和组件名一样,可以省略写为一个
}
});
</script>
</body>
# 总结:
1.使用组件时可以在组件上定义多个属性以及对应数据
2.在组件内部可以使用props数组生命多个定义在组件上的属性名 日后可以在组件中通过{
{ 属性名 }} 方式获取组件中属性值
12.3.2 通过在组件上声明【动态数据传递】给组件内部
//1.声明组件模板对象
const login = {
template:'<div><h2>欢迎: {
{ name }} 年龄:{
{ age }}</h2></div>',
props:['name','age']
}
//2.注册局部组件
const app = new Vue({
el: "#app",
data: {
username:"阿昌",
age:23
},
methods: {
},
components:{
login //注册组件
}
});
//3.使用组件
<login :name="username" :age="age"></login>
//使用v-bind形式将数据绑定Vue实例中data属性,日后data属性发生变化,组件内部数据跟着变化
12.3.3 prop的单向数据流
单向数据流:所有的 prop 都使得其父子 prop 之间形成了一个**单向下行绑定**:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。—【摘自官网】
12.4 组件中定义数据和事件使用
1. 组件中定义属于组件的数据
//声明组件的配置对象
const login ={
template:"<div><h1>欢迎:{
{msg}}</h1><ul><li v-for='index,item in lists'>{
{index}} {
{item}}</li></ul></div>",
data(){
//使用data函数的方式定义组件的数据; 在template属性中通过【{
{}}插值表达式】直接获取即可
return {
msg:"hello",
lists:['java','c#',"c"]
}
}
}
2.组件中事件定义
const login ={
template:"<div><input type='button' value='点我触发组件中的事件' @click='change'></div>",
data(){
return {
name:"阿昌",
};
},
methods: {
change(){
alert(this.name); //拿到组件内部的数据
alert("触发事件");
}
}
}
# 总结
1.【组件中定义事件和直接在Vue中定义事件基本一致】 直接在组件内部对应的html代码上加入@事件名=函数名方式即可
2.在组件内部使用methods属性用来定义对应的事件函数即可,事件函数中this 指向的是当前组件的实例
12.5 向子组件中传递事件并在子组件中调用该事件
在子组件中调用传递过来的相关事件必须使用 this.$emit('函数名') 方式调用
<body>
<div id="app">
<login :name="username" @aaa="findAll"></login>
</div>
<!--引入vue-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
//组件声明
const login = {
template:"<div><h1>阿昌学vue,{
{uname}}</h1><input type='button' @click='change' value='点我触发'></div>>",
data(){
return{
uname:this.name,
}
},
props:['name'],
methods: {
change(){
//在login组件的函数change,去调用vue实例的函数
this.$emit('aaa');
}
}
}
const app = new Vue({
el: "#app",
data: {
username:"阿昌",
},
methods: {
findAll(){
alert("vue实例中定义的函数")
}
},
components: {
//组件注册
login
}
});
</script>
</body>
13.Vue中路由(VueRouter)
13.1 路由
路由:根据请求的路径按照一定的路由规则进行请求的转发从而帮助我们实现统一请求的管理
13.2 作用
用来在vue中实现组件之间的动态切换
13.3 使用路由
-
引入路由
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> //vue 路由js
-
创建组件对象
//声明组件模板 const login ={ template:"<div><h1>用户登录</h1></div>" } const register={ template:"<div><h1>用户注册</h1></div>" }
-
定义路由对象的规则
//创建路由对象 const router = new VueRouter({ routes:[ //设置路由对象的规则 //path: 请求路由的路径 //component: 绑定组件(此处绑定后,就不需要在vue实例的components属性下绑定) { path:'/login',component:login}, { path:'/register',component:register} ], });
-
将路由对象注册到vue实例
const app = new Vue({ el: "#app", data: { }, methods: { }, components: { }, router:router //设置路由对象 });
-
在页面中显示路由的组件
<!--显示路由的组件--> <router-view></router-view>
-
根据连接切换路由
<a href="#/register">点我注册</a> <a href="#/login">点我登录</a>
13.4 router-link使用
作用:用来替换我们在切换路由时使用a标签切换路由
好处:就是可以自动给路由路径加入#不需要手动加入
a标签写法:
<a href="#/register">点我注册</a>
<a href="#/login">点我登录</a>
router-link写法:省略了【#】
<!--【router-link】
好处:书写路由路径不需要写 # 了
to属性: 用来书写要去的路径
tag属性: 将这个router-link标签渲染成你想要的,如下面的button
-->
<router-link to="/register" tag="button">我要注册</router-link>
<router-link to="/login" tag="button">我要登录</router-link>
# 总结:
1.router-link 用来替换使用a标签实现路由切换 好处是不需要书写#号直接书写路由路径
2.router-link
to属性: 用来书写路由路径
tag属性:: 用来将router-link渲染成指定的标签
13.5 默认路由
作用:用来在第一次进入界面是显示一个默认的组件
const router = new VueRouter({
routes:[ //配置路由规则
// 因为默认访问的是“/”,使用设置“/”,的component属性,就可以指定默认路由地址
// { path:'/',component:login},
//redirect: 用来当访问的是默认路由 "/" 时 跳转到指定的路由展示 【推荐使用】
{
path:"/",redirect:'/register'},
{
path:"/login",component:login},
{
path:"/register",component:register},
]
});
13.6 路由中参数传递
- 第一种方式传递参数 【传统方式,通过 [?] 的形式】
-
通过?号形式拼接参数
<router-link to="/login?id=21&name=zhangsan">我要登录</router-link>
-
组件中获取参数
const login = { template:"<div><h1>用户登录,{ {this.$route.query.id}},{ {this.$route.query.name}}</h1></div>", data(){ return{ }}, methods:{ }, created(){ console.log("【id】==>"+this.$route.query.id+",【name】==>"+this.$route.query.name); } }
- 第二种方式传递参数 restful
-
通过使用路径方式传递参数
:id == {id}
<router-link to="/register/24/张三">我要注册</router-link> var router = new VueRouter({ routes:[ { path:'/register/:id/:name',component:register} //定义路径中获取对应参数 ] });
-
组件中获取参数
const register = { template:"<div><h1>用户注册,{ {this.$route.params.id}},{ {this.$route.params.name}}</h1></div>", created(){ console.log("【id】==>"+this.$route.params.id+",【name】==>"+this.$route.params.name); } };
13.7 嵌套路由
-
声明最外层和内层路由
//商品管理模版,不在vue实例范围内 <template id="product"> <div> <h1>商品管理</h1> <router-link to="/product/add">商品添加</router-link> <router-link to="/product/update">商品编辑</router-link> <!--显示组件--> <router-view></router-view> </div> </template> //声明组件模版 const product={ template:"#product" } const add={ template:"<h4>商品添加</h4>" }; const update={ template:"<h4>商品编辑</h4>" }
-
创建路由对象含有嵌套路由
通过【children属性】,指定嵌套子路由,路径关系的语义被children实现了
//定义路由对象 const router = new VueRouter({ routes:[ { path:"/product", component:product, children:[ //设置这个路由中的【嵌套路由】 { path:"add",component:add}, { path:"update",component:update}, ] }, ] });
-
注册路由对象
const app = new Vue({ el: "#app", data: { }, methods: { }, components: { }, //注册路由对象 router });
-
测试路由
<router-link to="/product">商品管理</router-link> <router-view></router-view>