JavaWeb,Vue的学习(下)

Router路由

路由(Router)简介

  • 定义:路由就是根据不同的 URL 地址展示不同的内容或页面。
  • 通俗理解:路由就像是一个地图,我们要去不同的地方,需要通过不同的路线进行导航。

路由的作用

  • 单页应用程序(SPA)中,路由可以实现不同视图之间的无刷新切换,提升用户体验;
  • 路由还可以实现页面的认证和权限控制,保护用户的隐私和安全;
  • 路由还可以利用浏览器的前进与后退,帮助用户更好地回到之前访问过的页面。

路由的例子:

有四个组件,分别是Add、List、Update、Home,以Home为例,其他的组件将单词Home换了即可:

Home组件:

<script setup>

</script>

<template>
  <div>
   <h1>HOME</h1>
  </div>
</template>

<style scoped>

</style>

准备路由配置:

router.js:

// 导入创建路由对象需要使用的函数
import {createRouter,createWebHashHistory} from 'vue-router'
// 导入.vue组件
import Home from '../components/Home.vue'
import List from '../components/list.vue'
import Update from '../components/Update.vue'
import Add from '../components/Add.vue'
// 创建一个路由对象
const router = createRouter({
    // history属性用于记录路由的历史
    history:createWebHashHistory(),
    // routes用于定义多个不同的路径和组件之间的对应关系
    routes:[
        {
            path:"/home",
            component:Home
        },
        {
            path:"/list",
            component:List
        },
        {
            path:"/add",
            component:Add
        },
        {
            path:"/update",
            component:Update
        }
    ]
})
//向外暴露路由对象
export default router

main.js:

import { createApp } from 'vue'

import App from './App.vue'

//在整个App.vue中可以使用路由
import router from './routers/router'
const app = createApp(App)
app.use(router)
app.mount('#app')

主页面:

App.vue:

<script setup>

</script>

<template>
  <div>
    App开头的内容
    <router-link to="/home">home</router-link><br>
    <router-link to="/list">list</router-link><br>
    <router-link to="/update">update</router-link>
    <router-link to="/add">add</router-link>
    <hr>
    <!-- 该标签会被替换为具体的.vue -->
   <router-view></router-view>
   <hr>
   App结尾的内容
  </div>
</template>

<style scoped>

</style>

 

点击相应的紫色的单词,下划线中间的组件对应的页面就会发生改变,路由就是可以将不同的组件对应的页面进行切换

要让不同的按钮对应不同的router-view,要使用其name属性,例:

  • App.vue
<script setup>
</script>

<template>
    <div>
      <h1>App页面</h1>
      <hr/>
        <!-- 路由的连接 -->
        <router-link to="/">home页</router-link> <br>
        <router-link to="/list">list页</router-link> <br>
        <router-link to="/add">add页</router-link> <br>
        <router-link to="/update">update页</router-link> <br>
      <hr/>
      <!-- 路由连接对应视图的展示位置 -->
      <hr>
      默认展示位置:<router-view></router-view>
      <hr>
      Home视图展示:<router-view name="homeView"></router-view>
      <hr>
      List视图展示:<router-view name="listView"></router-view>
      <hr>
      Add视图展示:<router-view name="addView"></router-view>
      <hr>
      Update视图展示:<router-view name="updateView"></router-view>
    </div>
</template>

<style scoped>
</style>

4 准备路由配置

  • src/routers/router.js
// 导入路由创建的相关方法
import {createRouter,createWebHashHistory} from 'vue-router'

// 导入vue组件
import Home from '../components/Home.vue'
import List from '../components/List.vue'
import Add from '../components/Add.vue'
import Update from '../components/Update.vue'

// 创建路由对象,声明路由规则
const router = createRouter({
    //createWebHashHistory() 是 Vue.js 基于 hash 模式创建路由的工厂函数。在使用这种模式下,路由信息保存在 URL 的 hash 中,
    //使用 createWebHashHistory() 方法,可以创建一个路由历史记录对象,用于管理应用程序的路由。在 Vue.js 应用中,
    //通常使用该方法来创建路由的历史记录对象。
    //就是路由中缓存历史记录的对象,vue-router提供
    history: createWebHashHistory(),
    routes:[
        {
            path:'/',
            /*
                component指定组件在默认的路由视图位置展示
                components:Home
                components指定组件在name为某个值的路由视图位置展示
                components:{
                    default:Home,// 默认路由视图位置
                    homeView:Home// name为homeView的路由视图位置
                }
            */
            components:{
                default:Home,
                homeView:Home
            }
        },
        {
            path:'/list',
            components:{
                listView : List
            }
        },
        {
            path:'/add',
            components:{
                addView:Add
            }
        },
        {
            path:'/update',
            components:{
                updateView:Update
            }
        },
    ]

})

