vue3 组合式API
# 组合式API
Vue3.0在原来2.0版本基础上进行升级的时候,进行语法上的扩展与兼容。

快速使用
src/views/Group.vue,代码:
<script setup> import {reactive} from "vue"; //students:[] ,//学生数据 let students = reactive({ data: [ {"id":1,"name":"小明","age":17}, {"id":2,"name":"小明","age":17}, ] }); const add_student = ()=>{ //添加学生 } const get_student =()=>{ //获取学生 } const del_student =()=>{ } //courses:[] ,//课程数据 let courses = reactive({ data: [ {"id":1, "name": "python"}, {"id":2, "name": "java"}, ] }); const add_course = ()=>{ //添加课程 } const get_course=(id)=>{ //获取课程信息 } const del_course =()=>{ //删除课程 } </script> <template> </template> <style scoped> </style>
做拆分
src/views/Group.vue,代码:
<script setup> import student from "../api/student.js"; import {add_student} from "../api/student.js"; import course, {add_course} from "../api/course.js"; </script> <template> <button @click="add_student">添加学生</button> <ul> <li v-for="student in student.data">{{student}}</li> </ul> <button @click="add_course">添加课程</button> <ul> <li v-for="course in course.data">{{course}}</li> </ul> </template> <style scoped> </style>
src/api/courses.js,代码:
import {reactive} from "vue";
//courses:[] ,//课程数据
export default reactive({
  data: [
    {"id":1, "name": "python"},
    {"id":2, "name": "java"},
  ]
});
export const add_course = ()=>{
  //添加课程
  console.log("添加课程");
}
export const get_course=(id)=>{
  //获取课程信息
}
export const del_course =()=>{
  //删除课程
}
src/api/students.js,代码:
import {reactive} from "vue";
//students:[] ,//学生数据
export default reactive({
  data: [
    {"id":1,"name":"小明","age":17},
    {"id":2,"name":"小明","age":17},
  ]
});
export const add_student = ()=>{
  //添加学生
  console.log("添加学生");
}
export const get_student =()=>{
  //获取学生
}
export const del_student =()=>{
}
src/App.vue,代码:
<script setup> import List from "./views/List.vue" import Register from "./views/Register.vue"; import Goods from "./views/Goods.vue"; import Group from "./views/Group.vue"; // 使用js提供的location对象,获取url地址的路径 // script声明的所有变量都会被自动填充到data中,可以直接在template模板标签中使用 let url = location.pathname; </script> <template> <!-- <List v-if="url==='/list'"></List>--> <!-- <Register v-if="url==='/reg'"></Register>--> <!-- <Goods></Goods>--> <Group></Group> </template> <style scoped> </style>
语法代码
8.2.1 基本语法
src/GroupApi.vue
<script setup> import {ref,reactive,watch,onMounted,computed} from "vue"; /** * 声明只读变量 */ let num1 = 10; // 声明一个只读变量,无法在template中进行双向数据绑定 /** * 声明响应式变量 * ref函数的作用就是用于声明vue的基本数据类型[Number,String,Boolean/undefined/Array等]的响应式变量,可以进行双向数据绑定 * reactive 函数的作用就是用于声明vue的复杂数据类型[Object]的响应式变量,可以进行双向数据绑定 */ let num2 = ref(100); let data = ref([ {"id":1, "name": "小明", "age": 11}, {"id":2, "name": "小白", "age": 18}, {"id":3, "name": "小华", "age": 17}, {"id":4, "name": "小绿", "age": 18}, ]); let student_info = reactive({ "id": 1, "name": "小白", "age": 16 }) /** * 修改变量的操作 */ const change_data1 = ()=>{ // 修改ref响应式变量的值,需要通过value来改动 num2.value = 30000; console.log(num2); } const change_data2 = ()=>{ // 修改reactive响应式变量的值,不能修改变量本身,可以修改变量内部的属性,直接赋值即可。 student_info.age = 20 } // 监听属性写法 watch( ()=>num2.value, // 监听ref响应式变量,参数1是一个函数,返回值是被监听的ref变量的value属性 ()=>{ // 值发生改变时自动调用的代码 console.log("num2改变了",num2) } ) watch( student_info, // 监听reactive响应式变量,参数1就是被监听的reactive变量 ()=>{ console.log("student_info改变了",student_info); } ) /** * 钩子方法 */ // created 钩子,vue初始化完成时自动自动的。但是在组合API中时没有created钩子的 // 原因开发者在 <script setup>标签中缩写的所有所有代码,默认都是在created钩子中执行的。 console.log("created执行了,此时vue刚完成初始化,还是渲染template") // mounted钩子方法,在组合API中叫onMounted onMounted(()=> { // 视图被渲染以后,执行代码。 console.log("Mounted执行了,此时vue已经渲染了html内容"); }) /** * computed 计算属性 */ let data1 = ref(10); let data2 = ref(20); let result = computed(()=>{ return data1.value+data2.value; }) </script> <template> <h2>变量声明</h2> <p>num1={{num1}}</p> <input type="text" v-model="num1"> <hr> <p>num2={{num2}}</p> <input type="text" v-model="num2"> <ul> <li v-for="item in data">{{item}}</li> </ul> {{student_info}}}<br> {{student_info.name}}<br> <hr> <h2>修改变量</h2> <button @click="change_data1">修改ref数据</button> <button @click="change_data2">修改reactive数据</button> <hr> <h2>计算属性</h2> <input type="text" size="1" v-model.number="data1"> + <input type="text" v-model.number="data2"> = {{result}} </template> <style scoped> </style>
src/App.vue,代码:
<script setup> import List from "./views/List.vue" import Register from "./views/Register.vue"; import Goods from "./views/Goods.vue"; import Group from "./views/Group.vue"; import GroupApi from "./GroupApi.vue"; // 使用js提供的location对象,获取url地址的路径 // script声明的所有变量都会被自动填充到data中,可以直接在template模板标签中使用 let url = location.pathname; </script> <template> <!-- <List v-if="url==='/list'"></List>--> <!-- <Register v-if="url==='/reg'"></Register>--> <!-- <Goods></Goods>--> <!--<Group></Group>--> <GroupApi></GroupApi> </template> <style scoped> </style>
8.2.2 参数传递
父传子
在父组件中,传递数据需要通过组件标签名的属性进行传递,而子组件中,通过defineProps接受父组件传递过来的数据。
src/views/User.vue,代码:
<script setup> import Info from "./Info.vue"; import {ref} from "vue"; let str_data = ref("hello world") </script> <template> <h1>User组件</h1> <input type="text" v-model="str_data"> <Info :str_message="str_data"></Info> </template> <style scoped> </style>
src/views/Info.vue,代码:
<script setup> // import {defineProps} from "vue"; // 使用defineProps来接收父组件的数据 const props = defineProps(["str_message"]) </script> <template> <h1>Info子组件</h1> <p>子组件中接受来自父组件的数据</p> <p>{{props.str_message}}</p> </template> <style scoped> </style>
src/App.vue,代码:
<script setup> import List from "./views/List.vue" import Register from "./views/Register.vue"; import Goods from "./views/Goods.vue"; import Group from "./views/Group.vue"; import GroupApi from "./GroupApi.vue"; import User from "./views/User.vue"; // 使用js提供的location对象,获取url地址的路径 // script声明的所有变量都会被自动填充到data中,可以直接在template模板标签中使用 let url = location.pathname; </script> <template> <!-- <List v-if="url==='/list'"></List>--> <!-- <Register v-if="url==='/reg'"></Register>--> <!-- <Goods></Goods>--> <!--<Group></Group>--> <!-- <GroupApi></GroupApi>--> <User></User> </template> <style scoped> </style>

