vue入门基础2
1. 生命周期之钩子函数
所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对属性和方法进行运算。这意味着你不能使用箭头函数来定义一个生命周期方法 (例如 created: () => this.fetchTodos())。这是因为箭头函数绑定了父上下文,因此 this 与你期待的 Vue 实例不同。这段话以及下方图解转自vue官网,可点击查看详情。
生命周期演示图
下图展示了实例的生命周期。你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。
钩子函数案例(可帮助小白快速理解生命周期的过程,用现实生活解释)
<div id="app">
{{ count }}
<button @click='count += 1'>点击</button>
<button @click="destroyFn">销毁</button>
</div>
new Vue({
el: '#app',
data: {
count: 0
},
computed: {
},
watch: {
},
methods: {
destroyFn() {
this.$destroy()
}
},
beforeCreate() { console.log('准备怀孕了') },
created() { console.log('已经怀上了') },
beforeMount() { console.log('马上生了') },
mounted() { console.log('已经生下来了') },
beforeUpdate() { console.log('改变前') },
updated() { console.log('改变后') },
beforeDestroy() { console.log('临死前') },
destroyed() { console.log('game over') }
})
作为小白来说,在阅读完官方文档后,也许还是不能理解生命周期,不过通过上述案例,大致了解生命周期流程的大致意思也是不错的。我们目前无法掌握全部,那么通过下面的案例,来认识一些重要部分的作用。
<div id="app">
{{ count }}
<button @click='count += 1'>点击</button>
<button @click="destroyFn">销毁</button>
</div>
new Vue({
el: '#app',
data: { count: 0 },
computed: {},
watch: {},
methods: {
destroyFn () {
this.$destroy()
}
},
// 数据请求 --- 给孩子起名字 / 教育(胎教、早教)
created () {}, // 数据请求
mounted () {}, // 数据请求 + 操作DOM(孩子的衣服生下来之后才能穿)
updated () {}, // 操作DOM(不能一辈子穿一套衣服呀)
destroyed () {} // 不可以操纵DOM
})
2. vue中的数据请求
ajax — 数据请求 — 前后端分离(前后端耦合、不分离开发— 传统的系统架构)— 跨域
js 原生
XMLHttpRequest / ActiveXObject
jQuery $.ajax() / $.get() / $.post() / $.load() / $.getScript()
vue/react fetch / axios — 基于es6的promise
2.1 fetch
案例—fetch的mounted请求
html部分
<div id="app">
</div>
js部分
new Vue({
el:'#app',
mounted(){
fetch('https://www.daxunxun.com/banner')
.then(res=>res.json())
.then(data=>{
console.log(data)
})
}
})
fetch有两种请求,默认是get(可以省略),两种写法不同
js部分
//get方法
new Vue({
el:'#app',
mounted(){
//数据拼接在地址后方
fetch('https://www.daxunxun.com/douban?start=40',{
method:'get'
}).then(res => res.json()).then(data =>{ console.log(data)})
}
})
//post方法
new Vue({
el:'#app',
mounted(){
// 注意有些接口不允许用post,且post有两种写法
fetch('https://www.daxunxun.com/users/login',{
method:'post',
// body:JSON.stringify({
// username:'18813007814',
// password:'123456'
// })
body:'username=18813007814&password=123456'
}).then(res => res.json()).then(data =>{ console.log(data)})
//返回来一个-1,证明密码错误
}
})
2.2 axios
axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。axios的数据请求写法与fetch相比更加简单。使用前需要先下载相关文件并且引入。
js部分
new Vue({
el:'#app',
mounted(){
//更加方便,建议使用axios
//get方法
axios.get('https://www.daxunxun.com/banner').
then(res => {console.log(res.data)}),
//post方法
axios.post('https://www.daxunxun.com/users/login',{
username:'18813887814',
password:'123456'
}).then(res => {console.log(res.data)})
}
})
3. vue之组件初级部分
组件的应用大致可以分为三步:
1.先定义一个组件
2.注册一个组件
3.使用组件
3.1 全局组件
html部分
<div id="app">
<!-- 3.使用组件 -->
<my-header></my-header>
</div>
js部分
//全局注册组件
//1.定义组件
const MyHeader={
template:`<header>头部</header>`
}
//2.全局注册组件
Vue.component('my-header',MyHeader)
new Vue({
el:'app'
})
3.2 局部组件
html部分
<div id="app">
<!-- 3.使用组件 -->
<my-header></my-header>
</div>
js部分
//1.定义组件
const MyHeader={
template:`<header>这是头部</header>`
}
new Vue({
el:'#app',
//2.局部注册组件
compnents:{
'my-header':MyHeader
}
})
3.3 多组件
html部分
<div id="app">
<!-- 3.使用组件 -->
<my-header></my-header>
<my-content></my-content>
<my-footer></my-footer>
</div>
js部分
//1.定义组件
const MyHeader={
template:`<header>这是头部</header>`
}
const MyContent={
template:`<div>内容部分</div>`
}
const MyFooter={
template:`<footer>这是尾部</footer>`
}
new Vue({
el:'#app',
//2.局部注册组件
components:{
'my-header':MyHeader,
'my-content':MyContent,
'my-footer':MyFooter
}
})
3.4 嵌套组件
html部分
<div id="app">
<!-- 3.使用组件 -->
<my-header></my-header>
<my-content></my-content>
<my-footer></my-footer>
</div>
js部分
//1.定义组件
const myBanner={ //(1.定义子组件 ,在哪里用就在哪里注册组件
template:`<div>这是轮播图</div>`
}
const myNav={
template:`<div>这是导航</div>`
}
const MyHeader={
template:`<header>这是头部</header>`
}
const MyContent={ //(3.使用也要在content组件内部使用
template:`<div class="con">
内容部分
<my-banner></my-banner>
<my-nav></my-nav>
</div>`,
components:{ //(2.因为要在content内使用组件,所以在content内部注册
'my-banner':myBanner,
'my-nav':myNav
}
}
const MyFooter={
template:`<footer>这是尾部</footer>`
}
new Vue({
el:'#app',
//2.局部注册组件
components:{
'my-header':MyHeader,
'my-content':MyContent,
'my-footer':MyFooter
}
})
3.5 抽离组件的模块
以局部组件为例
html部分
<div id="app">
<!-- 3.使用组件 -->
<my-header></my-header>
</div>
需要在script标签上方插入template标签
<template id="header">
<header>这是头部---{{ tip }}</header>
</template>
js部分
//1.定义组件
const MyHeader={
template:`<header>这是头部</header>`
}
new Vue({
el:'#app',
//2.局部注册组件
compnents:{
'my-header':MyHeader
}
})
4. vue之组件进阶部分
4.1 父子组件之传值
父传子
父子组件之间,通过父组件向子组件传值的渠道多,传值类型多种多样。
如何传?
1.在父组件调用子组件的地方,添加一个自定义属性,属性的值就是父组件要传给子组件的值。(如果属性的值是number类型,boolean类型,或者是变量,需要使用到绑定属性)
2.在子组件定义的地方 给其添加一个选项props,props可以是数组或者对象
- 2.1若是数组,元素则是父组件中自定义的属性名
- 2.2若是对象,则有两种写法
/ 第一种:验证传递数据的有效性 ---- 在实际开发中,父子组件可能不是一个人写的,如果数据类型不对,会报出警告,可以及时调整。
/ 第二种:既要验证数据的类型,又要设定属性的默认值,如果默认值是对象或者是数组,值为一个函数。
推荐使用对象
看完讲解也许还是不好了解,那么请看下放代码,一定会让你明白!
html部分
<div id="app">
<!--1. 在父组件调用子组件的地方,添加一个自定义属性 test,count,flag,tips
皆是自定义属性,且数据类型不同,有常量、数值、布尔、变量 -->
<my-header test='父给子' :count='200' :flag="true" :tips='tips'/>
</div>
需要在script标签上方插入template标签
<template id="tou">
<header>这是头部
---{{test}}---{{count}}---{{flag}}---{{tips}}
</header>
</template>
该处案例的props是数组
js部分
const Header={
template:'#tou',
//2.在子组件定义的地方 给其添加一个选项props,该处案例的props是数组
props:['test','count','flag','tips']
}
new Vue({
el:'#app',
data:{
tips:'小提示'
},
components:{
'my-header':Header
}
})
该处案例的props是对象
js部分—写法一
const Header={
template:'#tou',
props:{
test:String,
count:Number,
flag:Boolean,
tips:String
}
}
new Vue({
el:'#app',
data:{
tips:'小提示'
},
components:{
'my-header':Header
}
})
js部分—写法二
const Header={
template:'#tou',
props:{
test:{
type:String,
default:'测试数据'
},
count:{
type:Object,
default:function(){
return {a:'11',b:'22'}
}
},
tips:{
type:Array,
default:function(){
return [1,2,3]
}
}
}
}
new Vue({
el:'#app',
data:{
tips:'小提示'
},
components:{
'my-header':Header
}
})
子传父
相较于父传子,子传父的方式就比较单一了,具体步骤如下。
1.在父组件调用子组件的地方,给其绑定一个自定义事件,注意事件不要加()。
2.在父组件选项methods中实现此事件,默认参数为从子组件得到的值。
3.在子组件中,可以是生命周期钩子函数,也可以是组件自己的事件去触发父组件中的自定义事件。
html部分
<div id="app">
<!-- 绑定一个自定义事件 -->
<my-header @myevent="getData"/>
</div>
需要在script标签上方插入template标签
<template id="tou">
<header>
这是头部
</header>
</template>
js部分
const Myoo={
template:'#tou',
mounted(){ //第二个参数为子传给父的值
this.$emit('myevent',1000)
}
}
new Vue({
el:'#app',
methods:{
getData(val){
console.log(val)
}
},
components:{
'my-header':Myoo
}
})
4.2非父子组件传值
非父子组件的传值—兄弟组件传值
- 先要确定中间联系人
const bus = new Vue()
- 确保接受者的存在,在接收端通过
bus.$on( ‘收信信号’,function(val){ })
- 在发送端通过
bus.$emit(‘收信信号’,val)
html部分
<div id="app">
<my-lists></my-lists>
<my-btn></my-btn>
</div>
需要在script标签上方插入template标签
<template id="li">
<ul>
<li>11<button @click="add">+1</button></li>
<li>22<button @click="add">+1</button></li>
<li>33<button @click="add">+1</button></li>
<li>44<button @click="add">+1</button></li>
<li>55<button @click="add">+1</button></li>
</ul>
</template>
<template id="btn">
<div>
总量是:{{num}}
</div>
</template>
js部分
//1.确定中间联系人
const media = new Vue()
const Mylist={
template:'#li',
methods:{
add(){
//3.在发送端以确认过的收信信号来发送相关内容
media.$emit('love',2)
}
}
}
const Mybtn={
template:'#btn',
data(){
return {
num:0
}
},
mounted(){
//2.确保接收端可以接受,并且确定接收端的收信信号
media.$on('love',(val)=>{
this.num += val;
})
}
}
4.3 组件间的动态传值
keep-alive保持组件的状态,避免组件的重新渲染
可以理解为手机打开软件后按了home键,再打开软件,数据仍然存在。
每个组件都会有两个生命周期钩子函数
activated() 正在用的
deactivated() 后台的
include可以只给部分组件保留状态,给需要定义的组件
添加name属性
html部分
<div id="app">
<button @click="tem = 'a-con'">AAA</button>
<button @click="tem = 'b-con'">BBB</button>
<button @click="tem = 'c-con'">CCC</button><br>
<!-- keep-alive保持组件的状态,避免组件的重新渲染 -->
<!-- 可以理解为手机打开软件后按了home键,再打开软件
数据仍然存在
每个组件都会有两个生命周期钩子函数
activated() 正在用的
deactivated() 后台的
include可以只给部分组件保留状态,给需要定义的组件
添加name属性-->
<keep-alive include='a,b'>
<!-- 只显示is后面的值 -->
<component :is='tem'></component>
</keep-alive>
</div>
需要在script标签上方插入template标签
<template id="acon">
<input type="text" placeholder="aaa">
</template>
<template id="bcon">
<input type="text" placeholder="bbb">
</template>
<template id="ccon">
<input type="text" placeholder="ccc">
</template>
js部分
//定义组件时顺便定义名字
const Acon = {
name:'a',
template: '#acon',
activated(){
console.log('a11')
},
deactivated(){
console.log('a22')
}
}
const Bcon = {
name:'b',
template: '#bcon',
activated(){
console.log('b11')
},
deactivated(){
console.log('b22')
}
}
const Ccon = {
template: '#ccon',
activated(){
console.log('c11')
},
deactivated(){
console.log('c22')
}
}
new Vue({
el: '#app',
data:{
tem:'a-con'
},
components: {
'a-con': Acon,
'b-con': Bcon,
'c-con': Ccon
}
})