// 对外暴露路由对象
export default router;

编程式路由

普通路由

  • <router-link to="/list">list页</router-link>这种路由,to中的内容目前是固定的,点击后只能切换/list对象组件(声明式路由)

编程式路由

  • 通过useRouter,动态决定向那个组件切换的路由
  • 在 Vue 3 和 Vue Router 4 中,可以使用 useRouter 来实现动态路由(编程式路由)
  • 这里的 useRouter 方法返回的是一个 router 对象,可以用它来做如导航到新页面、返回上一页面等操作。

例:

<script setup type="module">

  import {useRouter} from 'vue-router'
  import {ref} from 'vue'
  //创建动态路由对象
  let router = useRouter()

  let  routePath =ref('')
  let  showList= ()=>{
      // 编程式路由
      // 直接push一个路径
      //router.push('/list')
      // push一个带有path属性的对象
      router.push({path:'/list'})
  }
</script>

<template>
    <div>
      <h1>App页面</h1>
      <hr/>
        <!-- 路由的连接 -->
        <router-link to="/">home页</router-link> <br>
        <router-link to="/list">list页</router-link> <br>
        <router-link to="/showAll">showAll页</router-link> <br>
        <router-link to="/add">add页</router-link> <br>
        <router-link to="/update">update页</router-link> <br>
        <!-- 动态输入路径,点击按钮,触发单击事件的函数,在函数中通过编程是路由切换页面 -->
        <button @click="showList()">showList</button> <br>
      <hr/>
      <!-- 路由连接对应视图的展示位置 -->
      <hr>
      默认展示位置:<router-view></router-view>
      <hr>
      Home视图展示:<router-view name="homeView"></router-view>
      <hr>
      List视图展示:<router-view name="listView"></router-view>
      <hr>
      Add视图展示:<router-view name="addView"></router-view>
      <hr>
      Update视图展示:<router-view name="updateView"></router-view>
    </div>
</template>

<style scoped>
</style>

路由传参

路径参数

在路径中使用一个动态字段来实现,称之为路径参数

在router.js文件中,要使用路径参数的组件的path中应该使用占位符(:参数名)

调用具体的参数用:路由对象名.params.参数名

  • 例如: 查看数据详情 /showDetail/1 ,1就是要查看详情的id,可以动态添值

键值对参数

  • 类似与get请求通过url传参,数据是键值对形式的
    • 例如: 查看数据详情/showDetail?hid=1,hid=1就是要传递的键值对参数
    • 在 Vue 3 和 Vue Router 4 中,可以使用 useRoute 这个函数从 Vue 的组合式 API 中获取路由对象。
    • useRoute 方法返回的是当前的 route 对象,可以用它来获取关于当前路由的信息,如当前的路径、查询参数等。

调用具体的参数使用:路由对象名.query.参数名

例:

<script setup type="module">

  import {useRouter} from 'vue-router'

  //创建动态路由对象
  let router = useRouter()
  //动态路由路径传参方法
  let showDetail= (id,language)=>{
      // 尝试使用拼接字符串方式传递路径参数
      //router.push(`showDetail/${id}/${languange}`)
      /*路径参数,需要使用params  */
      router.push({name:"showDetail",params:{id:id,language:language}})
  }
  let showDetail2= (id,language)=>{
      /*uri键值对参数,需要使用query */
      router.push({path:"/showDetail2",query:{id:id,language:language}})
  }
</script>

<template>
    <div>
      <h1>App页面</h1>
      <hr/>
      <!-- 路径参数   -->
      <router-link to="/showDetail/1/JAVA">showDetail路径传参显示JAVA</router-link>
      <button @click="showDetail(1,'JAVA')">showDetail动态路由路径传参显示JAVA</button>
      <hr/>
      <!-- 键值对参数 -->
      <router-link v-bind:to="{path:'/showDetail2',query:{id:1,language:'Java'}}">showDetail2键值对传参显示JAVA</router-link>
      <button @click="showDetail2(1,'JAVA')">showDetail2动态路由键值对传参显示JAVA</button>
      <hr>
      showDetail视图展示:<router-view name="showDetailView"></router-view>
      <hr>
      showDetail2视图展示:<router-view name="showDetailView2"></router-view>
    </div>
</template>

