Vue3.0之第一章——生命周期(钩子)、指令标签、Composition API

一、生命周期(钩子)

1. 创建期间的生命周期函数

创建期间的生命周期函数:
beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好data和 methods 属性
created:例已经在内存中创建OK,此时data和methods已经创建OK,此时还没有开始编译模板
beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示

2. 运行期间的生命周期函数

运行期间的生命周期函数:
beforeUpdate:状态更新之前执行此函数,此时data 中的状态值是最新的,但是界面上显示的数据还是旧的,因为此时还没有开始重新渲染DOM节点
updated:实例更新完毕之后调用此函数,此时data 中的状态值和界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了

3. 销毁期间的生命周期函数

销毁期间的生命周期函数:
beforeUnmounted:实例销毁之前调用。在这—步,实例仍然完全可用.
unmounted:Vue实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

4. 总结Xmind

在这里插入图片描述


二、指令标签

1.事件指令——v-on

事件指令v-on:click=“handleClick” 简写成 @click="handleClick"

1.1 事件执行多方法

<button @click="handleBtnClick1(), handleBtnClick2()">多调用新增</button>

1.2 子标签点击才执行方法

    <div @click.self="selfEvent">
        {{counter}}
        <button @click="handleBtnClick()">>
        通过.self修饰符,比如这里{{counter}}点击才会执行selfEvent方法
        </button>
    </div>
    //类似的事件修饰符还有 .prevent .once .capture .passive

1.3 禁止冒泡事件执行

    <div @click="maopaopao">
        <button @click.stop="handleBtnClick()">通过.stop修饰符来禁止maopaopao事件的执行</button>
    </div>

1.4 按键与鼠标修饰符

    //按键修饰符 .enter键 .tab .delete esc up down left right
    //鼠标修饰符 left right middle
    <div>
        <input @keydown="handleKeyDown"/>
        <input @keydown.enter="enterDown"/>
        <div @click.ctrl.exact="ctrlAndMouseDown"/>按住ctrl+鼠标点击这个div才执行事件</div>
    </div>

1.5 事件DOM操作

<button @click="handleBtnClick(2, $event)">新增</button> 
 		handleBtnClick(num, event){
            //event可获得原生js事件,获得一些dom属性进行操作
            console.log(event.target);
            this.counter += num;
        }

2. 循环指令——v-for

2.1 循环数组

<div v-for="(item, index) in list" :key='index'>{{item}}--{{index}}</div>
  data(){
    return {
      list: ['lee', 'bill', 'bob' ],
    }
  },

2.2 循环数组对象

  <template v-for="(value, key, index) in listObject" :key="index">
    <div v-if="key !== 'lastName'">
      {{value}}--{{key}}--{{index}}
    </div>
  </template>

  data(){
    return {
      listObject: {
        firstName: 'lee',
        lastName: 'dell',
        job: 'teacher'
      },
    }
  },

2.3 v-for与v-if优先级问题,活用template标签

<!--
  iffor在同一个div内时,for级别比if高,if会失效,所以把if单独提出来写
-->  
<div v-for="(value, key, index) in listObject" :key="index">
    <div v-if="key !== 'lastName'">
      {{value}}--{{key}}--{{index}}
    </div>
  </div>
<!--
  但是上面那种循环会多生成div层,所以可以用template标签做占位符
-->
  <template v-for="(value, key, index) in listObject" :key="index">
    <div v-if="key !== 'lastName'">
      {{value}}--{{key}}--{{index}}
    </div>
  </template>

3. 标签展示、DOM加载指令——v-show、v-if

标签展示与不展示指令,相当于:style="display:block/none"

v-if
v-else-if
v-else 要连接使用
会消除DOM节点,对于经常变化的标签建议使用v-show

4. 文本展示方式指令——v-text、v-html

v-html会将文本里面的html标签进行转义输出

5. 数据绑定与交互指令——v-bind、v-model、插值表达式

5.1 v-bind

v-bind:value="inputValue"可简写为:value="inputValue"
支持类型:html中的属性、css的样式、对象、数组、number 类型、bool类型

数据值可在data或setup函数中定义

// 绑定文本
<p v-bind="message"></p>
// 绑定属性
<p v-bind:src="http://...."></p>
<p v-bind:class="http://...."></p>
<p v-bind:style="http://...."></p>
// 绑定表达式
:class{className:true}

5.2 v-model

数据绑定形式。一般用于表单数据绑定
表单常用标签:input、textarea、checkbox、radio、select