src/views/Info.vue,代码:
<script setup> // import {defineProps} from "vue"; // 使用defineProps来接收父组件的数据 const props = defineProps({ str_message:Number, }) </script> <template> <h1>Info子组件</h1> <p>子组件中接受来自父组件的数据</p> <p>{{props.str_message}}</p> </template> <style scoped> </style>

src/views/User.vue,代码:
<script setup> import Info from "./Info.vue"; import {ref} from "vue"; let str_data = ref("hello world"); let num_data = ref(10); </script> <template> <h1>User组件</h1> <input type="text" v-model="str_data"> <input type="text" v-model="num_data"> <Info :str_message="str_data" :num_message="num_data"></Info> </template> <style scoped> </style>
src/views/Info.vue,代码:
<script setup> // import {defineProps} from "vue"; // 使用defineProps来接收父组件的数据 const props = defineProps({ str_message: { type: String, default:"没有数据", }, num_message:{ type:Number, default:0, }, }) </script> <template> <h1>Info子组件</h1> <p>子组件中接受来自父组件的数据</p> <p>{{props.str_message}}</p> <p>{{props.num_message}}</p> </template> <style scoped> </style>

src/views/User.vue,代码:
<script setup> import Info from "./Info.vue"; import {ref,reactive} from "vue"; let str_data = ref("hello world"); let num_data = ref(10); let obj_data = reactive({ id:1, name: "小明", age:18, }); </script> <template> <h1>User组件</h1> <input type="text" v-model="str_data"> <input type="text" v-model="num_data"> <Info :str_message="str_data" :num_message="num_data" :obj_data="obj_data" ></Info> </template> <style scoped> </style>
src/views/Info.vue,代码:
<script setup> // import {defineProps} from "vue"; // 使用defineProps来接收父组件的数据 import {ref,watch} from "vue"; const props = defineProps({ str_message: { type: String, default:"没有数据", }, num_message:{ type:Number, default:0, }, obj_data:Object, }) let num = ref(10) watch( num, ()=>{ console.log(num.value) } ) </script> <template> <h1>Info子组件</h1> <p>子组件中接受来自父组件的数据</p> <p>{{props.str_message}}</p> <p>{{props.num_message}}</p> <input type="text" v-model="num"> <p>obj_data={{props.obj_data}}</p> </template> <style scoped> </style>
子传父
在子组件中通过defineEmits先声明要注册的事件源,然后通过defineEmits的返回值emits进行调用事件源进行参数传递,在父组件中,直接声明方法绑定到子组件标签名中即可。
src/views/Info.vue,代码:
<script setup> // import {defineProps} from "vue"; // 使用defineProps来接收父组件的数据 import {ref,watch} from "vue"; //定义事件 //注册的事件源 const emits = defineEmits(["num_change"]) // 使用defineProps来接收父组件的数据 const props = defineProps({ str_message: { type: String, default:"没有数据", }, num_message:{ type:Number, default:0, }, obj_data:Object, }) let num = ref(10) watch( num, ()=>{ console.log(num.value); emits("num_change",num); } ) </script> <template> <h1>Info子组件</h1> <p>子组件中接受来自父组件的数据</p> <p>{{props.str_message}}</p> <p>{{props.num_message}}</p> num=<input type="text" v-model="num"> <p>obj_data={{props.obj_data}}</p> </template> <style scoped> </style>
src/views/User.vue,代码:
<script setup> import Info from "./Info.vue"; import {ref,reactive} from "vue"; let str_data = ref("hello world"); let num_data = ref(10); let obj_data = reactive({ id:1, name: "小明", age:18, }); const get_num = (data)=>{ console.log("父组件中接收数据data=", data.value); } </script> <template> <h1>User组件</h1> <input type="text" v-model="str_data"> <input type="text" v-model="num_data"> <Info :str_message="str_data" :num_message="num_data" :obj_data="obj_data" @num_change="get_num" ></Info> </template> <style scoped> </style>

ref引用template标签对象[抓取标签对象]
src/views/Info.vue,代码:
<script setup> // import {defineProps} from "vue"; // 使用defineProps来接收父组件的数据 import {ref,watch} from "vue"; //定义事件 //注册的事件源 const emits = defineEmits(["num_change"]) // 使用defineProps来接收父组件的数据 const props = defineProps({ str_message: { type: String, default:"没有数据", }, num_message:{ type:Number, default:0, }, obj_data:Object, }) let num = ref(10) watch( num, ()=>{ console.log(num.value); emits("num_change",num); } ) /** * ref引用template标签对象[抓取标签对象] */ let p1 = ref(null); // 这里的p1就是<p ref="p1"> const get_ele= ()=>{ console.log(p1); // 这里的p1就是<p ref="p1"> console.log(p1.value); // 这里得到的就是原生的js的标签对象 } </script> <template> <h1>Info子组件</h1> <p>子组件中接受来自父组件的数据</p> <p>{{props.str_message}}</p> <p>{{props.num_message}}</p> num=<input type="text" v-model="num"> <p ref="p1" @click="get_ele">obj_data={{props.obj_data}}</p> </template> <style scoped> </style>
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号