<style scoped>
</style>

路由守卫

在 Vue 3 中,路由守卫是用于在路由切换期间进行一些特定任务的回调函数。路由守卫可以用于许多任务,例如验证用户是否已登录、在路由切换前提供确认提示、请求数据等。Vue 3 为路由守卫提供了全面的支持,并提供了以下几种类型的路由守卫:

  1. 全局前置守卫:在路由切换前被调用,可以用于验证用户是否已登录、中断导航、请求数据等。
  2. 全局后置守卫:在路由切换之后被调用,可以用于处理数据、操作 DOM 、记录日志等。

守卫代码的位置在router.js中

//全局前置路由守卫
router.beforeEach( (to,from,next) => {
    //to 是目标地包装对象  .path属性可以获取地址
    //from 是来源地包装对象 .path属性可以获取地址
    //next是方法,不调用默认拦截! next() 放行,直接到达目标组件
    //next('/地址')可以转发到其他地址,到达目标组件前会再次经过前置路由守卫
    console.log(to.path,from.path,next)

    //需要判断,注意避免无限重定向
    if(to.path == '/index'){
        next()
    }else{
        next('/index')
    }

} )

//全局后置路由守卫
router.afterEach((to, from) => {
    console.log(`Navigate from ${from.path} to ${to.path}`);
});

Promise

回调函数

回调函数是一种基于事件的,自动调用的函数

非回调函数的代码不会等待回调函数执行完毕,而是直接执行

Promise简介

Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

  • Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
  • 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。
  • ES6规定,Promise对象是一个构造函数,用来生成Promise实例。

例:

    <script>

       /*
        1.实例化promise对象,并且执行(类似Java创建线程对象,并且start)
        参数: resolve,reject
        参数: resolve,reject分别处理成功和失败的两个函数 成功resolve(结果)  失败reject(结果)
        参数: 在function中调用这里两个方法,那么promise会处于两个不同的状态
        状态: promise有三个状态
                pending   正在运行
                resolved  内部调用了resolve方法
                rejected  内部调用了reject方法
        参数: 在第二步回调函数中就可以获取对应的结果
        */
        let promise =new Promise(function(resolve,reject){
            console.log("promise do some code ... ...")
            //resolve("promise success")
            reject("promise fail")
        })
        console.log('other code1111 invoked')
        //2.获取回调函数结果  then在这里会等待promise中的运行结果,但是不会阻塞代码继续运行
        promise.then(
						//第一个函数是要执行了resolve之后执行
            function(value){console.log(`promise中执行了resolve:${value}`)},
						//第二个函数是要执行了reject之后执行
            function(error){console.log(`promise中执行了reject:${error}`)}
        )
        // 3 其他代码执行
        console.log('other code2222 invoked')
    </script>

关于Promise catch()

Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。

<script>
    let promise =new Promise(function(resolve,reject){
        console.log("promise do some code ... ...")
        // 故意响应一个异常对象
        throw new Error("error message")
    })
    console.log('other code1111 invoked')
    /*
        then中的reject()的对应方法可以在产生异常时执行,接收到的就是异常中的提示信息
        then中可以只留一个resolve()的对应方法,reject()方法可以用后续的catch替换
        then中的reject对应的回调函数被后续的catch替换后,catch中接收的数据是一个异常对象
        */
    promise.then(
        function(resolveValue){console.log(`promise中执行了resolve:${resolveValue}`)}
        //,
        //function(rejectValue){console.log(`promise中执行了reject:${rejectValue}`)}
    ).catch(
        function(error){console.log(error)}
    )
    console.log('other code2222 invoked')
</script>

async和await

async和await是ES6中用于处理异步操作的新特性。通常,异步操作会涉及到Promise对象,而async/await则是在Promise基础上提供了更加直观和易于使用的语法。

async 用于标识函数的

  1. async标识函数后,async函数的返回值会变成一个promise对象
  2. 如果函数内部返回的数据是一个非promise对象,async函数的结果会返回一个成功状态 promise对象
  3. 如果函数内部返回的是一个promise对象,则async函数返回的状态与结果由该对象决定
  4. 如果函数内部抛出的是一个异常,则async函数返回的是一个失败的promise对象

例:

