标签:vue console name setup Vue3 ref log
官方文档
项目搭建
// 在cmd终端输入下方命令,查看@vue/cli版本,确保@vue/cli版本在4.5.0以上 vue --version
// 如果vue/cli版本过低或上方命令报错,需要安装或者升级你的@vue/cli npm install -g @vue/cli
// 创建新项目 vue create vue_test
// 可视化创建新项目 vue ui
根据需求创建即可,版本选vue3(默认是vue2)
Composition API(组合式API)
Composition API将vue中的很多功能拆分成了一个一个的hook
可以理解为Vue3中一个新的配置项,值为一个函数
setup()
setup是所有Composition API(组合式API)的入口
- 在setup函数内的this指向undefined
- setup函数是处于生命周期函数 beforeCreate 和 Created 两个钩子函数之前的函数,也就说在 setup函数中是无法使用 data 和 methods 中的数据和方法的
- 在setup函数中定义的变量和方法最后都是需要 return 出去的,不然无法在模板中使用
- 注意:如果data内的变量和setup函数内的变量重名,优先使用setup里面的变量
setup可以接受参数props和content
setup(props, content){} 或者===>setup(props, { attrs, slots, emit }) {}
props参数
组件外部传递进入或组件内部声明已经接收的属性
// 父组件 <son :name="obj.name"></son> // 子组件 <template> <div> <h1>我是子组件</h1> <div>{{ name }}</div> </div> </template> <script> export default { props: { name: { type: String } }, setup(props, context) { console.log(props) } </script>
context参数
包含attrs,slots和emit,content参数可以解构
attrs是组件外部传递进入组件的值,但组件内部未在props内声明,即可使用context.attrs得到
// 父组件 <son :name="obj.name" :age="obj.age"></son> // 子组件 <script> export default { props: { name: { type: String } }, setup(props, context) { console.log(props) console.log(context.attrs.age)// 此时未在props声明age } </script>
emit用于分发自定义函数,等同于this.$emit,可用于子向父传值
// 子组件 <button @click="son">子组件</button> <script> export default { setup(props, context) { const son = () => { context.emit('change', 50) } return { son } } } </script> // 父组件 <template> <div> <h1>我是父组件</h1> <div>子组件可以改变我的值{{ sonval }}</div> <div>---------------------------------------</div> <son :name="obj.name" :age="obj.age" @change="formSon"></son> </div> </template> <script> import son from '../components/son.vue' import { ref } from 'vue' export default { name: 'Father', components: { son }, setup() { let sonval = ref(0) const formSon = val => { sonval.value = val } return { formSon, sonval } } } </script>
对于生命周期而言,在vue2中函数的生命周期和data平级声明即可
data() { return {} }, beforeCreate() { console.log('created') }, method: {} setup() { console.log('======setup=========') onBeforeMount(() => { console.log('======onBeforeMount=========') }) onMounted(() => { console.log('======onMounted=========') }) onBeforeUpdate(() => { console.log('======onBeforeUpdate=========') }) onUpdated(() => { console.log('======onUpdated=========') }) onBeforeUnmount(() => { console.log('======onBeforeUnmount=========') }) onUnmounted(() => { console.log('======onUnmounted=========') }) }
slots可以获取插槽的内容,相当于this.$slots
// 子组件 <template> <div> <h1>我是子组件</h1> <slot name="son"> <div>默认插槽</div> </slot> </div> </template> <script> export default { props: { name: { type: String } }, setup(props, context) { console.log(context.slots.son()[0])// 获取slot的信息 } } </script> // 父组件 <son> <template v-slot:son> <p>我是父组件呵呵哈哈哈</p> </template> </son>
setup语法糖
vue3.2开始,在script脚本上声明setup会自动将所有顶级函数和变量自动暴露给模板使用
<template> <div> {{ name }} <button @click="changeName">改变名字</button> </div> </template> <script setup> import { ref } from 'vue' const name = ref('user') const changeName = () => { name.value = 'newUser' } </script>
数据定义
ref
使用ref可以定义一个响应式数据 const xxx=ref(initValue)
使用前需要按需导入,ref定义的响应式数据修改数据时必需要.value
<script setup> import { ref } from 'vue' // 括号内的为初始值 // 基本数据类型 number,string,boolean let name=ref('张三'); let age=ref(18); let isMarry=ref(false); // 使用ref定义数组 let hobby=ref(['吃饭','睡觉','打豆豆']); // 使用ref定义对象 let user=ref({ idCard:'身份证', nation:['中国','美国','英国','俄罗斯'] }) const changeName = () => { name.value = 'newUser'// name.value修改数据 } </script>
reactive函数
使用reactive可以定义一个响应式数据 const 代理对象=reactive(被代理的对象)接收一个对象(或数组),返回一个代理器对象(Proxy的实例对象,简称Proxy对象)
使用前需要按需导入
<script setup> import { reactive } from 'vue' let student=reactive({ name:'张三', age:19, hobbies:['吃饭','睡觉','打豆豆'] }); console.log(student) const changeName = () => { student.name = '李四' // 直接修改数据 } </script>
reactive与ref
ref多用来定义:基本类型数据
reactive多用来定义:对象(或数组)类型数据
注意:ref也可以用来定义对象(或数组)类型的数据,它内部会自动通过reactive转为代理对象
两者原理
ref通过Object.defineProperty()的get和set实现(响应式)数据劫持
reactive通过使用Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据 从使用角度
所以ref操作数据需要.value,但reactive定义的数据可以直接修改
toRef、toRefs
使用toRef创建一个ref对象,其value值指向另一个对象中的某个属性值
<template> <h2>姓名:{{name}}</h2> <h2>年龄:{{age}}</h2> </template> <script> import {reactive,toRef} from 'vue' export default { setup(){ let person=reactive({ name:'user', age:18 }) return{ name:toRef(person,'name'), age:toRef(person,'age'), } } } </script>
toRefs与toRef功能一致,但可以批量创建多个ref对象
<template> <h2>姓名:{{name}}</h2> <h2>年龄:{{age}}</h2> </template> <script> import {reactive,toRef} from 'vue' export default { setup(){ let person=reactive({ name:'user', age:18 }) return{ ...toRefs(person) } } } </script>
生命周期
Vue2 | Vue3 |
---|---|
beforeCreate | setup |
created | setup |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeDestory | onBeforeUnmount |
destoryed | onUnmounted |
activated | onActivated |
deactivated | onDeactivated |
vue2推荐将生命周期函数和data,methods平级定义
vue3推荐将生命周期函数定义在setup函数内部
setup(){ console.log("======setup========="); onBeforeUnmount(()=>{ console.log("======onBeforeUnmount========="); }) onMounted(()=>{ console.log("======onMounted========="); }) onBeforeUpdate(()=>{ console.log("======onBeforeUpdate========="); }) onUpdated(()=>{ console.log("======onUpdated========="); }) onBeforeUnmount(()=>{ console.log("======onBeforeUnmount========="); }) onUnmounted(()=>{ console.log("======onUnmounted========="); }) }
数据处理
shallowRef和shallowReactive
shallowReactive:只处理对象最外层属性的响应式(浅响应式),对深层次的数据不会改变视图但会改变数据
shallowRef: 只处理基本数据类型的响应式,不进行对象的响应式处理
如果有一个对象数据,结构比较深,但变化时只是外层属性变化用shallowReactive
如果有一个对象数据,后续功能不会修改该对象中的属性,而是生新的对象来替换用shallowRef
readonly和shallowReadonly
readonly:让一个响应式数据变为只读的(深只读),所有的数据将无法被修改
shallowReadonly:让一个响应式变为只读的(浅只读),基本数据类型无法被修改,对象可以被修改
toRaw和markRaw
toRaw将一个由reactive生成的响应式对象转为普通对象对这个普通对象的所有操作,不会引起页面更新,对ref定义的响应式数据无效!
markRow标记一个对象,使其永远不会再成为响应式对象。有些值不应该被设置为响应式的,例如复杂的第三方类库,当渲染具有不可变的数据源的大列表时,跳过响应式转换可以提高性能
响应式数据的判断
isRef:检查一个值是否为ref对象
isReactive:检查一个对象是否由reactive创建的响应式代理
isReadonly:检查一个对象是否由readonly创建的只读代理
isProxy:检查一个对象是否由reactive或者readonly方法创建的代理
provide和inject
用于实现祖与后代组件间通信
<template> <h2>我是祖组件</h2> <h3>汽车信息</h3> <p>名称:{{name}}</p> <p>价格:{{price}}</p> <inject_component></inject_component> </template> <script> import {reactive,toRefs,provide} from 'vue' export default { name: "provide_component", setup(){ let car=reactive({ name:'宝马', price:'40w' }) provide('car',car) // 提供provide return{ ...toRefs(car) } } } </script>
<template> <h2>我是孙组件</h2> <h3>汽车信息</h3> <p>名称:{{name}}</p> <p>价格:{{price}}</p> </template> <script> import {inject,toRefs,ref} from 'vue' export default { name: "inject_component", setup(){ let car=inject("car"); //使用inject接收 return{ ...toRefs(car) } } } </script>
过滤器
vue3建议使用计算属性代替过滤器,如果需要全局过滤器可以自定义全局属性
// 定义全局属性 app.config.globalProperties.$filters = { currencyUSD(value) { return '$' + value } }
标签:vue,console,name,setup,Vue3,ref,log 来源: https://www.cnblogs.com/JC30705/p/16293252.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。