vue2升级vue3知识点

echarts自适应大小

 myChart.setOption(option)
  window.onresize = function () {
    myChart.resize()
  }

setup在create之前,所有变量方法都要return。

function btn() {}

或者

const btn = () =>{}

二、组合式API(常用)

1.import { ref } from 'vue

当ref的值发生改变时,视图层会自动更新。 

const name = ref('班海斌')

function btn() {

name.value = '韦艳迎'

}

2. import { reactive } from 'vue

  • 为值创建响应式引用

  • 定义基本普通数据类型不能用reactive,用ref

  • reactive主要定义复杂数据类型,如数组、对象

  • 可相应深层次的数据,如多维数组

  • reactive返回一个响应式的proxy对象

function btn() {

name = '韦艳迎'

}

3. import { toRef } from 'vue

响应式数据

ref的本质是复制粘贴一份数据,脱离了与原数据的交互

ref函数将对象中的属性变成响应式数据,修改响应式数据是不会影响到原数据,但是会更新视图层

toRef的本质是引用,与原数据有交互,修改响应式数据会影响到原数据,但不会更新视图层

toRef接受两个参数(要操作的对象、对象的某个属性)

4. import { toRefs } from 'vue

用于批量设置多个数据为响应式数据

toRefs与原数据有交互,修改响应式数据会影响到原数据,但不会更新视图层

toRefs还可以与其他响应式数据交互,更加方便处理视图数据

<h1> {{ name }} </h1>

<h1> {{ age }} </h1>

setup() {

const obj = { name: '班海斌', age: 18,  sex: '男'}

const newObject = reactive(obj)

return { ...torefs(newObject) }

}

5.computed,监听数据变化; import { computed } from 'vue

<input type='number' v-model="age1"/>

<input type='number' v-model="age2"/>

总和:<input type='number' v-model="sum"/>

setup() {

const age1 = ‘ ’

const age2 = ' '

const res = reactive( { age1,  age2 })

const sum = computed( () =>{

return  age1 + age2

})

return { ...torefs(res), sum }

}

6.watch,监听数据变化; import { watch } from 'vue

setup() {

const num1 = ref(0)

const num3 =  reactive( {

name :  '班海斌',

age: { num: 1}

})

// 监听一个

watch( num1, ( newVal, oldVal ) = > {

console.log( newVal, oldVal )

})

// 监听多个

watch( [num1, num2], ( newVal, oldVal ) = > {

console.log( newVal, oldVal )

})

// 监听整个reactive响应数据变化,只能监听到最新的结果newVal=oldVal

watch( num3, ( newVal, oldVal ) = > {

console.log( newVal, oldVal )

})

// 监听reactive响应数据中某一个值的变化

watch( () => num3.age.num, ( newVal, oldVal ) = > {

console.log( newVal, oldVal )

}, { immediate: true } )  // { immediate: true } ,进入页面立即开启监听

return { num1,num3}

}

7.watchEffect,监听数据变化; import { watchEffect } from 'vue

watchEffect如果存在的话,在组件初始化的时候就会执行一次收集依赖

 watchEffect拿不到新值和旧值

watchEffect不需要指定监听的属性,他会自动收集依赖,只要我们回调中引用到了响应式的属性

           那么当这些属性变更的时候,这个回调都会执行,而watch只能监听指定的属性而做出变更。

setup() {

const p1= ref(0)

const res = watchEffect( () => {

const a = p1.value

})

res() // 停止数据监听

}

8.shallowRef和shallowReactive

shallowRef只处理基本类型数据

shallowReactive只处理第一层数据,对象第一层数据

const p1 = shallowReactive({

name: '班海斌',

age: {

num: 0

}

})

三、组件传值

1.普通页面传值

父:

setup() {

const p1 = reactive( { name: '班海斌',age: 18})

provide( 'name', p1)    //  传值

return { p1 }

}

子:

setup() {

const p1 = inject( ‘name')  //接收传值

return { p1 }

}

2.点击给子组件传值

<button @click="btn">点击传值给父组件</button》

<helloWord ref="tableRef"/>

父组件:

setup() {

const  tableRef = ref()

const p1 = reactive( { name: '班海斌',age: 18})

function btn () {

tableRef.value.myChild( p1 )

}

return{ tableRef, p1, btn }

}

子组件:

setup() {

function myChild(val) {}

return { myChild }

}

getCurrentInstance()

1、概述:一个很重要的方法,获取当前组件的实例、上下文来操作router和vuex等。
2、使用:由vue提供,按需引入:import { getCurrentInstance} from 'vue';

import { getCurrentInstance } from 'vue';
// 获取当前组件实例
const instance = getCurrentInstance();

// 获取当前组件的上下文,下面两种方式都能获取到组件的上下文。
const { ctx }  = getCurrentInstance();  //  方式一,这种方式只能在开发环境下使用,生产环境下的ctx将访问不到
const { proxy }  = getCurrentInstance();  //  方式二,此方法在开发环境以及生产环境下都能放到组件上下文对象(推荐)
// ctx 中包含了组件中由ref和reactive创建的响应式数据对象,以及以下对象及方法;

例如:

 ctx.$notify.success({ title: '成功', message: '导出成功' })

props(为组件的props),context(包含attrs;emit;slots三个组件的property)

setup(props,context){

}

1、扩展:父组件通过属性传的值在子组件中的各个部分的获取:
 ①:props:通过父传子的方式直接获取到值
 ②:setup(props, context){} 方法中的props只能拿到选项props中已经定义的属性;
 ③:setup(props, { attrs, emit, slots}){} 方法中的attrs只能拿到未在选项props中定义的属性;
 ④:通过{ proxy } = getCurrentInstance(); proxy.attrs也只能拿到未在选项props中定义的属性;
2、context:非响应式的对象;包含了组件暴露的三个property:
 context.attrs:传入组件中但是未被props接收的对象。
 context.emit:用于触发当前组件实例上的传值事件。
 context.slots:用来访问被插槽分发的内容(一般用于使用渲染函数来书写一个组件时)

Vue3.x中重写的v-model

用例:Vue3.x重写了v-model的实现方式,以适用用绑定多个v-model
①:单个数据实现数据双向绑定

<my-components v-model="msg"></my-components>
// 等价于
<my-components :modelValue="msg" @update:modelValue="value=$event"></my-components>

// myComponents组件中接收绑定数据和触发数据改变
props: { modelValue: String }; // 获取数据
setup(props, { emit }) {
    emit('update:modelValue', 'newValue'); // 触发事件并传值
};

②:多个数据实现数据双向绑定

<my-components v-model:msg="msg" v-model:name="name"></my-components>
// 等价于
<my-components :msg="msg" @update:msg="value=$event" :name="name" @update:name="name=$event"></my-components>

// myComponents组件中接收绑定数据和触发数据改变
props: { msg: String, name: String }; // 获取数据
setup(props, { emit }) {
    emit('update:msg', 'newValue'); // 触发事件并传值
    emit('update:name', 'newValue'); // 触发事件并传值
};

插槽修改

vue2写法
<div slot="footer">
  <el-button size="small" @click="cancelBtn()">取 消</el-button>
  <el-button size="small" type="primary" @click="confirmSubmit">确 定</el-button>
</div>
  
  
vue3写法
 <template #footer>
  <div>
  	<el-button size="small" @click="cancelBtn()">取 消</el-button>
  	<el-button size="small" type="primary" @click="confirmSubmit">确 定</el-button>
  </div>
 </template>

vue3 Watch 更新

watch(
  () => props.cloudTipsMessage,	//监听对象
  (newValue, oldValue) => {
    if (newValue === '视频') {
      reactiveData.fileMap = ['.mp4']
      reactiveData.tipsMessage = '.mp4'
    } else if (newValue === '音频') {
      reactiveData.fileMap = ['.mp3']
      reactiveData.tipsMessage = '.mp3'
    } else if (newValue === 'PDF') {
      reactiveData.fileMap = ['.pdf']
      reactiveData.tipsMessage = '.pdf'
    } else if (newValue === '文档') {
      reactiveData.fileMap = ['.xls', '.xlsx', '.doc', '.docx', '.ppt', '.pptx']
      reactiveData.tipsMessage = '.xls,.xlsx,.doc,.docx,.ppt,.pptx'
    }
  },
  {
    deep: true // 深度监听的参数
  }
)

使用echarts

按需引用,并且挂载方式和vue2(var myChart = this.$echarts.init(this.$refs['pieChart']))有点差别,

不再使用this.$echarts,并且按需引入

<template>
  <div id="pieChart" style="width: 100%; height: 400px" />
</template>

<script setup>
import { onMounted } from 'vue'
import * as echarts from 'echarts'

const props = defineProps({
  courseData: { type: Array, default: () => [] },
  legendData: { type: Array, default: () => [] },
  courseTotal: { type: Number, default: 0 }
})
onMounted(() => {
  drawPie()
})
function drawPie() {
  var myChart = echarts.init(document.getElementById('pieChart'))
  var option = {
    tooltip: {
      trigger: 'item',
      formatter: '{b}: {c} ({d}%)'
    },
    color: ['#3AA0FF', '#4DCB73', '#ee6f3d', '#FAAD14', '#42c7df'], // 饼图颜色
    legend: {
      orient: 'vertical',
      right: 40,
      bottom: 30,
      data: props.legendData
    },
    series: [
      {
        name: '总课程数', // 配置formatter时候会用到(就是{a})
        type: 'pie',
        radius: ['45%', '66%'], // 配置饼图和环图的内圆和外圆的大小
        center: ['40%', '50%'], // 配置图形的位置,前面一个是x轴,后面一个是y轴,'50%'代表是水平居中
        avoidLabelOverlap: false,
        label: {
          show: false,
          position: 'center',
          fontSize: '16',
          fontWeight: 'bold',
          formatter: `{a}\n${props.courseTotal}`
        },
        data: props.courseData
      }
    ]
  }
  // 设置成功
  myChart.setOption(option)
  window.onresize = function () {
    myChart.resize()
  }
}
</script>

<style scoped>
</style>

引入Treeselect

import Treeselect from 'vue3-treeselect'
import 'vue3-treeselect/dist/vue3-treeselect.css'

不再是vue2中的(按照vue2引入会报错)

import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值