<script>

    /*
        async 用于标识函数的
            1. async标识函数后,async函数的返回值会变成一个promise对象
            2. 如果函数内部返回的数据是一个非promise对象,async函数的结果会返回一个成功状态 promise对象
            3. 如果函数内部返回的是一个promise对象,则async函数返回的状态与结果由该对象决定
            4. 如果函数内部抛出的是一个异常,则async函数返回的是一个失败的promise对象

        */
    	async function fun1(){
            //return 10
            //throw new Error("something wrong")
            let promise = Promise.reject("heihei")
            return promise
        }

        let promise =fun1()

        promise.then(
            function(value){
                console.log("success:"+value)
            }
        ).catch(
            function(value){
                console.log("fail:"+value)
            }
        )
</script>

await

  1. await右侧的表达式一般为一个promise对象,但是也可以是一个其他值
  2. 如果表达式是promise对象,await返回的是promise成功的值
  3. await会等右边的promise对象执行结束,然后再获取结果,后续代码也会等待await的执行
  4. 如果表达式是其他值,则直接返回该值
  5. await必须在async函数中,但是async函数中可以没有await
  6. 如果await右边的promise失败了,就会抛出异常,需要通过 try ... catch捕获处理

例:

<script>
    /*
            1. await右侧的表达式一般为一个promise对象,但是也可以是一个其他值
            2. 如果表达式是promise对象,await返回的是promise成功的值
            3. await会等右边的promise对象执行结束,然后再获取结果,后续代码也会等待await的执行
            4. 如果表达式是其他值,则直接返回该值
            5. await必须在async函数中,但是async函数中可以没有await
            6. 如果await右边的promise失败了,就会抛出异常,可以通过 try ... catch捕获处理
        */

		async function fun1(){
            return 10

        }

        async function fun2(){
            try{

                let res = await fun1()
                //let res = await Promise.reject("something wrong")
            }catch(e){
                console.log("catch got:"+e)
            }

            console.log("await got:"+res)
        }

        fun2()
</script>

Axios

Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。

特性:

  • 从浏览器创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防御XSRF

例:

<script setup type="module">
  import axios from 'axios'
  import { onMounted,reactive } from 'vue';

  let jsonData =reactive({code:1,content:'奥里给'})

  let getLoveMessage =()=>{
    axios({
      method:"post", // 请求方式
      url:"<https://api.uomg.com/api/rand.qinghua?format=json>",  // 请求的url
      data:{ // 当请求方式为post时,data下的数据以JSON串放入请求体,否则以key=value形式放url后
        username:"123456"
      }
    }).then( function (response){//响应成功时要执行的函数
      console.log(response)
      Object.assign(jsonData,response.data)
    }).catch(function (error){// 响应失败时要执行的函数
      console.log(error)
    })
  }

  /* 通过onMounted生命周期,自动加载一次 */
  onMounted(()=>{
    getLoveMessage()
  })
</script>

<template>
    <div>
      <h1>今日鸡汤:{{jsonData.content}}</h1>
      <button  @click="getLoveMessage">获取今日鸡汤</button>
    </div>
</template>

<style scoped>
</style>

响应的数据中包含以下信息:

{
  // `data` 由服务器提供的响应
  data: {},
  // `status` 来自服务器响应的 HTTP 状态码
  status: 200,
  // `statusText` 来自服务器响应的 HTTP 状态信息
  statusText: 'OK',
  // `headers` 是服务器响应头
  // 所有的 header 名称都是小写,而且可以使用方括号语法访问
  // 例如: `response.headers['content-type']`
  headers: {},
  // `config` 是 `axios` 请求的配置信息
  config: {},
  // `request` 是生成此响应的请求
  // 在node.js中它是最后一个ClientRequest实例 (in redirects),
  // 在浏览器中则是 XMLHttpRequest 实例
  request: {}
}

如果要对其取值使用,使用then方法:

<script setup type="module">
  import axios from 'axios'
  import { onMounted,reactive } from 'vue';

  let jsonData =reactive({code:1,content:'奥里给'})

  let getLoveWords = async ()=>{
    return await axios({
      method:"post",
      url:"<https://api.uomg.com/api/rand.qinghua?format=json>",
      data:{
        username:"123456"
      }
    })
  }

  let getLoveMessage =()=>{
   	 let {data}  = await getLoveWords()
     Object.assign(message,data)
  }

  /* 通过onMounted生命周期,自动加载一次 */
  onMounted(()=>{
    getLoveMessage()
  })
</script>

<template>
    <div>
      <h1>今日鸡汤:{{jsonData.content}}</h1>
      <button  @click="getLoveMessage">获取今日鸡汤</button>
    </div>
</template>

<style scoped>
</style>

Axios get和post方法

配置添加语法

axios.get(url[, config])

axios.get(url,{
   上面指定配置key:配置值,
   上面指定配置key:配置值
})

