• VUE在项目中的使用


    目录

    vue项目的创建

    单文件组件

    组件的组织

    props组件交互

    将message与age传递给组件MyComponent

    组件接收值

    自定义事件的组件交互

    子组件传递参数

    父组件接收子组件参数

    组件的生命周期

    生命周期时的状态

    vue引入第三方

    axios网络请求

    使用前

    使用案例 

    快捷方案

    全局引用axios

    axios网络请求的封装

    网络请求的跨域解决方案

    js采取的是同源策略

    非同源限制

    解决跨域问题的方案

    前台跨域解决案例

    vue引入路由配置

    路由传递参数

    嵌套路由

    vue状态管理

    配置vuex文件

    在主文件中引入vuex

    在组件中读取状态

    方式一 

    方式二 

    vuex状态管理的核心

    Getter

    Mutation

    Action

    第一种方式 

    第二种方式

    vue3新特性

    组合式API

    ref或者reactive

    setup中使用props和context

    在setup中使用生命周期函数

    provide/inject

    前言

    父组件向子组件传递信息

    子组件从父组件接收信息

    fragment-碎片

    vue项目的创建

    安装vue工具vue cli

    vue cli是vue.js的开发标准工具,vue cli是一个基于vue.js进行快速开发的完整系统

    全局安装vue cli:npm install -g @vue/cli

    验证安装是否成功:vue -V

    创建一个项目

    npx vue create vue-demo

    注意:项目名无论如何都不能出现大写,必须全小写,但是可以用-来链接多个单词

     

    注意:

    • 在控制台中可以用上下按键来调整选择项
    • 在控制台中,可以使用空格选择是否选中或取消
    • 我们选择第三个手动选择特性 

    我们如图选中即可,注意关闭linter/formatter校检

    我们选择版本3

    询问配置文件的存放位置,我们选择第一个

    是否保存预设,我选n

    用什么包管理-npm因为使得熟

    成功哩

    运行项目

    1. 进入项目根目录:cd vue-demo
    2. 运行npm run serve启动项目 

    进入local:后面的地址(其实哪个都行)

    单文件组件

    Vue单文件组件(又名.vue文件,缩写为SFC)是一种特殊的文件格式,他允许将Vue组建的模板、逻辑与样式封装在单个文件中

    1. <template>
    2. <h3>我是单文件组件h3>
    3. template>
    4. <script>
    5. export default{
    6. name:"MyConponent"/* 组件名称 */
    7. }
    8. script>
    9. <style scoped>
    10. h3{
    11. background: red;
    12. }
    13. style>

    scoped属性:该属性表示css标签样式只在当前组件内有效

    组件内部元素

    • template:视图结构部分
    • script:逻辑部分
    • style:样式部分

    加载组件

    • 第一步:引入组件:import HelloWorld from './components/HelloWorld.vue'
    • 第二步:挂载组件:components: {HelloWorld}
    • 第三步:显示组件:

    组件的组织

    通常一个应用会以一棵嵌套的组件树的形式来组织

    props组件交互

    props是可以在组件之上进行传递数据的

    将message与age传递给组件MyComponent

    1. <template>
    2. <my-component :message="message" :age="age" :names="names">my-component>
    3. template>
    4. <script>
    5. import MyComponent from './components/MyComponent.vue'
    6. export default {
    7. name: 'App',
    8. data() {
    9. return {
    10. message:"总有一天,我便超越这个世界",
    11. age:20,
    12. names:["lili","makabaka","tangbulibou"]
    13. }
    14. },
    15. components: {
    16. MyComponent
    17. }
    18. }
    19. script>

    组件接收值

    1. <template>
    2. <h3>props传递数据h3>
    3. <p>{{message}}p>
    4. <p>{{age}}p>
    5. <ul>
    6. <li v-for="(item,index) in names" :key="index">{{item}}li>
    7. ul>
    8. template>
    9. <script>
    10. export default{
    11. name:"MyConponent",/* 组件名称 */
    12. props:{
    13. message:{
    14. type:String,/* 组件接受的值为string类型 */
    15. default:""/* 如果不传值则组件默认值为空串 */
    16. },
    17. age:{
    18. type:Number,
    19. default:0
    20. },
    21. names:{
    22. type:Array,
    23. /* 数组和对象必须使用函数进行返回 */
    24. default:function(){
    25. return []
    26. }
    27. }
    28. }
    29. }
    30. script>

    理解:两个组件通过v-bind:进行连接,子组件通过props属性对床过来的数据进行接收

    自定义事件的组件交互

    自定义事件可以在组件中反向传递,props可以将数据从父组件传递到子组件,那么反向如何操作呢,就可以利用自定义事件实现$emit

    子组件传递参数

    1. <template>
    2. <h3>自定义事件的组件交互h3>
    3. <button @click="sendClickHandle()">点击传递事件button>
    4. template>
    5. <script>
    6. export default{
    7. name:"MyConponent",/* 组件名称 */
    8. data() {
    9. return {
    10. message:"我变大神,那是必然"
    11. }
    12. },
    13. methods: {
    14. sendClickHandle(){
    15. /* 参数1:字符串-事件名称
    16. 参数2:传递的数据-事件参数 */
    17. this.$emit("onevent",this.message)/* 自定义事件 */
    18. }
    19. },
    20. }
    21. script>

    父组件接收子组件参数

    1. <template>
    2. <my-component @onevent="getDataHandle">my-component>
    3. template>
    4. <script>
    5. import MyComponent from './components/MyComponent.vue'
    6. export default {
    7. name: 'App',
    8. components: {
    9. MyComponent
    10. },
    11. methods: {
    12. /* 里面的参数为自定义事件传递数据的参数 */
    13. getDataHandle(data){
    14. console.log(data);
    15. }
    16. },
    17. }
    18. script>

    理解:点击事件触发sendClickHandle函数,此函数触发自定义事件onevent并将参数带入父组件,父组件事件已被触发调用带参数的getDataHandle方法来获得数据

    组件的生命周期

    每个组件在被创建时都要经过一系列的初始化过程--例如,需要设置数据监听、编译模板、将实例挂载到dom并在数据变化时更新dom等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己代码的机会

    生命周期时的状态

    1. 创建时:beforeCreate、created
    2. 渲染时:beforeMount、mounted
    3. 更新时:beforeUpdate、updated
    4. 卸载时:beforeUnmount、unmounted
    1. <template>
    2. <h3>生命周期函数h3>
    3. <input type="text" v-model.lazy="msg">
    4. <p>{{msg}}p>
    5. template>
    6. <script>
    7. export default{
    8. name:"mycomponent",
    9. data() {
    10. return {
    11. msg:""
    12. }
    13. },
    14. beforeCreate() {
    15. console.log("组件创建之前");
    16. },
    17. created() {
    18. console.log("组件创建之后");
    19. },
    20. beforeMount() {
    21. console.log("组件挂载前");
    22. },
    23. mounted() {
    24. console.log("组件挂载后");
    25. },
    26. beforeUpdate() {
    27. console.log("组件更新前");
    28. },
    29. updated() {
    30. console.log("组件更新后");
    31. },
    32. beforeUnmount() {
    33. console.log("组件卸载前");
    34. },
    35. unmounted() {
    36. console.log("组件卸载后");
    37. },
    38. }
    39. script>

    vue引入第三方

    以swiper为例

    • swiper开源、免费、强大的触摸滑动插件
    • swiper是纯javascript打造的滑动特效插件,面向手机、平板电脑等移动终端
    • swiper能实现触摸焦点图、触屏tab切换、触屏轮播图切换等常用效果

    安装swiper:npm i --save swiper

    1. <template>
    2. <div id="a">
    3. <swiper>
    4. <swiper-slide class="mySwiper">
    5. <img src="../assets/test.jpg" alt="图片没了">
    6. swiper-slide>
    7. <swiper-slide>
    8. <img src="../assets/test.jpg" alt="图片没了">
    9. swiper-slide>
    10. <swiper-slide>
    11. <img src="../assets/test.jpg" alt="图片没了">
    12. swiper-slide>
    13. swiper>
    14. div>
    15. template>
    16. <script>
    17. // 引入轮播图组件
    18. import {Swiper,SwiperSlide} from "swiper/vue"
    19. import "swiper/css"
    20. export default{
    21. name:"mycomponent",
    22. // 注册组件
    23. components:{
    24. Swiper,
    25. SwiperSlide,
    26. }
    27. }
    28. script>

    axios网络请求

    使用前

    axios是一个基于promise的网络请求库

    安装axios:npm install --save axios

    安装querystring:npm install --save querystring

    组件中引入:

    import axios from axios

    import querystring from "querystring"

    使用案例 

    1. <template>
    2. <div id="a">
    3. {{msg}}
    4. div>
    5. template>
    6. <script>
    7. import axios from "axios"
    8. import querystring from "querystring"
    9. export default{
    10. name:"mycomponent",
    11. data() {
    12. return {
    13. msg:""
    14. }
    15. },
    16. mounted() {
    17. // get请求方式
    18. axios({
    19. method:"get",
    20. url:"https://limestart.cn/"
    21. }).then(res =>{
    22. console.log(res.data);
    23. this.msg=res.data
    24. })
    25. // post请求参数
    26. axios({
    27. method:"post",
    28. url:"http://iwenwiki.com/api/blueberrypai/login.php",
    29. data:querystring.stringify({
    30. user_id:"iwen@qq.com",
    31. password:"iwen123",
    32. verification_code:"crfvw"
    33. })
    34. }).then(res=>{
    35. console.log(res.data);
    36. })
    37. },
    38. }
    39. script>

    注意:data里面的数据必须传递为json格式

    快捷方案

    1. <template>
    2. <div id="a">
    3. {{msg}}
    4. div>
    5. template>
    6. <script>
    7. import axios from "axios"
    8. import querystring from "querystring"
    9. export default{
    10. name:"mycomponent",
    11. data() {
    12. return {
    13. msg:""
    14. }
    15. },
    16. mounted() {
    17. // get请求方式
    18. axios.get("https://limestart.cn/")
    19. .then(res=>{
    20. console.log(res.data);
    21. })
    22. // post请求参数
    23. axios.post("http://iwenwiki.com/api/blueberrypai/login.php",querystring.stringify({
    24. user_id:"iwen@qq.com",
    25. password:"iwen123",
    26. verification_code:"crfvw"
    27. })).then(res=>{
    28. console.log(res.data);
    29. })
    30. },
    31. }
    32. script>

    全局引用axios

    1. import { createApp } from 'vue'
    2. import App from './App.vue'
    3. import './registerServiceWorker'
    4. /* 引入axios */
    5. import axios from "axios"
    6. const app=createApp(App)
    7. /*将axios挂载到全局 */
    8. app.config.globalProperties.$axios=axios
    9. // 使用时直接this.$axios()来调用axios
    10. app.mount('#app')

    axios网络请求的封装

    在日常应用过程中,一个项目中的网络请求会很多,此时一般采用的方案是将网络请求封装起来

    封装方案

    安装axios:npm install --save axios

    安装querystring:npm install --save querystring

    组件中引入:

    import axios from axios

    import querystring from "querystring"

    1. import axios from "axios"
    2. import querystring from "querystring"
    3. const errorHandle=(status,info)=>{
    4. switch(status){
    5. case 400:
    6. console.log("语义有误");
    7. break
    8. case 401:
    9. console.log("服务器认证失败");
    10. break
    11. case 403:
    12. console.log("服务器拒绝访问");
    13. break
    14. case 404:
    15. console.log("地址错误");
    16. break
    17. case 500:
    18. console.log("服务器遇到意外");
    19. break
    20. case 502:
    21. console.log("服务器无响应");
    22. break
    23. default:
    24. console.log(info);
    25. break
    26. }
    27. }
    28. /* 创建自己的网络请求对象 */
    29. const instance=axios.create({
    30. /* 网络请求的公共配置 */
    31. timeout:5000
    32. })
    33. //拦截器常用
    34. //发送数据之前
    35. instance.interceptors.request.use(
    36. //拦截成功执行的函数
    37. //config包含网络请求的所有信息
    38. config=>{
    39. if(config.methods==="post"){
    40. /* 转化post请求参数格式 */
    41. config.data=querystring.stringify(config.data)
    42. }
    43. return config
    44. },
    45. //拦截失败执行的函数
    46. error=>{
    47. return Promise.reject(error)
    48. }
    49. )
    50. //获取数据之前
    51. instance.interceptors.response.use(
    52. //成功时返回结果
    53. response=>{
    54. return response.status===200?Promise.resolve(response):Promise.reject(response)
    55. },
    56. //失败时返回结果
    57. error=>{
    58. const {response}=error
    59. // 错误处理才是重中之重
    60. errorHandle(response.status,response.info)
    61. }
    62. )
    63. export default instance

    网络请求的跨域解决方案

    js采取的是同源策略

    同源策略是浏览器的一项安全策略,浏览器只允许js代码请求和当前所在服务器域名、端口、协议相同的数据接口上的数据,这就是同源策略

    理解:当协议、域名、端口号任意一个不相同时,都会产生跨域问题

    非同源限制

    • 无法读取非同源网页的cookie、localStorage和IndexedDB
    • 无法接触非同源网页的dom
    • 无法向非同源地址发送ajax请求 

    解决跨域问题的方案

    • 后台解决:cors
    • 前台解决:proxy

    前台跨域解决案例

    1. <script>
    2. import axios from "axios"
    3. export default{
    4. name:"mycomponent",
    5. mounted() {
    6. /* 删掉前面的地址 */
    7. axios.get("/api/FingerUnion/list.php")//跨域了
    8. .then(res=>{
    9. console.log(res.data);
    10. })
    11. },
    12. }
    13. script>
    1. //vue.config.js中
    2. const { defineConfig } = require('@vue/cli-service')
    3. module.exports = defineConfig({
    4. transpileDependencies: true,
    5. /* 解决跨域问题的配置 */
    6. devServer:{
    7. proxy:{
    8. "/api":{
    9. target:"http://iwenwiki.com",/* 参数为产生跨域的域名地址 */
    10. changeOrigin:true
    11. }
    12. }
    13. }
    14. })

    注意:解决完跨域之后,要记得重启服务器

    vue引入路由配置

    在vue中,我们可以通过vue-router路由管理页面之间的关系
    vue router是vue.js的官方路由。他与vue.js核心深度集成,让vue.js构建单页面应用轻而易举

    在vue中引入路由

    安装路由:npm install --save vue-router

    配置独立的路由文件

    在src文件下新建一个文件夹router里面建一个index.js文件作为路由的配置文件

    1. // 路由配置文件index.js
    2. //引入路由,第一个为了创建路由对象,第二个为路由配置需要的一个选项
    3. import {createRouter,createWebHashHistory} from "vue-router"
    4. //配置信息中需要页面的相关配置在src文件夹下建一个views文件夹,在文件夹建文件HomeView.vue与AboutView.vue组件
    5. import HomeView from "../views/HomeView"
    6. import AboutView from "../views/AboutView"
    7. //配置路由
    8. const routes=[
    9. {path:"/",component:HomeView},
    10. {path:"/about",component:AboutView}
    11. ]
    12. // 创建路由
    13. const router=createRouter({
    14. history:createWebHashHistory(),/* 访问方式 */
    15. /* createWebHistory这种方式需要后台配合1做重定向,否则会出现404问题*/
    16. routes
    17. })
    18. export default router

    注意:提前创建好两个组件HomeView.vue与AboutView.vue组件

    1. // main.js内
    2. import { createApp } from 'vue'
    3. import App from './App.vue'
    4. import './registerServiceWorker'
    5. // 全局引入路由
    6. import router from "./router/index.js"
    7. const app=createApp(App)
    8. // 使用路由
    9. app.use(router).mount('#app')
    1. <template>
    2. <router-link to="/">首页router-link> |
    3. <router-link to="/about">关于router-link>
    4. <router-view>router-view>
    5. template>
    6. <script>
    7. export default {
    8. name: 'App',
    9. components: {
    10. }
    11. }
    12. script>

    路由传递参数

    路由是管理页面之间的跳转关系的,在跳转的过程中,页面与页面之间也需要传递参数

    1. const routes=[
    2. {path:"/",component:HomeView},
    3. {path:"/about",component:AboutView},
    4. /* 异步加载方式:如果页面没有被显示出来component后面的代码是不会执行的,不会执行的话就节省了内存空间 */
    5. {path:"/news",component:()=>import("../views/NewsView.vue")},
    6. //路由传参
    7. {path:"/newsdetails/:name",component:()=>import("../views/NewsDetails")}
    8. ]

    在path路径下加:属性名(:属性名就相当于一个路径的占位符)也可以写多个属性

    1. <template>
    2. <h3>新闻h3>
    3. <ul>
    4. <li><router-link to="/newsdetails/百度">baidu新闻router-link> li>
    5. <li><router-link to="/newsdetails/网易">网易新闻router-link> li>
    6. <li><router-link to="/newsdetails/头条">头条新闻router-link> li>
    7. ul>
    8. template>

    在此文件内要跳转的的路径后加参数,此参数可以传递给上面path路径的name属性

    1. <template>
    2. <div>新闻详情div>
    3. <p>{{$route.params.name}}p>
    4. template>

    通过$route.params.属性来获取传过来的值

    嵌套路由

    1. //配置路由
    2. const routes=[
    3. {path:"/",component:HomeView},
    4. { path:"/about",component:()=>import("../views/AboutView.vue"),
    5. redirect:"/about/us",/* 路由重定向 */
    6. children:[
    7. /* 注意:子路由路径前面不带/ */
    8. {path:"us",component:()=>import("../views/aboutsub/AboutUs")},
    9. {path:"info",component:()=>import("../views/aboutsub/AboutInfo")}
    10. ]
    11. }
    12. ]
    1. <template>
    2. <div class="about">
    3. <router-link to="/about/us">关于我们router-link> |
    4. <router-link to="/about/info">关于信息router-link>
    5. <router-view>router-view>
    6. div>
    7. template>

    vue状态管理

    vuex是一个专门为vue.js应用程序开发的状态管理模式+库。他采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化

    简单来说,状态管理可以理解成:为了更方便的管理组件之间的数据交互,提供了一个集中式的管理方案,任何组件都可以按照指定的方式进行读取和改变数据

    使用vuex

    安装vuex:npm install --save vuex

    配置vuex文件

    在src目录中新建一个store文件夹存放index.js文件

    1. // index.js内
    2. import {createStore} from "vuex"
    3. // vuex的核心作用就是帮我们管理组件之间的状态
    4. const store=createStore({
    5. // 通过state对象进行存储
    6. state:{
    7. //模拟的数据
    8. counter:0
    9. }
    10. })
    11. export default store

    在主文件中引入vuex

    1. import { createApp } from 'vue'
    2. import App from './App.vue'
    3. import './registerServiceWorker'
    4. /* 全局引入vuex */
    5. import store from "./store"
    6. const app=createApp(App)
    7. //将vuex注册
    8. app.use(store).mount('#app')

    在组件中读取状态

    方式一 

    1. <template>
    2. <div class="hello">
    3. {{counter}}
    4. div>
    5. template>
    6. <script>
    7. //引入mapState从vuex
    8. import { mapState } from 'vuex'
    9. export default {
    10. name: 'HelloWorld',
    11. computed:{
    12. ...mapState(["counter"])
    13. }
    14. }
    15. script>

    方式二 

    1. <template>
    2. <p>{{$store.state.counter}}p>
    3. template>

    vuex状态管理的核心

    常用的核心概念包括:State、Getter、Mulation、Action

    Getter

    作用:对vuex中的数据进行过滤(对读取的方式提供一种更合理的方式)

    1. import { createStore } from 'vuex'
    2. export default createStore({
    3. /* 注意state不能更改 */
    4. state: {
    5. /* 数据名称随便起 */
    6. counter:10
    7. },
    8. getters: {
    9. getCounter(state){
    10. /* counter数据深层的管理 */
    11. return state.counter>0?state.counter:"counter数据异常"
    12. }
    13. },
    14. })
    1. <template>
    2. <div class="hello">
    3. <h1>HelloWorldh1>
    4. <p>counter={{$store.getters.getCounter}}p>
    5. {{getCounter}}
    6. div>
    7. template>
    8. <script>
    9. /* 引入mapgetters */
    10. import { mapGetters } from "vuex";
    11. export default {
    12. name: 'HelloWorld',
    13. computed:{
    14. ...mapGetters(["getCounter"])
    15. }
    16. }
    17. script>

    Mutation

    更改vuex的store中状态的唯一方法是提交mutation。vuex中的mutation非常类似于事件:每个mutation都有一个字符串的事件类型(type)和一个回调函数(handler),这个回调函数就是我们实际进行状态更改的地方,并且他会接收state作为第一个参数 

    1. import { createStore } from 'vuex'
    2. export default createStore({
    3. state:{
    4. counter:10
    5. },
    6. /* 更改state状态 */
    7. mutations: {
    8. addCounter(state,num){
    9. state.counter+=num
    10. }
    11. /* 注意:任何组件对值得引用都可以得到相应的修改 */
    12. },
    13. })

    方式一 

    1. <template>
    2. <div class="hello">
    3. <h1>HelloWorldh1>
    4. <p>counter={{$store.getters.getCounter}}p>
    5. <button @click="addClickHandler">增加button>
    6. div>
    7. template>
    8. <script>
    9. /* 引入mapgetters */
    10. import { mapGetters } from "vuex";
    11. export default {
    12. name: 'HelloWorld',
    13. methods: {
    14. /* mutation调用函数 */
    15. addClickHandler(){
    16. /* 固定调用方式 */
    17. this.$store.commit("addCounter",15)
    18. }
    19. },
    20. }
    21. script>

    方式二

    1. <template>
    2. <div class="hello">
    3. <h1>HelloWorldh1>
    4. <p>counter={{$store.getters.getCounter}}p>
    5. <button @click="addClickHandler">增加button>
    6. div>
    7. template>
    8. <script>
    9. /* 引入mapMutations */
    10. import { mapMutations } from "vuex";
    11. export default {
    12. name: 'HelloWorld',
    13. methods: {
    14. /* mutation调用函数 */
    15. ...mapMutations(["addCounter"]),
    16. addClickHandler(){
    17. this.addCounter(20)
    18. }
    19. },
    20. }
    21. script>

    Action

    Action类似于Mutation不同在于

    • Action提交的是mutation,而不是直接变更状态
    • Mutation只允许同步操作,不允许异步操作;Action可以包含任意异步操作
    1. import { createStore } from 'vuex'
    2. import axios from "axios"
    3. export default createStore({
    4. state:{
    5. counter:10
    6. },
    7. getters:{
    8. getCounter(state){
    9. return state.counter>0?state.counter:"counter数据异常"
    10. }
    11. },
    12. /* 更改state状态 */
    13. mutations: {
    14. addCounter(state,num){
    15. state.counter+=num
    16. }
    17. /* 注意:任何组件对值得引用都可以得到相应的修改 */
    18. },
    19. /* 为异步操作所准备 */
    20. actions:{
    21. /* commit就是为了调用mutation里的方法的 */
    22. asyncAddCounter({commit}){
    23. axios.get("http://iwenwiki.com/api/generator/list.php")
    24. .then(res=>{
    25. commit("addCounter",res.data[0])
    26. })
    27. }
    28. }
    29. })

    第一种方式 

    1. <template>
    2. <div class="hello">
    3. <h1>HelloWorldh1>
    4. <p>counter={{$store.getters.getCounter}}p>
    5. <button @click="addAsyncClickHandler">异步增加button>
    6. div>
    7. template>
    8. <script>
    9. export default {
    10. name: 'HelloWorld',
    11. methods: {
    12. addAsyncClickHandler(){
    13. /* 固定写法,第一种方式 */
    14. this.$store.dispatch("asyncAddCounter")
    15. }
    16. },
    17. }
    18. script>

    第二种方式

    1. <template>
    2. <div class="hello">
    3. <h1>HelloWorldh1>
    4. <p>counter={{$store.getters.getCounter}}p>
    5. <button @click="addAsyncClickHandler">异步增加button>
    6. div>
    7. template>
    8. <script>
    9. import { mapActions } from "vuex";
    10. export default {
    11. name: 'HelloWorld',
    12. methods: {
    13. ...mapActions(["asyncAddCounter"]),
    14. addAsyncClickHandler(){
    15. /* 第二种方式 */
    16. this.asyncAddCounter();
    17. }
    18. },
    19. }
    20. script>

    vue3新特性

    组合式API

    ref或者reactive

    1. <template>
    2. <div class="hello">
    3. <h1>组合式APIh1>
    4. <p>{{message}}p>
    5. <ul>
    6. <li v-for="(item,index) in names.list" :key='index'>{{item}} li>
    7. ul>
    8. <button @click="clickHandle">按钮button>
    9. div>
    10. template>
    11. <script>
    12. import { ref,reactive } from 'vue'
    13. export default {
    14. name: 'HelloWorld',
    15. /* 组合式API */
    16. setup(){//类似于data功能
    17. //ref基本类型使用比较高
    18. const message=ref("我是个消息")
    19. //一般用reactive声明对象数组等复杂一点的数据
    20. const names=reactive({list:["lili","lala","lan"]})
    21. /* 以前定义在methods里的东西可以定义在setup中了 */
    22. function clickHandle(){
    23. message.value="看不见我"
    24. }
    25. return{
    26. message,names,clickHandle
    27. }
    28. }
    29. }
    30. script>

    setup中使用props和context

    在2.x中,组件的方法可以通过this获取到当前组件的实例,并执行data变量的修改,方法的调用,组件的通信等等,但在3.x中,setup()在beforeCreate和Created时机就已经调用,无法使用和2.x一样的this,但是可以通过接收setup(props,ctx)的方法,获取当前组件的实例ctx和props

    1. <template>
    2. <HelloWorld msg="数据"/>
    3. template>
    4. <script>
    5. import HelloWorld from './components/HelloWorld.vue'
    6. export default {
    7. name: 'App',
    8. components: {
    9. HelloWorld
    10. }
    11. }
    12. script>
    1. <template>
    2. <div class="hello">
    3. <h1>组合式APIh1>
    4. {{msg}}
    5. div>
    6. template>
    7. <script>
    8. export default {
    9. name: 'HelloWorld',
    10. /* 组合式API */
    11. /*里面也可以传props */
    12. props:{
    13. msg:String
    14. },
    15. setup(props,ctx){//类似于data功能
    16. console.log(this); /* setup中没有this关键字 */
    17. console.log(ctx); /* setup中ctx就相当于this关键字 */
    18. console.log(props.msg);
    19. }
    20. }
    21. script>

    在setup中使用生命周期函数

    可以通过生命周期钩子函数前面加"on" 来访问组件的生命周期钩子

    1. <template>
    2. <div class="hello">
    3. <h1>生命周期函数h1>
    4. div>
    5. template>
    6. <script>
    7. /* 使用生命周期函数时必须引入 */
    8. import {onMounted} from "vue"
    9. export default {
    10. name: 'HelloWorld',
    11. props:{
    12. msg:String
    13. },
    14. setup(props,ctx){
    15. /* 没有调用,自动执行,还比以前有优势,以前同一个生命周期函数只能存在一个,现在可以存在多个 */
    16. onMounted(() => {
    17. console.log("挂载后");
    18. })
    19. onMounted(() => {
    20. console.log("挂载后的第二个生命周期函数");
    21. })
    22. }
    23. }
    24. script>

    provide/inject

    前言

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

    父组件向子组件传递信息

    1. <template>
    2. <img alt="Vue logo" src="./assets/logo.png">
    3. <HelloWorld msg="数据"/>
    4. template>
    5. <script>
    6. import HelloWorld from './components/HelloWorld.vue'
    7. /* 引入provide */
    8. import { provide } from 'vue'
    9. export default {
    10. name: 'App',
    11. components: {
    12. HelloWorld
    13. },
    14. setup(){
    15. /* 传递信息 */
    16. provide("message","我是消息信息")
    17. }
    18. }
    19. script>

    子组件从父组件接收信息

    1. <template>
    2. <div class="hello">
    3. {{val}}
    4. div>
    5. template>
    6. <script>
    7. /* 引入inject接收消息 */
    8. import { inject } from 'vue'
    9. export default {
    10. name: 'HelloWorld',
    11. props:{
    12. msg:String
    13. },
    14. setup(){
    15. const val=inject("message")
    16. return{
    17. val
    18. }
    19. }
    20. }
    21. script>

    fragment-碎片

    作用:不再限于模板中只有一个根节点

    1. <template>
    2. <div>道生一div>
    3. <div>一生二div>
    4. template>

  • 相关阅读:
    day57【动态规划】647.回文子串 516.最长回文子序列
    常用LINUX配置及SHELL命令集锦-网络配置和系统管理操作
    【CSS】自定义进度条
    袖口收缩包装机包装效果如何调整
    Java —— 抽象类和接口
    源码层面理解 LiveData 各种特性的实现原理
    C语言:输入t行字符串,每行字符串有10个字符
    mac 本地搭建go-admin之vue打包(二)
    Spring学习笔记(三十七)——Flyway 数据库版本控制
    面试:Sqlite的线程、进程安全性
  • 原文地址:https://blog.csdn.net/m0_60027772/article/details/125847564