<template>
  <!--下拉框-->
  <select v-model="selected">
    <option value="A被选">A</option>
    <option value="B被选">B</option>
    <option value="C被选">C</option>
  </select>
  <span>Selected: {{ selected }}</span>

  <!--单选按钮-->
  <input type="radio" id="small" value="small_value" v-model="picked">
  <label for="small">small</label>
  <br>
  <input type="radio" id="big" value="big_value" v-model="picked">
  <label for="big">big</label>
  <br>
  <span>Picked: {{ picked }}</span>

  <!--复选框-->
  <input type="checkbox" id="one" value="value_one" v-model.lazy="checkedNames">
  <label for="one">选项一</label>
  <input type="checkbox" id="two" value="value_two" v-model.lazy="checkedNames">
  <label for="two">选项二</label>
  <input type="checkbox" id="three" value="value_three" v-model.lazy="checkedNames">
  <label for="three">选项三</label>
  <br>
  <span>Checked names: {{ checkedNames }}</span>

</template>

  data(){
    return {
      selected: '',
      picked: '',
      checkedNames: []
    }
  }

v-model也可以和.lazy、.trim和.number这些修饰符一起使用

  <!-- 在每次 input 事件触发后将输入框的值与数据进行同步,添加 lazy 修饰符,
  从而转变为使用 change 事件进行同步 -->
  <input v-model.lazy="msg" >
  <!--去除字符串首尾的空格-->
  <input v-model.trim="msg">
  <!--将数据转化为值类型-->
  <input v-model.number="age" type="number">

5.3 插值表达式

可写js表达式:{{Math.max(1,2,3)}}
也可直接写:{{content}}

6. 一些其他常用指令——v-pre、v-once、v-block

7.总结Xmind

在这里插入图片描述


三、Composition API

1. 安装使用

首先利用cli4创建一个demo下载composition-api在main.js中引入使用
//下载
npm install --save @vue/composition-api
//在main.js 引入官方提供的vue-composition-api库
import VueCompositionApi from '@vue/composition-api';
Vue.use(VueCompositionApi)

2. 数据方法入口——setup()

之前定义的data,methods等都统一放入setup中实现

//home.vue里
<setup :data="123"></setup>

//setup.vue里
export default {
   name:'Setup',
   setup(props,context){
		console.log(props.data)//123
	    console.log(context)
   },
   props:{
      data:Number
   }
}
// console.log(context)输出结果
{
 root: (...),
 parent: (...),
 refs: (...),
 attrs: (...),
 listeners: (...),
 isServer: (...),
 ssrContext: (...),
 emit: (...),
 slots: {}}

3. 代理对象多——reactive()

reactive()函数接受一个普通对象,返回一个响应式的数据对象.类似于2.x的组件里的data()函数,想要使用必须先引入reactive,模板中想要使用该数据必须return出去,此函数只能在setup函数里使用.

<template>
  <div>
       <span style="margin-right:10px">{{state.count}}</span>
       <el-button type="primary" @click="changeCount">点击累加</el-button>
  </div>
 
</template>

<script>
import { reactive } from '@vue/composition-api';
export default {
   name:'Setup',
   setup(){
    //state响应式的数据对象
     const state= reactive({
           count:1
     })
     function changeCount() {
         state.count++;
     }
     return{
        state,
        changeCount
     }
   }
}
//也可以return state 如这样返回在模板直接{{count}}就可以取到值

4. 代理对象一——ref()

4.1 ref会返回一个对象,并且只有value属性,不像reactive返回多个自定义的

 //注意在setup内部访问值需要.value,在模板直接拿值可以使用
<template>
    <div>{{count}}---{{name}}</div>
</template>
<script>
import {ref} from '@vue/composition-api';
export default {
    name:'Ref',
    setup(){
        const count=ref(0);
        //ref会返回一个对象,并且只有value属性
        console.log(count.value)//0
        console.log(name.value) //undefined
        return {
            count,
            name:ref('zdb')
        }
    }
}
</script>

4.2 ref与reactive联动,不用.value调值

<template>
    <div>{{state.count}}</div>
</template>
<script>
import { ref ,reactive } from '@vue/composition-api';
export default {
    name:'Ref',
    setup(){
        const count=ref(0);
        //ref会返回一个对象,并且只有value属性
        const state=reactive({
            count
        })
        state.count++;
        return {
           state
        }
    }
}
</script>

4.3 新的ref会覆盖旧的ref

<script>
import { ref ,reactive } from '@vue/composition-api';
export default {
    name:'Ref',
    setup(){
      const c1=ref(0)
      const state=reactive({
          c1
      })
      const c2=ref(9)
      state.c1=c2;
      state.c1++;
      console.log(c1.value) //0
      console.log(c2.value) //10
      console.log(state.c1) //10
    }
}
</script>