axios.post(url[, data[, config]])

axios.post(url,{key:value //此位置数据,没有空对象即可{}},{
   上面指定配置key:配置值,
   上面指定配置key:配置值
})

测试get参数

<script setup type="module">
  import axios from 'axios'
  import { onMounted,ref,reactive,toRaw } from 'vue';
  let jsonData =reactive({code:1,content:'奥里给'})

  let getLoveWords= async ()=>{
    try{
      return await axios.get(
        '<https://api.uomg.com/api/rand.qinghua>',
        {
          params:{// 向url后添加的键值对参数
            format:'json',
            username:'zhangsan',
            password:'123456'
          },
          headers:{// 设置请求头
            'Accept' : 'application/json, text/plain, text/html,*/*'
          }
        }
      )
    }catch (e){
      return await e
    }
  }

  let getLoveMessage =()=>{
     let {data}  = await getLoveWords()
     Object.assign(message,data)
  }
  /* 通过onMounted生命周期,自动加载一次 */
  onMounted(()=>{
    getLoveMessage()
  })
</script>

<template>
    <div>
      <h1>今日鸡汤:{{jsonData.content}}</h1>
      <button  @click="getLoveMessage">获取今日鸡汤</button>
    </div>
</template>

<style scoped>
</style>

测试post参数

<script setup type="module">
  import axios from 'axios'
  import { onMounted,ref,reactive,toRaw } from 'vue';
  let jsonData =reactive({code:1,content:'奥里给'})

  let getLoveWords= async ()=>{
    try{
      return await axios.post(
        '<https://api.uomg.com/api/rand.qinghua>',
        {//请求体中的JSON数据
            username:'zhangsan',
            password:'123456'
        },
        {// 其他参数
         	params:{// url上拼接的键值对参数
            	format:'json',
          	},
          	headers:{// 请求头
            	'Accept' : 'application/json, text/plain, text/html,*/*',
            	'X-Requested-With': 'XMLHttpRequest'
          	}
        }
      )
    }catch (e){
      return await e
    }
  }

  let getLoveMessage =()=>{
     let {data}  = await getLoveWords()
     Object.assign(message,data)
  }
  /* 通过onMounted生命周期,自动加载一次 */
  onMounted(()=>{
    getLoveMessage()
  })
</script>

<template>
    <div>
      <h1>今日鸡汤:{{jsonData.content}}</h1>
      <button  @click="getLoveMessage">获取今日鸡汤</button>
    </div>
</template>

<style scoped>
</style>

Axios 拦截器

如果想在axios发送请求之前,或者是数据响应回来在执行then方法之前做一些额外的工作,可以通过拦截器完成

// 添加请求拦截器 请求发送之前
axios.interceptors.request.use(
  function (config) {
    // 在发送请求之前做些什么
    return config;
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

// 添加响应拦截器 数据响应回来
axios.interceptors.response.use(
  function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    return response;
  },
  function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
  }
);
  • 定义src/axios.js提取拦截器和配置语法
import axios from 'axios'

//  创建instance实例
const instance = axios.create({
    baseURL:'<https://api.uomg.com>',
    timeout:10000
})

//  添加请求拦截
instance.interceptors.request.use(
    // 设置请求头配置信息
    config=>{
        //处理指定的请求头
        console.log("before request")
        config.headers.Accept = 'application/json, text/plain, text/html,*/*'
        return config
    },
    // 设置请求错误处理函数
    error=>{
        console.log("request error")
        return Promise.reject(error)
    }
)
// 添加响应拦截器
instance.interceptors.response.use(
    // 设置响应正确时的处理函数
    response=>{
        console.log("after success response")
        console.log(response)
        return response
    },
    // 设置响应异常时的处理函数
    error=>{
        console.log("after fail response")
        console.log(error)
        return Promise.reject(error)
    }
)
// 默认导出
export default instance
  • App.vue
<script setup type="module">
  // 导入我们自己定义的axios.js文件,而不是导入axios依赖
  import axios from './axios.js'
  import { onMounted,ref,reactive,toRaw } from 'vue';
  let jsonData =reactive({code:1,content:'奥里给'})

  let getLoveWords= async ()=>{
    try{
      return await axios.post(
        'api/rand.qinghua',
        {
            username:'zhangsan',
            password:'123456'
        },//请求体中的JSON数据
        {
          params:{
            format:'json',
          }
        }// 其他键值对参数
      )
    }catch (e){
      return await e
    }
  }

  let getLoveMessage =()=>{
    // 这里返回的是一个fullfilled状态的promise
    getLoveWords().then(
        (response) =>{
          console.log("after getloveWords")
          console.log(response)
          Object.assign(jsonData,response.data)
        }
    )
  }
  /* 通过onMounted生命周期,自动加载一次 */
  onMounted(()=>{
    getLoveMessage()
  })
