携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情 \
🍁 作者:知识浅谈,CSDN签约讲师,CSDN博客专家,华为云云享专家,阿里云专家博主
📌 擅长领域:全栈工程师、爬虫、ACM算法
💒 公众号:知识浅谈
🔥 联系方式vx:zsqtcc
13.Vue中的组件(Component)
13.1组件作用
组件作用:用来减少Vue实例对象中代码量,日后在使用vue开发过程中,可以根据不能业务功能将页面中划分不同的多个组件,然后由多个组件去完成整个页面的布局,便于日后使用Vue进行开发时页面管理,方便开发人员维护。
13.2组件使用
13.2.1全局组件注册
说明:全局组件注册给vue实例,日后可以在任意Vue实例的范围内使用该组件。
就相当于把组件注册到vue.js中
//1.开发全局组件
Vue.component('login',{
template:'<div><h1>用户登录</h1></div>'
})
//2.使用全局组件,在vue实例范围内
<login></login>
# 注意
1.Vue.component用来开发全局组件,参数1:组件名称 参数二:组件配置{} template:'' 用来书写组件的html代码 template中必须有且只有一个root元素
2.使用时需要在vue的作用范围内根据组件名使用全局组件
3.如果在注册组件的过程中使用驼峰命名组件的方式,在使用组件时,比须将驼峰的所有单词小写加如-线进行使用
13.2.2局部组件注册
说明:通过将组建注册给对应的Vue实例中一个components属性来完成组件注册,这种方式不会对Vue实例造成累加
第一种开发方式:
//局部组件登录模板声明
<script>
let login={ //具体局部组件名称
template: '<div><h2></h2></div>'
};
const app = new Vue({
el: "#app",
data: {},
methods: {},
components:{ //用来注册局部组件
login:login,
}
});
</script>
//局部组件使用在vue实例范围内
<login></login>
第二种开发方式:
//声明局部组件模板 template 标签 注意:在vue实例作用范围外声明
<template id="loginTemplate">
<h1>用户登录</h1>
</template>
2.定义变量用来保存模板配置对象
let login={ //具体局部组件名称
template:'#loginTemplate' //使用自定义的template标签选择器就可以
};
3.注册组件
const app = new Vue({
el: "#app",
data: {},
methods: {},
components:{ //用来注册局部组件
login:login, //这里边写的时候可以直接使用一个login,因为组件名和上边的变量名相同
}
});
4.局部组件的使用,在Vue的实例范围内
<login></login>
13.3 Props的使用
作用:props用来给组件传递相应的静态数据或者是动态数据的
13.3.1 通过在组件上声明静态数据传递给组件内部
//1.声明组件模板配置对象
let login={ //具体局部组件(子组件)名称
template:"#loginTemplate",
props:['name','age']
};
//2.注册组件
const app = new Vue({
el: "#app",
data: {},
methods: {},
components:{ //用来注册局部组件也就是子组件
login:login,
}
});
//3.通过组件完成静态数据的传递
<login name="Layne" age="23"></login> <!--静态传值-->
# 总结
1.使用组件的时候可以在组件上定义多个属性以及对应的数据
2.在组件内部可以使用props数组声明多个定义在组件上的属性名
,之后便可以在组件中通过{{ 属性名 }}方式获取组件中属性值
13.3.2 通过在组件上声明动态数据传递给组件内部
//1.声明组件模板对象
//定义一个局部组件声明
const login={ //具体局部组件名称
template:"#loginTemplate",
props:['name']
};
//2.注册局部组件
const app = new Vue({
el:"#app",
data:{
username:"善者之道",
},
methods:{},
components:{
login //注册子组件
}
})
//3.使用组件
<login :name="username" ></login>
//使用v-bond形式将数据绑定到vue实例中data属性,组件内部数据会随着绑定的vue私立中的data属性发生变化
13.3.3 prop的单向数据流
单向数据流:所有的prop都使得其父子prop之间形成了一个**单向下行绑定** 父级prop的更新会向下流动到子组件中,但是反过来不行
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外变更父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
<div id="app">
<!--使用全局组件-->
<login :name="username"></login> <!--静态传值-->
</div>
<!--通过模板标签注册-->
<template id="loginTemplate">
<h1>用户登录:{{ name }}</h1>
</template>
<!--引入vue 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
//全局组件的注册 参数1:组件名称 参数2:组件配置对象 template:用来书写组件的html代码,(注意:在template中必须存在一个容器)
// Vue.component('login',{
// template:'<div><h1>用户登录</h1></div>'
// })
const login={ //具体局部组件名称
template:"#loginTemplate",
props:['name'],
data(){
return{
name:this.name, //把props传递过来的属性初始化给本地的name
};
},
};
const app = new Vue({
el:"#app",
data:{
username:"善者之道",
},
methods:{},
components:{
login //注册组件
}
})
</script>
解释:上边的例子中,:name绑定vue中的username,而name通过props传到组件内部,在组件内部,又通过 name:this.name,把props中的name初始化给组件本地的name。
除了在组件中的data中定义一个变量名,并把传给props的变量名赋值给data中定义的,一般不要把data中定义的变量名和props中的变量名相同。
上遍说到的单向数据流就是父级的prop更新,其子类也会随着更新,但是子类更新,父类不会跟着更新
13.4 组件中定义数据和事件的使用
1.组件中定义属于组件的数据
const login={ //具体局部组件名称
template:"#loginTemplate",
props:['name'],
data(){
return{
name:this.name, //把props传递过来的属性初始化给本地的name
msg:"hello",
lists:["asd","asd"], //列表
};
},
};
2.组件中事件的定义
const login={ //具体局部组件名称
template:"#loginTemplate",
props:['name'],
data(){
return{
name:this.name, //把props传递过来的属性初始化给本地的name
msg:"hello",
lists:["asd","asd"], //列表
};
},
methods:{
change(){
alert("asdasd");
}
}
};
# 总结
1.组件中定义事件和直接在vue中定义事件基本一致 直接在组件内部对应的html代码上加如@事件名=函数名的方式即可
2.在组件内部使用methods属性用来定义对应的事件函数即可,事件函数中this指向当前组件的实例
13.5 向子组件中传递事件并在在子组件中调用该事件
在子组件中调用传递过来的相关事件必须使用this.$emit('函数名')方式调用
//1.声明组件
const login={ //具体局部组件名称
template:"#loginTemplate",
props:['name'],
data(){
return{
name:this.name, //把props传递过来的属性初始化给本地的name
msg:"hello",
lists:["asd","asd"], //列表
};
},
methods:{
change(){ //这个函数是在模板中通过触发事件调用这个函数,然后通过调用$emit(find)调用和find绑定的其他组件中函数
alert("asdasd");
//调用vue实例中的函数或者其他组件中的函数
this.$emit('find');
}
}
};
//2.注册组件
const app = new Vue({
el:"#app",
data:{
username:"善者之道",
},
methods:{
findAll(){ //定义了一个事件函数,将这个函数传递给子组件
alert("唐三");
}
},
components:{
login:login //注册组件
}
})
//3.使用组件
<login :name="username" @find="findAll"></login>
//在组件中内部使用 this.$emit('find')
<!--向子组件中传递事件并在子组件中调用该事件,注意传递的事件名字和绑定到组件中的事件名不应相同-->
14.Vue中的路由(VueRouter)
14.1 路由
路由:根据请求的路径按照一定的路由规则进行请求的转发,从而帮助我们实现统一请求的管理。,主要是用于进行动态的切换组件
14.2 作用
用来在vue中实现组件之间的动态切换
14.3 路由的使用
-
引入路由
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> -
创建组件对象
//声明组件模板 const login={ template:'<h1>Login</h1>', }; const register={ template:'<h1>Register</h1>', }; -
定义路由对象的规则
//创建路由对象 const router = new VueRouter({ routes:[ {path:'/login',component:login}, //path:路由路径,component:路径对应的组件 {path:'/register',component:register}, ] }); -
将路由对象注册到vue实例
const app = new Vue({ el: "#app", data: {}, methods: {}, router:router, /*将router路由对象注册到vue实例*/ }); -
在页面显示路由组件
<a href="#/login">点我登录</a> <!--通过超链接更改地址即可触发对应的路由来显示对应的组件--> <a href="#/register">点我注册</a> <!--显示路由的组件--> <router-view></router-view> -
根据链接切换路由
<a href="#/login">点我登录</a> <!--通过超链接更改地址即可触发对应的路由来显示对应的组件--> <a href="#/register">点我注册</a> <!--注意那个#,在前端中叫做hash路由的意思-->
14.4 router-link的使用
<router-link to="/login">登录</router-link> <!--相比与a标签 就是不用写#,会自动加入-->
<router-link to="/register">注册</router-link>
<!--router-link 会自动渲染成超链接的属性-->
<!--但是可以通过tag进行设置渲染成的属性,但是无论什么都绑定了单击事件-->
# 总结
1. router-link用来替換使用a标签实现路由切換好处是不需要书写#号直接书写路由路径
2. router-link to属性用来书写路由路径tag属性:用来将 router-1ink渲染成指定的标签
14.5 默认路由
用来第一次进入页面时,显示的一个默认的组件
routes: [
// {path: '/',component: login}, /*默认路由*/
{path: '/',redirect:'/login'}, //用来当访问默认路由 / shi'hou台哦站到指定路由展示
{path:'/login',component:login},
{path:'/register',component:register},
]
14.6 路由中参数传递
- 第一种方式传递
-
通过?号形式拼接参数
<router-link to="/login?id=21" tag="button">登录</router-link> -
组件中获取参数
const login={ template:'<h1>login {{ this.$route.query.id }}</h1>', data(){return{ }}, created(){ console.log("--------"+this.$route.query.id) } }; const register={ template: '<h1>register</h1>', };
- restful方式的传递
-
通过使用路径方式传递参数
<router-link to="/register/11111">注册</router-link> const router = new VueRouter({ routes: [ {path:'/register/:id',component:register}, ] }); -
组件中获取参数
const register={ template: '<h1>register</h1>', created(){ console.log(this.$route.params.id); }, };# 总结 1.使用?参数=值这样的形式传递的时候,使用this.$route.query.参数名获取传递的对应的值 2.使用restful格式传递参数的时候,使用this.$route.params.参数名获取传递的对应的值
14.7 嵌套路由
-
声明最外层和最内层的路由
//声明组件模板 const login = { template: '#login', }; const test = { template: '<h1>register</h1>' }; <!--定义模板--> <template id="login"> <div> <h1>商品管理</h1> <router-link to="/login/test" >注册</router-link> <router-view></router-view> </div> </template> -
创建路由对象含有嵌套路由
const router = new VueRouter({ routes:[ { path:'/login', component: login, children:[ {path:'test',component: test}, /*这个就代表的是在login的下*/ ] }, ] }); -
注册路由对象
const app = new Vue({ el: "#app", data: {}, methods: {}, components: {}, router:router, //指定路由 }); -
测试
<router-link to="/login" tag="button">login</router-link> <!--显示路由的组件--> <router-view></router-view>