5. 转换代理对象——toRef()

可以将reactive()创建出来的响应式对象,转换为普通的对象

       //将reactive里定义的item转化为普通对象出来
		 const data = reactive({ item:{} });
        const getItemData = async() => {
            const result = await get(`/api/shop/${route.params.id}`)
            data.item = result.data
        }
        const { item } = toRefs(data)
        return { item, getItemData }

6. 计算函数——computed()

用来创建计算属性,computed()函数的返回值是一个ref的实例,使用computed之前需要按需导入

1.创建只读计算属性
<script>
import {ref , computed} from '@vue/composition-api';
export default {
   name:'Computed',
   setup(){
       const count = ref(1);
       const plusOne=computed(()=>{ return count.value++ })
       console.log(plusOne.value) //1
       plusOne.value++ //error
   }
}
</script>
2.创建可读可写的计算属性
<template>
   <div>
        <div>count:{{count}}</div>
        <div>computed:{{countComputed}}</div>
        <el-button type="primary" @click="changeCount">点击累加</el-button>
   </div>
</template>

<script>
import {ref , computed} from '@vue/composition-api';
export default {
   name:'Computed',
   setup(){
       const count = ref(1);
       const countComputed=computed({
           //读取函数
           get:()=> count.value+1,
           //赋值函数
           set:(val)=>count.value=val
       })
       const changeCount=()=>{
           count.value++;
       }
       return{
           count,
           countComputed,
           changeCount
       }
   }
}
</script>

京东到家项目代码实例(只应用了get然后返回了):

  const calculations = computed(() => {
    const productList = cartList[shopId]?.productList
    const result = { total: 0, price: 0, allChecked: true}
    if(productList) {
       for(let i in productList) {
         const product = productList[i]
         result.total += product.count
         if(product.check) {
           result.price += (product.count * product.price)
         }
         if(product.count > 0 && !product.check) {
           result.allChecked = false
         }
      }
    }
    result.price = result.price.toFixed(2)
    return result
  })

7. 监听函数——watch()

7.1 监听数据源变化做成一些操作、定时操作

7.2 可监听ref数据源,reactive数据源,多数据源

//reactvie
<script>
import { watch ,ref, reactive, toRefs } from '@vue/composition-api';
export default {
   name:'Watch',
   setup(){
     const state=reactive({
       count:0,
       name:'zdb'
     })
     watch(
       [()=>state.count,()=>state.name], //Object.values(toRefs(state))
       ([newCount,newName],[oldCount,oldName])=>{
          console.log(`新的count${newCount}`)
          console.log(`新的name${newName}`)
          console.log(`旧的count${oldCount}`)
          console.log(`旧的name${oldName}`)
       },
    //去掉此项页面会报错
       {
         lazy:true
       }
      )
       setTimeout(()=>{
         state.count+=15;
         state.name+='zs'
       },2000)
      return{
       state
      }
   },
   
}
</script>

//ref

<script>
import { watch ,ref, reactive, toRefs } from '@vue/composition-api';
export default {
   name:'Watch',
   setup(){
     const count=ref(0);
     const name=ref('zdb');
     watch(
       [count,name],
       ([newCount,newName],[oldCount,oldName])=>{
          console.log(`新的count${newCount}`)
          console.log(`新的name${newName}`)
          console.log(`旧的count${oldCount}`)
          console.log(`旧的name${oldName}`)
       },
       {
         lazy:true
       }
      )
       setTimeout(()=>{
         count.value+=15;
         name.value+='zs'
       },2000)
      return{
        count,
        name
      }
   },
   
}
</script>

7.3 消耗性能,可监听数据到一定阈值,取消watch函数

8. provide()&inject()

provide和inject可以实现嵌套组件之间数据传递.这两个函数只能在setup中使用.父组件中使用provide()函数向下传递数据,子组件使用inject()获取上层传递来的数据

//父组件
<template>
  <div class="home">
    父组件:
   <Provide></Provide>
  </div>
</template>

<script>
import Provide from '@/components/provide.vue'
import {provide,ref} from '@vue/composition-api'
export default {
  name: 'Home',
  components: {
    Provide
  },
  setup(){
    const msg=ref('我是父组件传递来的数据');
    //参数一:共享的名称 参数二:共享的数据
    provide('sendMsg',msg)
    return {
      msg
    }
  }
}
</script>
//子组件
<template>
   <div>子组件:{{msg}}</div>
</template>

<script>
import {inject,ref} from '@vue/composition-api'
export default {
   name:'Provide',
   setup(){
     const msg=inject('sendMsg')
     return {
         msg
     }
   }
}
</script>


9. 总结Xmind

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值