</script>

<template>
    <div>
      <h1>今日鸡汤:{{jsonData.content}}</h1>
      <button  @click="getLoveMessage">获取今日鸡汤</button>
    </div>

</template>

<style scoped>
</style>

 

Pinia

当我们有多个组件共享一个共同的状态(数据源)时,多个视图可能都依赖于同一份状态。来自不同视图的交互也可能需要更改同一份状态,这时候要用到Pinia

npm install pinia完后,就可以开始使用Pinia。

例:

定义pinia store对象

import {defineStore } from 'pinia'

//定义数据并且对外暴露
// store就是定义共享状态的包装对象
// 内部包含四个属性: id 唯一标识 state 完整类型推理,推荐使用箭头函数 存放的数据 getters 类似属性计算,存储放对数据
// 操作的方法  actions 存储数据的复杂业务逻辑方法
// 理解: store类似Java中的实体类, id就是类名, state 就是装数据值的属性  getters就是get方法,actions就是对数据操作的其他方法
export const definedPerson = defineStore(
    {
        id: 'personPinia', //必须唯一
        state:()=>{ // state中用于定义数据
            return {
                username:'张三',
                age:0,
                hobbies:['唱歌','跳舞']
            }
        },
        getters:{// 用于定义一些通过数据计算而得到结果的一些方法 一般在此处不做对数据的修改操作
                 // getters中的方法可以当做属性值方式使用
            getHobbiesCount(){
                return this.hobbies.length
            },
            getAge(){
                return this.age
            }
        },
        actions:{ // 用于定义一些对数据修改的方法
            doubleAge(){
                this.age=this.age*2
            }
        }
    }
)

在main.js配置pinia组件到vue中

import { createApp } from 'vue'
import App from './App.vue'
import router from './routers/router.js'
// 导pinia
import { createPinia } from 'pinia'
// 创建pinia对象
let pinia= createPinia()

let app =createApp(App)
app.use(router)
// app中使用pinia功能
app.use(pinia)
app.mount('#app')

5 Operate.vue 中操作Pinia数据

<script setup type="module">
    import { ref} from 'vue';
    import { definedPerson} from '../store/store';
    // 读取存储的数据
    let person= definedPerson()

    let hobby = ref('')

</script>

<template>
    <div>
        <h1>operate视图,用户操作Pinia中的数据</h1>
        请输入姓名:<input type="text" v-model="person.username"> <br>
        请输入年龄:<input type="text" v-model="person.age"> <br>
        请增加爱好:
        <input type="checkbox" value="吃饭"  v-model="person.hobbies"> 吃饭
        <input type="checkbox" value="睡觉"  v-model="person.hobbies"> 睡觉
        <input type="checkbox" value="打豆豆"  v-model="person.hobbies"> 打豆豆 <br>

        <!-- 事件中调用person的doubleAge()方法 -->
        <button @click="person.doubleAge()">年龄加倍</button> <br>
        <!-- 事件中调用pinia提供的$reset()方法恢复数据的默认值 -->
        <button @click="person.$reset()">恢复默认值</button> <br>
        <!-- 事件中调用$patch方法一次性修改多个属性值 -->
        <button @click="person.$patch({username:'奥特曼',age:100,hobbies:['晒太阳','打怪兽']})">变身奥特曼</button> <br>
        显示pinia中的person数据:{{person}}
    </div>
</template>
<style scoped>
</style>

6 List.vue中展示Pinia数据

<script setup type="module">
    import { definedPerson} from '../store/store';
    // 读取存储的数据
    let person= definedPerson()
</script>

<template>
    <div>
        <h1>List页面,展示Pinia中的数据</h1>
        读取姓名:{{person.username}} <br>
        读取年龄:{{person.age}} <br>
        通过get年龄:{{person.getAge}} <br>
        爱好数量:{{person.getHobbiesCount}} <br>
        所有的爱好:
        <ul>
            <li v-for='(hobby,index) in person.hobbies' :key="index" v-text="hobby"></li>
        </ul>
    </div>
</template>

<style scoped>
</style>

7 定义组件路由router.js

// 导入路由创建的相关方法
import {createRouter,createWebHashHistory} from 'vue-router'

// 导入vue组件
import List  from '../components/List.vue'
import Operate  from '../components/Operate.vue'
// 创建路由对象,声明路由规则
const router = createRouter({
    history: createWebHashHistory(),
    routes:[
        {
            path:'/opearte',
            component:Operate
        },

        {
            path:'/list',
            component:List
        },
    ]

})

// 对外暴露路由对象
export default router;

8 App.vue中通过路由切换组件

<script setup type="module">

</script>

<template>
    <div>
      <hr>
      <router-link to="/opearte">显示操作页</router-link> <br>
      <router-link to="/list">显示展示页</router-link> <br>
      <hr>
      <router-view></router-view>
    </div>
</template>

<style scoped>
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/367925.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flink CEP(基本概念)

Flink CEP 在Flink的学习过程中&#xff0c;我们已经掌握了从基本原理和核心层的DataStream API到底层的处理函数&#xff0c;再到应用层的Table API和SQL的各种手段&#xff0c;可以应对实际应用开发的各种需求。然而&#xff0c;在实际应用中&#xff0c;还有一类更为复…

奇瑞瑞虎8,是真不能随便碰

文 | AUTO芯球 作者 | 李虎 我是实在看不下去了啊 这奔驰车主砸车 现在开始反转了啊 但卡住我喉咙的是定损5200的奇瑞引擎盖啊 我是真买不起&#xff0c;也不敢买啊 我怕A柱断了&#xff0c;要修20万啊 但我一算&#xff0c;这也不对啊 顶配的报价也只有16.18万啊 如果…

linux 文件查看 head 、 cat 、 less 、tail 、grep

查看文件详细信息 stat 文件 cat 》》适合显示小文件【行数比较少】&#xff0c;如果行数较多&#xff0c;屏幕显示不完整&#xff08;如果虚拟操作&#xff0c;是无法上下键的&#xff0c;或者滚动鼠标的&#xff0c;第三方 xsheel&#xff0c;crt 可以方向键查看&#xf…

Matplotlib雷达图教程:学会绘制炫酷多彩的多维数据可视化【第53篇—python:Seaborn大全】

文章目录 Matplotlib雷达图绘制指南&#xff1a;炫酷雷达图参数解析与实战1. 普通雷达图2. 堆叠雷达图3. 多个雷达图4. 矩阵雷达图5. 极坐标雷达图6. 定制化雷达图外观7. 调整雷达图坐标轴范围8. 雷达图的子图布局9. 导出雷达图总结 Matplotlib雷达图绘制指南&#xff1a;炫酷雷…

[SWPUCTF 2021 新生赛]Do_you_know_http

我们看到它让我们用WLLM浏览器登录 那我们修改User-Agent的值即可 发现有一个a.php的我们进入该目录 它提示我们不在本地服务器上 发现有一个/secretttt.php的目录 我进入即可获得flag

设计模式_策略模式_Strategy

案例引入 有各种鸭子&#xff0c;比如野鸭、北京鸭、水鸭等。 鸭子有各种行为&#xff0c;比如走路、叫、飞行等。不同鸭子的行为可能略有不同。要求显示鸭子的信息 传统方案实现 不同的鸭子继承一个父类Duck&#xff0c;如果是相同的行为就继承&#xff0c;不同行为就重写方…

【Mode Management】BswM模块和其他模块的交互

目录 1.BSWM模块和COM模块 2.BSWM模块和ComM模块 3.BSWM模块和CanSM模块 4.BSWM模块和DCM模块 4.1 DCM通过BSWM控制通信 4.2 DCM通过BSWM控制ECU复位 5.BSWM模块和自定义SWC模块 6.BSWM模块和NVM模块 6.1 BswMNvMJobModeIndication 6.2 BswMNvMRequest 6.3 小结 1.B…

C++初阶 内存管理和模板

目录 一、new 1.1什么是new&#xff1f; 1.2为什么要有new&#xff1f; 1.3使用new 1.4 new的超级好处 二、delete 2.1什么是delete&#xff1f; 2.2为什么要有delete&#xff1f; 2.3使用delete 三、 malloc / free和new / delete的共同点和区别 四、浅谈模板 4.1什…

可解释性AI(XAI):构建透明和值得信赖的决策过程

可解释性AI&#xff08;XAI&#xff09;旨在提高人工智能系统的透明度和可理解性&#xff0c;使人们更好地理解AI的决策过程和原理。随着AI技术的广泛应用&#xff0c;XAI成为了一个备受关注的重要领域。它不仅有助于建立人们对AI的信任&#xff0c;还可以帮助解决AI伦理和偏见…

系统添加多版本支持

记录一下最近做的一个需求&#xff1a; 前段时间做的【监狱点名系统】改成公司打卡考勤用的系统&#xff0c;里面的"服刑人员"、"监区"、"入监/出监"……等相关配置需要做改动&#xff0c;所以考虑加一个全局的标志&#xff0c;来区分一下版本。…

大数据本地环境搭建03-Spark搭建

需要提前部署好 Zookeeper/Hadoop/Hive 环境 1 Local模式 1.1 上传压缩包 下载链接 链接&#xff1a;https://pan.baidu.com/s/1rLq39ddxh7np7JKiuRAhDA?pwde20h 提取码&#xff1a;e20h 将spark-3.1.2-bin-hadoop3.2.tar.gz压缩包到node1下的/export/server目录 1.2 解压压…

EF Core入门例子(以SqLite为数据库)

测试环境&#xff1a; visual studio 2017 .net core 2.1 具体步骤如下&#xff1a; 1 新增名称为EFCoreDemo的.net core控制台程序&#xff0c;版本选择.net core 2.1&#xff0c;项目不能放到带中文的目录下&#xff0c;不然到后面执行Add-Migration命令时会报如下的错误…

关于ZYZ旋转和XYZ旋转

ZYZ旋转和XYZ旋转 概述1、XYZ旋转2、ZYZ旋转 概述 以下公式默认为右手坐标系&#xff1b;ZYZ通常可以避免死解情况&#xff0c;因此在六轴末端解算时常被用到&#xff1b;参考文章 1、XYZ旋转 XYZ旋转一般是绕固定轴旋转(外旋)&#xff0c;旋转矩阵的构成为&#xff1a;RzRy…

供应链系统架构的设计与实践

供应链系统是现代企业管理中不可或缺的一部分&#xff0c;它涉及到从原材料采购到产品销售的整个生产流程。一个高效的供应链系统可以帮助企业实现成本控制、库存优化和客户满意度提升等目标。在本文中&#xff0c;我们将讨论供应链系统的设计与实践。 一、供应链系统设计 1.…

kerberos+kafka(2.13)认证(单节点ubuntu)

一&#xff1a;搭建kerberos。 1. 运行安装命令 apt-get install krb5-admin-server krb5-kdc krb5-user krb5-config2. 检查服务是否启动。 systemctl status krb5-admin-server systemctl status krb5-kdcsystemctl start krb5-admin-server systemctl startkrb5-kdc3. 修…

GrayLog踩坑历险记

背景 GrayLog作为ELK的替代产品&#xff0c;是新生代的日志采集框架。在一个采集节点日志的需求中&#xff0c;因为节点很多&#xff0c;产生的日志也很多&#xff0c;因此尝试了使用GrayLog进行日志的采集。下面记录一下使用GrayLog中遇到的坑和解决方案。 一、部署与启动 …

【开源】WordPress一键崩溃宕机插件(整活娱乐)

插件介绍 可一键实现Wordpress崩溃宕机的整活向插件&#xff08;请勿用于非法途径&#xff0c;仅供整活娱乐&#xff09;。鼓励关注网站性能的提升&#xff0c;以提供更好的用户体验&#xff0c;提倡为用户提供良好体验和高效速度的原则。 介绍 长期以来&#xff0c;人们都在…

iOS图像处理----OpenGL ES之大长腿特效

目录 一、代码部分概括 二、实现流程概括 1、第一次加载图片 ①、GLKView初始化数据 这部分内容主要是初始化顶点数组、上下文以及顶点数组缓存区&#xff0c;需要在加载图片之前做好准备​编辑 ②、加载图片 ③、绘制 2、拉伸图片 ①、滑块调整 ②、图片拉伸过程 3、…

【React】react组件传参

【React】react组件传参 一、props&#xff1a;父组件向子组件传参1、将普通的参数作为props传递2、将jsx作为props传递&#xff08;组件插槽&#xff09; 二、自定义事件&#xff1a;子父组件向父组件传参三、context进行多级组件传参四、redux全局状态管理 一、props&#xf…

Redis客户端有哪些:你了解吗?

一、分类 Redis客户端工具是用来连接和管理redis服务器的软件&#xff0c;它们可以有不同的类型&#xff0c;如桌面客户端、web客户端和IDE插件。不同的客户端工具有各自的优缺点和特色&#xff0c;你可以根据你的需求和喜好选择合适的工具。 1、Redis 命令行工具 redis-cli官…