Vue初识系列【2】内容升级版

news2024/12/22 17:54:22

文章目录

  • 一 模板语法
    • 1.1 文本
    • 1.2 原始THTML
    • 1.3 属性Attribute
    • 1.4 JavaScript表达式的使用
  • 二 条件渲染
  • 三 列表渲染
  • 四 事件处理
    • 4.1 监听事件
    • 4.2 事件处理方法
    • 4.3 内联处理器中的方法(事件传递参数)
    • 4.4 完整代码和效果展示
  • 五 表单输入绑定
  • 六 组件基础
    • 6.1 单文本组件
    • 6.2 加载组件
    • 6.3 组件的组织
  • P r o p s Props Props组件交互
    • 7.1 Props简介
    • 7.2 演示
      • 7.2.1 App.vue
    • 7.2.2 MyCompent.vue
  • 八 自定义事件组件交互
    • 8.1 简介
    • 8.2 演示
      • 8.2.1 MyCompent.vue
      • 8.2.2 App.vue
  • 九 组件生命周期
    • 9.1 生命周期钩子函数
    • 9.2 钩子函数分类
    • 9.3 演示
  • 十 Vue引入第三方Swiper
    • 10.1 Swiper简介
    • 10.2 演示
      • 10.2.1 安装Swiper
      • 10.2.2 引入&使用
  • 十一 Axios网络请求
    • 11.1 安装
    • 11.2 引入
    • 11.3 网络请求演示get&post
    • 11.4 网络请求封装
    • 11.5 演示
      • 11.5.1 request.js
      • 11.5.2 index.js
      • 11.5.3 path.js
    • 11.6 网络请求跨域解决方案
  • 十二 Vue引入路由配置
    • 12.1 手动引入步骤
    • 12.2 创建项目时引入路由
    • 12.3 完整代码
      • 12.3.1 index.js
      • 12.3.2 HomeView.vue
      • 12.3.3 AboutView.vue
      • 12.3.4 main.js
    • 12.4 路由传递参数
    • 12.5 完整代码
      • 12.5.1 index.js
      • 12.5.2 App.vue
      • 12.5.3 NewsView.vue
      • 12.5.4 NewsDetails.vue
    • 12.6 嵌套路由
    • 12.7 完整代码
      • 12.7.1 index.js
      • 12.7.2 AboutView.vue
      • 12.7.3 AboutUs.vue
      • 12.7.4 AboutInfo.vue
  • 十三 Vue状态管理(Vuex)
    • 13.1 Vuex简介
    • 13.2 手动引入步骤
    • 13.3 创建项目时引入
    • 13.4 完整代码
      • 13.4.1 HelloWorld.vue
      • 13.4.2 index.js
      • 13.4.3 App.vue
      • 13.4.4 main.js
    • 13.5 Vue状态管理核心(Vuex)
      • 13.5.1 核心概念简介
      • 13.5.2 完整代码演示

一 模板语法

1.1 文本

- 数据绑定最常见的形式是${{}}$双括号语法的文本插值。
- 一般配合`JS data()`使用
<span>{{msg}}</span>
<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      msg: "消息"
    }
  }
}
</script>

在这里插入图片描述

1.2 原始THTML

  • 双大括号会将数据解释为普通文本
  • 使用 − h t m l -html html会将文本输出为HTML代码解析后的结果
<h1>{{ rawHtml }}</h1>
<h1 v-html="rawHtml"></h1>
<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      rawHtml: '<a herf="htttp://www.baidu.com">百度</a>'
    }
  }
}
</script>

在这里插入图片描述

1.3 属性Attribute

  • 使用 v − b i n d v-bind vbind指令(使用效果同双到括号)
<h1 v-bind:id="dynamicId">{{dynamicId }}</h1>
<!--简写:<h1 :id="dynamicId">{{dynamicId }}</h1>-->
<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      dynamicId: 1001
    }
  }
}
</script>

在这里插入图片描述

1.4 JavaScript表达式的使用

  • Vue.js提供了完整的JavaScipt表达式支持
  • 限制:每个绑定都只能包含单个表达式
{{num+1}}
{{flag ? 'true':'false'}}
{{message.split('').reverse().join('')}}

二 条件渲染

2.1 v − i f & v − e l s e v-if\&v-else vif&velse

  • v − i f v-if vif指令用于条件渲染一块内容。
  • 渲染条件:当该块内容的指令的表达式的返回值为 t r u e true true
  • v − e l s e v-else velse v − i f v-if vif搭配使用
<template>
  <div class="hello">
    <h1 v-if="flag">{{ flag }}</h1>
    <h1 v-else>{{ flag }}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      flag: true
    }
  }
}
</script>

在这里插入图片描述

2.2 v − s h o w v-show vshow

  • 用于条件性展示的选项指令
  • 效果同 v − i f v-if vif
<template>
  <div class="hello">
    <h1 v-show="flag">{{ flag }}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  data() {
    return {
      flag: true
    }
  }
}
</script>

在这里插入图片描述

2.3 v − i f v-if vif v − s h o w v-show vshow的区别

  • v − i f v-if vif是真正的条件渲染,因为它会确保在切换过程中,条件块内的事件监听器和子组件适当地被销毁和重建。 v − i f v-if vif同时也是情性的:如果在初始漳染时条件为假,则什么也不做,一直到条件第一次变为真时,才会开始滑染条件块。
  • v − s h o w v-show vshow元素总是会被染并目只是简单地基于CSS进行切换
  • 总结
    • v − i f v-if vif有更高的切换开销
    • v − s h o w v-show vshow有更高的初识渲染开销。
    • 如果需要非常频繁地切换,则使用 v − s h o w v-show vshow较好
    • 如果运行时条件很少改变,则使用 v − i f v-if vif合适

三 列表渲染

3.1 v − f o r v-for vfor列表渲染

  • v − f o r v-for vfor将一个数组映射为一组元素
    • v − f o r v-for vfor指令基于一个数组来渲染一个列表
    • v − f o r v-for vfor需要使用 i t e m i n i t e m s item in items iteminitems形式的特殊语法, i t e m s items items是源数据数组, i t e m item item是被迭代的数组元素的别名。
<template>
  <h1>列表渲染</h1>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <hr/>
    <ul>
      <!--  :key="item.id"  就地原则  -->
      <li v-for="item in items" :key="item.id"><hr/>{{item.message}}<hr/></li><hr/>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items:[
          {
            id: 1001,
            message: 'A'
          },
          {
            id: 1002,
            message: 'B'
          },
          {
            id: 1003,
            message: 'C'
          }
      ]
    }
  }
}
</script>

在这里插入图片描述

3.2 v − f o r v-for vfor维护状态

  • 当vue正在更新使用V-for渲染的元素列表时,默认使用“就地更新”的策略。
  • 如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确演染。
  • 为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一的key属性。
<!--  :key="item.id"  就地原则  -->
<li v-for="item in items" :key="item.id">{{item.message}}</li>
  • 一般开发中,对象的属性中一般存在唯一标识字段,也可以使用下标作为唯一key属性字段
<li v-for="(item,index) in items" :key="index">{{item.message}}</li>

四 事件处理

4.1 监听事件

  • v − o n v-on von指令用来监听DOM事件,并在触发事件时执行一些JavaScript。
<button v-on:click="num++">数字+1</button>
<button @click="display">简写形式@click</button>
data() {
   return {
     num: 1
   }
 }

4.2 事件处理方法

  • v − o n v-on von还可以接收一个需要调用的方法名称。
<button @click="change">改变文本内容</button>
methods: {
    change(event) {
        this.message='hello Vue';
    }
  }

4.3 内联处理器中的方法(事件传递参数)

<button @click="say('AAA')">AAA</button>
methods: {
    say(message) {
      alert(message);
    }
  }

4.4 完整代码和效果展示

<template>
  <h1>事件处理</h1>
  <div class="hello">
    <button v-on:click="num++">数字+1</button>
    &nbsp;
    <button v-on:click="num--">数字-1</button>
    &nbsp;
    <button @click="display">简写形式@click</button>
    <h1>{{ num }}</h1>
    <hr/>
    <button @click="change">改变文本内容</button>
    <h1 >{{message}}</h1>
    <hr/>
    <button @click="say('AAA')">AAA</button>
    &nbsp;
    <button @click="say('BBB')">BBB</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      num: 1,
      message: 'Hello World',
    }
  },
  methods: {
    display(event){
      alert("@click=\"xxx\"");
    },
    change(event) {
        this.message='hello Vue';
    },
    say(message) {
      alert(message);
    }
  }
}
</script>

在这里插入图片描述

五 表单输入绑定

5.1 v − m o d e l v-model vmodel简介

  • v − m o d e k l v-modekl vmodekl指令在表单<input> <textarea> <select>元素上创建双向数据绑定。
  • 它会根据控件类型自动选取正确的方法来更新元素。
  • 它负责监听用户的输入事件来更新数据,并在某种极端场景下进行一些特殊处理。

5.2 修饰符

  • 默认情况下, v − m o d e l v-model vmodel在每次 i n p u t input input事件触发后将输入框的值与数据同步
  • . l a z y .lazy .lazy:事件在输入值后同步
  • . t r i m .trim .trim:自动过滤用户输入的首尾空白字符
<template>
  <h1>表单输入绑定</h1>
  <div class="hello">
    <hr/>
    <input v-model="message1" placeholder="请输入"/>
    <h1>输入的内容为:{{message1}}</h1>
    <hr/>
    <input v-model.lazy="message2" placeholder="请输入"/>
    <h1>输入的内容为:{{message2}}</h1>
    <hr/>
    <input v-model.trim="message3" placeholder="请输入"/>
    <h1>输入的内容为:{{message3}}</h1>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
    return {
      message1: "",
      message2: "",
      message3: ""
    }
  }
}
</script>

在这里插入图片描述

六 组件基础

6.1 单文本组件

  • Vue单文本组件( . v u e .vue .vue文件)是一种特殊的文本格式。它允许将Vue组件的模板、逻辑与样式封装在单个文件中。
<template>
  <h1>组件基础</h1>
  <h1>{{msg}}</h1>
</template>

<script>
export default {
  /*导出的名称*/
  name: "MyCompent",
  data() {
    return {
      msg: "单文件组件"
    }
  }
}
</script>
<!--样式只在当前组建中生效  -->
<style scoped>
h3{
  color: chartreuse;
}
</style>

6.2 加载组件

  1. 引入组件
/*第一步:导入组件*/
import MyCompent from "@/components/MyCompent";
  1. 挂载组件
export default {
  name: 'App',
  /*第二步:挂载组件*/
  components: {
    MyCompent
  }
}
  1. 显示组件
<template>
  <!-- 第三步:显示组件 -->
  <MyCompent />
</template>

6.3 组件的组织

  • 一个应用会以一个嵌套的组件树的形式来组织
    在这里插入图片描述

P r o p s Props Props组件交互

7.1 Props简介

  • 组建与组建之间存在来交互
  • P r o p s Props Props可以在组件上注册一些自定义属性
  • Peops传递参数是没有类型限制的
  • 数据类型为数组或者对象的时候,默认值是需要返回工厂模式

7.2 演示

7.2.1 App.vue

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <MyCompent :title="title" :num="nums" :names="names"/>
</template>

<script>
import MyCompent from "@/components/MyCompent";
export default {
  name: 'App',
  data() {
    return {
      title: "武林大会",
      nums: "20",
      names: ["A","B","C"]
    }
  },
  components: {
    MyCompent
  }
}
</script>

7.2.2 MyCompent.vue

<template>
  <h1>props组件交互</h1>
  <h1>{{num}}{{title}}</h1>
  <ul>
    <li v-for="(item,index) in names" :key="index" v-html="item"></li>
  </ul>
</template>

<script>
export default {
  name: "MyCompent",
  props:{
    title: {
      type:String,
      default:""
    },
    num: {
      type: Number,
      default: 1
    },
    /*数组和对象必须使用函数返回 */
    names: {
      type: Array,
      default:function () {
        return []
      }
    }
  }

}
</script>

<style scoped>

</style>

在这里插入图片描述

八 自定义事件组件交互

8.1 简介

  • 自定义事件可以在组件中反向传递数据,可以将数据从父组件传递到子组件
  • 如果需要将数据从子组件传递到负组件,那么就可以利用自定义事件实现$emit
  • vm.$emit( event, arg ) 触发当前实例上的事件

8.2 演示

8.2.1 MyCompent.vue

<template>
  <h1>自定义事件组件交互</h1>
  <hr/>
  <button @click="send">发送数据</button>
</template>
<script>
export default {
  name: "MyCompent",
  data() {
    return {
      message: "我是来自子组件的数据"
    }
  },
  methods: {
    send() {
      //参数1:字符串:理论上是随便的,但是需要具有意义
      //参数2:传递的数据
      this.$emit("onEvent",this.message)
    }
  }
}
</script>
<style scoped>
</style>

8.2.2 App.vue

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <MyCompent @onEvent="getData"/>
</template>

<script>

import MyCompent from "./components/MyCompent";

export default {
  name: 'App',
  components: {
    MyCompent
  },
  methods: {
    getData(data) {
      alert(data);
    }
  }
}
</script>

在这里插入图片描述

九 组件生命周期

9.1 生命周期钩子函数

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

9.2 钩子函数分类

函数存作用时期函数名称
创建时beforeCreate、created
渲染时beforeMount、mounted
更新时beforeUpdate、Updated
卸载时beforeUnmount、unmounted

9.3 演示

<template>
  <h1>生命周期函数</h1>
  <hr/>
  <button @click="addFunction()">点击</button>
  <hr/>
  <h1>{{msg}}</h1>
</template>

<script>
export default {
  name: "MyCompent",
  data() {
    return {
      msg: 1
    }
  },
  methods: {
    addFunction(event) {
      this.msg++;
    }
  },
  created() {
    console.log("create--组件创建完成")
  },
  beforeCreate() {
    console.log("beforeCreate--组件创建完成之前")
  },
  beforeMount() {
    console.log("beforeMount--组件渲染完成之前")
  },
  mounted() {
    console.log("beforeMount--渲染完成")
    //网络请求放到这里
  },
  beforeUpdate() {
    console.log("beforeUpdate--更新组件之前")
  },
  unmounted() {
    console.log("Update--组件卸载完成")
  },
  beforeUnmount() {
    console.log("beforeDestroy--组件下载完成之前")
    //卸载之前,把消耗性能的处理都干掉
    //定时器
  },
  destroyed() {
    console.log("destroy--销毁完成")
  }
}
</script>

<style scoped>

</style>

在这里插入图片描述

十 Vue引入第三方Swiper

10.1 Swiper简介

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

10.2 演示

10.2.1 安装Swiper

cnpm install --save swiper

10.2.2 引入&使用

<template>
  <h1>Vue引入第三方</h1>
  <!--第三步:使用-->
  <div class="hello">
    <Swiper :modules="modules" :pagination="{clickable:true}">
      <SwiperSlide>
        <img src="../assets/logo.png"/>
      </SwiperSlide>
      <SwiperSlide>
        <img src="../assets/logo.png"/>
      </SwiperSlide>
      <SwiperSlide>
        <img src="../assets/logo.png"/>
      </SwiperSlide>
    </Swiper>
  </div>
</template>

<script>
//第二步:引入
import {Swiper,SwiperSlide} from 'swiper/vue';
/*引入过滤器*/
import {Pagination} from 'swiper';
import 'swiper/css';
import 'swiper/css/pagination';
export default {
  name: 'HelloWorld',
  data() {
    return {
      modules: [Pagination]
    }
  },
  components: {
    Swiper,
    SwiperSlide,
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
img {
  width: 100%;
}
</style>

在这里插入图片描述

十一 Axios网络请求

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

11.1 安装

  • 在终端进入该项目根目录下,输入已下命令:
cnpm install --save axios

在这里插入图片描述

11.2 引入

  • 组件中引入import axios from "axios"
  • 全局引入
import { createApp } from 'vue'
import App from './App.vue'
import './registerServiceWorker'

//将Axios挂载到全局
import axios from "axios"
const app=createApp(App);
app.config.globalProperties.$axios=axios
app.mount('#app')

11.3 网络请求演示get&post

  • post请求参数需要额外处理
    1. 安装依赖(同样是在该项目的根目录下输入)
    cnpm install --save querystring
    
    1. 转化参数格式
    import queryString from "querystring";
    queryString.stringify()
    
<template>
  <div class="hello">
    <h1>Axios网络请求</h1>
    <p>{{chengpin.title}}</p>
  </div>
</template>

<script>
import queryString from "querystring";
export default {
  name: 'HelloWorld',
  data() {
      return {
        chengpin: {}
    }
  },
  mounted() {
    this.$axios.get("http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php").then(
        res=>{
          console.log(res.data);
        }
    ),
    this.$axios.post("http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php",queryString.stringify({
          user_id: "iwen@qq.com",
          password: "iwen123",
      verification_code:"crfvm"
    })).then(
        res=>{
          console.log(res.data);
        })
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

在这里插入图片描述

11.4 网络请求封装

  • 一个项目中的网络请求会很多,此时就会出现难以管理的问题。
  • 解决方案:一般采用的方案就是将网络请求封装起来。

11.5 演示

11.5.1 request.js

  • 在src目录下创建文件夹utils,并创建文件request.js,用来存储网络请求对象axios
cnpm install --save axios
cnpm install --save querystring
import axios from "axios"
import queryString from "querystring"

const instance=axios.create({
    //网络请求的公共配置
    timeout:5000
})

const errorHandle=(status,info)=> {
    switch (status){
        case 400:
            console.log("语义有误");
            break;
        case 401:
            console.log("服务器认证失败");
            break;
        case 403:
            console.log("服务器拒绝访问");
            break;
        case 404:
            console.log("地址错误");
            break;
        case 500:
            console.log("服务器遇到意外");
            break;
        case 502:
            console.log("服务器无响应");
            break;
        default:
            console.log(info);
            break;
    }
}

//拦截器
//发送数据之前
instance.interceptors.request.use(
    config=>{
        if(config.method==="post"){
            config.data=queryString.stringify(config.data)
        }
        //config:包含着网络请求的所有信息
        return config;
    },
    error=> {
        return Promise.reject(error);
    }
)
//响应拦截
instance.interceptors.response.use(
    response=>{
        return response.status===200 ? Promise.resolve(response): Promise.reject(response)
    },
    error=> {
        const {response}=error;
        //错误的处理
        errorHandle(response.status,response.info)
    }
)
export default instance;

11.5.2 index.js

  • 在src目录下创建文件夹 api,并创建文件 index和 path分别来存放网络请求方法和请求路径。
import axios from '../utils/request'
import path from "./path"
const api={
    //成品详细地址
    getChengPin() {
        return axios.get(path.baseUrl+path.chengpin)
    }
}
export default api;

11.5.3 path.js

const base={
    baseUrl: "http://iwenwiki.com",
    chengpin: "/api/blueberrypai/getChengpinDetails.php"
}
export default base;

在这里插入图片描述

11.6 网络请求跨域解决方案

  • js采用的是同源策略(浏览器的一项安全策略)
  • 同源策略浏览器只允许JS码请求和当前所在服务器域名,端口,协议相同的数据接口上的数据。
  • 当协议域名端口任意一个不相同时,就会产生跨域问题
  • 跨域错误提示信息
    在这里插入图片描述
  • 主流的跨域解决方案有两种
    • 后台解决:cors
    • 前台解决:proxy
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  //添加下列代码
  devServer: {
    proxy: {
      '/api': {
      	//协议和服务器域名
        target: 'http://iwenwiki.com',
        changeOrigin: true
      }
    }
  }
  
})
<script>
import axios from "axios"
export default {
  name: 'HelloWorld',
  mounted() {
  //写入剩下的路径
    axios.get("/api/FingerUnion/list.php")
        .then(res=> {
          console.log(res.data);
        })
  }
}
</script>
  • 记得需要重启服务器
    在这里插入图片描述

十二 Vue引入路由配置

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

12.1 手动引入步骤

  • 第一步:安装路由npm install --save vue-router
  • 第二步:配置独立的路由文件index.js
    在这里插入图片描述
//index.js
import {createRouter,createWebHashHistory} from "vue-router"
import HomeView from "../views/HomeView";
import AboutView from "../views/AboutView";
//配置信息中需要页面的相关配置 数组类型
const routes=[
    {
        path: "/",
        component: HomeView
    },
    {
        path: "/about",
        component: AboutView
    }
]
/**
 * createWebHashHistory
 *  home:http://localhost:8080/#/
 *  about:http://localhost:8080/#/about
 *原理:a标签的锚点连接
 * createWebHistory
 *  home:http://localhost:8080/
 *  about:http://localhost:8080/about
 *原理:H5 pushState() 需要后台配合做重定向,否则出现404问题
 * @type {Router}
 */
const router=createRouter({
    history:createWebHashHistory(),
    routes
})
export default router;
  • 第三步:引入路由到项目
    在这里插入图片描述
//main.js
import { createApp } from 'vue'
import App from './App.vue'
import './registerServiceWorker'
//手动导入和添加
import router from "./router";
//安装路由功能
createApp(App).use(router).mount('#app')
  • 第四步:指定路由显示入口<router-view/>
    在这里插入图片描述
//App.vue
<template>
  <!-- 路由显示入口 -->
  <router-view></router-view>
</template>
  • 第五步:指定路由跳转
    在这里插入图片描述
//App.vue
<template>
  <span><router-link to="/">首页</router-link></span>|
  <span><router-link to="/about">关于</router-link></span>
</template>

12.2 创建项目时引入路由

在这里插入图片描述

12.3 完整代码

12.3.1 index.js

import {createRouter,createWebHashHistory} from "vue-router"
import HomeView from "../views/HomeView";
import AboutView from "../views/AboutView";
//配置信息中需要页面的相关配置 数组类型
const routes=[
    {
        path: "/",
        component: HomeView
    },
    {
        path: "/about",
        component: AboutView
    }
]
/**
 * createWebHashHistory
 *  home:http://localhost:8080/#/
 *  about:http://localhost:8080/#/about
 *原理:a标签的锚点连接
 * createWebHistory
 *  home:http://localhost:8080/
 *  about:http://localhost:8080/about
 *原理:H5 pushState() 需要后台配合做重定向,否则出现404问题
 * @type {Router}
 */
const router=createRouter({
    history:createWebHashHistory(),
    routes
})
export default router;

12.3.2 HomeView.vue

<template>
  <h1>首页</h1>
  <img src="../assets/girl01.jpg">
</template>

<script>
export default {
  name: "HomeView"
}
</script>

<style scoped>
img {
  width: 800px;
}
</style>

12.3.3 AboutView.vue

<template>
  <h1>分页面</h1>
  <img src="../assets/girl02.jpg">
</template>

<script>
export default {
  name: "AboutView"
}
</script>

<style scoped>
img {
  width: 800px;
}
</style>

12.3.4 main.js

import { createApp } from 'vue'
import App from './App.vue'
import './registerServiceWorker'
//手动导入和添加
import router from "./router";
//安装路由功能
createApp(App).use(router).mount('#app')

在这里插入图片描述

12.4 路由传递参数

  • 第一步:在路由配置中指定参数的key
{
  path: "/newsDetails/:area",
  name: "newsDetails",
  component: ()=>import('../views/NewsDetails')
}
  • 第二步:在跳转过程中携带参数
<ul>
  <li><router-link to="/newsDetails/global">global news</router-link></li>
  <li><router-link to="/newsDetails/local">local news</router-link></li>
</ul>
  • 第三步:在详情页面读取路由参数携带的参数
<div class="home">
  <img alt="Vue logo" src="../assets/logo.png">
</div>

12.5 完整代码

12.5.1 index.js

import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  },
  {
    path: "/news",
    name: "news",
    /*异步加载,有主语提升主页的加载速度*/
    component: () => import('../views/NewsView')
  },
  {
    path: "/newsDetails/:area",
    name: "newsDetails",
    component: ()=>import('../views/NewsDetails')
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

12.5.2 App.vue

<template>
  <h1>路由传递参数</h1>
  <nav>
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>|
    <router-link to="/news">News</router-link>
  </nav>
  <router-view/>
</template>

12.5.3 NewsView.vue

<template>
  <ul>
    <li><router-link to="/newsDetails/global">global news</router-link></li>
    <li><router-link to="/newsDetails/local">local news</router-link></li>
  </ul>
</template>

<script>
export default {
  name: "NewsView"
}
</script>

<style scoped>
a {
  text-decoration-line: none;
}
</style>

12.5.4 NewsDetails.vue

<template>
  <h1>{{$route.params.area}} news content</h1>
</template>

<script>
export default {
  name: "NewsDetails"
}
</script>
<style scoped>
</style>

在这里插入图片描述

12.6 嵌套路由

  • 第一步:创建子路由要加载显示的页面
<template>
  <h1>关于{{$route.params.info}}</h1>
</template>

<script>
export default {
  name: "AboutUs"
}
</script>

<style scoped>

</style>
<template>
  <h1>关于{{$route.params.info}}</h1>
</template>

<script>
export default {
  name: "AboutInfo"
}
</script>

<style scoped>

</style>
  • 第二步:在路由配置文件中添加子路由配置
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    /*重定向*/
    redirect: '/about/us/了解信息',
    component: () => import( '../views/AboutView.vue'),
    children:[
      {
        /*没有/*/
        path: 'us/:info',
        name: 'us/:info',
        component:()=>import('../views/AboutUs.vue')
      },
      {
        /*没有/*/
        path: 'info/:info',
        name: 'info/:info',
        component:()=>import('../views/AboutInfo.vue')
      }
    ]
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

  • 第三步:指定子路由显示位置
<router-view></router-view>
  • 第四步:添加子路由跳转连接
<router-link to="/about/us/公司">公司简介</router-link>|
    <router-link to="/about/us/成员">成员简介</router-link>|
    <router-link to="/about/info/材料">材料信息简介</router-link>|
    <router-link to="/about/info/产品">产品信息简介</router-link>
  • 第五步:重定向配置
/*重定向*/
redirect: '/about/us/了解信息',

12.7 完整代码

12.7.1 index.js

import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/about',
    name: 'about',
    /*重定向*/
    redirect: '/about/us/了解信息',
    component: () => import( '../views/AboutView.vue'),
    children:[
      {
        /*没有/*/
        path: 'us/:info',
        name: 'us/:info',
        component:()=>import('../views/AboutUs.vue')
      },
      {
        /*没有/*/
        path: 'info/:info',
        name: 'info/:info',
        component:()=>import('../views/AboutInfo.vue')
      }
    ]
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

12.7.2 AboutView.vue

<template>
  <div class="about">
    <router-link to="/about/us/公司">公司简介</router-link>|
    <router-link to="/about/us/成员">成员简介</router-link>|
    <router-link to="/about/info/材料">材料信息简介</router-link>|
    <router-link to="/about/info/产品">产品信息简介</router-link>
    <router-view></router-view>
  </div>
</template>

12.7.3 AboutUs.vue

<template>
  <h1>关于{{$route.params.info}}</h1>
</template>

<script>
export default {
  name: "AboutUs"
}
</script>

<style scoped>

</style>

12.7.4 AboutInfo.vue

<template>
  <h1>关于{{$route.params.info}}</h1>
</template>

<script>
export default {
  name: "AboutInfo"
}
</script>

<style scoped>

</style>

在这里插入图片描述

十三 Vue状态管理(Vuex)

13.1 Vuex简介

  • Vuex是一个专为Vue.js应用程序开发的状态管理模式+库
  • 它采用集中式存储管储管理应用的所有组件的状态,并以相应的规则保证状态。以一种可预测的方式发生改变。
  • 简单理解:状态管理可以理解成为了更方便地管理组件之间的数据交互提供了一个集中式的管理方案,任何组件都可以按照指定的方式进行读取和改变数据。
    在这里插入图片描述

13.2 手动引入步骤

  • 第一步:安装Vues
npm install --save vuex
//或者
cnpm install --save vuex
  • 第二步:配置Vuex文件
    在这里插入图片描述
//index.js
import {createStore} from "vuex"
//Vuex的核心作用就是帮我们管理组件之间的状态
export default createStore({
    //所有的数据状态都存放在这里
    state: {
        counter: 0
    }
})
  • 第三步:在主文件中引入Vuex
    在这里插入图片描述
import { createApp } from 'vue'
import App from './App.vue'
import './registerServiceWorker'
import store from './storve'
createApp(App).use(store).mount('#app')
  • 第四步:在组件中读取状态【两种】
    • 第一种:普通读取
    <h1>App.Vue中引入counter:{{ $store.state.counter}}</h1>
    
    • 第二种:快捷读取
    <template>
      <div class="hello">
        <h1>HelloWorld中引入counter:{{ $store.state.counter}}</h1>
        <h1>利用计算属性快捷读取counter:{{ $store.state.counter}}</h1>
      </div>
    </template>
    
    <script>
    //第二种方式:快捷读取 利用计算属性的方式
    import {mapState} from "vuex"
    
    export default {
      name: 'HelloWorld',
      props: {
        msg: String
      },
      computed: {
        ...mapState(["counter"])
      }
    }
    </script>
    

13.3 创建项目时引入

在这里插入图片描述

13.4 完整代码

在这里插入图片描述

13.4.1 HelloWorld.vue

<template>
  <div class="hello">
    <h1>HelloWorld中引入counter:{{ $store.state.counter}}</h1>
    <h1>利用计算属性快捷读取counter:{{ $store.state.counter}}</h1>
  </div>
</template>

<script>
//第二种方式:快捷读取 利用计算属性的方式
import {mapState} from "vuex"

export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  computed: {
    ...mapState(["counter"])
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

13.4.2 index.js

import {createStore} from "vuex"
//Vuex的核心作用就是帮我们管理组件之间的状态
export default createStore({
    //所有的数据状态都存放在这里
    state: {
        counter: 0
    }
})

13.4.3 App.vue

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Vue状态管理(Vuex)"/>
  <h1>App.Vue中引入counter:{{ $store.state.counter}}</h1>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

13.4.4 main.js

import { createApp } from 'vue'
import App from './App.vue'
import './registerServiceWorker'
import store from './storve'
createApp(App).use(store).mount('#app')

在这里插入图片描述

13.5 Vue状态管理核心(Vuex)

13.5.1 核心概念简介

  • 最常用的核心概念包括:
  • State:组件状态
import { createStore } from 'vuex'
import axios from 'axios'
export default createStore({
  state: {
    counter: -1
  }
})

  • Getter:对Vuex中的数据进行过滤
import { createStore } from 'vuex'
import axios from 'axios'
export default createStore({
  state: {
    counter: -1
  },
  getters: {
    getCounter(state) {
      return state.counter>0 ? state.counter : "counter数据异常"
    }
  }
})

  • Mutation:更改store中的状态的方法。
    • Vuex中mutation非常类似事件:每个mutation都有一个字符串的是件类型和一个回调函数这个回调函数就是实际进行状态更改的地方,并且它会接受state作为第一个参数
import { createStore } from 'vuex'
import axios from 'axios'
export default createStore({
  state: {
    counter: -1
  },
  getters: {
    getCounter(state) {
      return state.counter>0 ? state.counter : "counter数据异常"
    }
  },
  mutations: {
    addCounter(state,num) {
      state.counter+=num
    }
  }
})

  • Action:本质是mutation
    • Action提交的是mutation,而不是直接改变状态
    • Action可以包含任意异步操作
import { createStore } from 'vuex'
import axios from 'axios'
export default createStore({
  state: {
    counter: -1
  },
  getters: {
    getCounter(state) {
      return state.counter>0 ? state.counter : "counter数据异常"
    }
  },
  mutations: {
    addCounter(state,num) {
      state.counter+=num
    }
  },
  actions: {
    //异步操作
    asycAddCounter({commit}) {
      axios.get("http://iwenwiki.com/api/generator/list.php")
          .then(res=>{
            commit("addCounter",res.data[0])
          })
    }
  }
})

13.5.2 完整代码演示

  • index.js
import { createStore } from 'vuex'
import axios from 'axios'
export default createStore({
  state: {
    counter: -1
  },
  getters: {
    getCounter(state) {
      return state.counter>0 ? state.counter : "counter数据异常"
    }
  },
  mutations: {
    addCounter(state,num) {
      state.counter+=num
    }
  },
  actions: {
    //异步操作
    asycAddCounter({commit}) {
      axios.get("http://iwenwiki.com/api/generator/list.php")
          .then(res=>{
            commit("addCounter",res.data[0])
          })
    }
  },
  modules: {
  }
})
  • HelloWorld.vue
<template>
  <div class="hello">
    <h1>{{$store.getters.getCounter}}</h1>
    <h1>{{getCounter}}</h1>
    <button @click="addHander">同步增加</button>&nbsp;
    <button @click="addAsyncHander">异步增加</button>
  </div>
</template>

<script>
import {mapGetters,mapMutations,mapActions} from 'vuex'
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  computed: {
    ...mapGetters(["getCounter"])
  },
  methods: {
    ...mapMutations(["addCounter"]),
    ...mapActions(["asycAddCounter"]),
    addHander() {
      /*固定调用方式*/
      //this.$store.commit("addCounter",3)
      this.addCounter(3)
    },
    addAsyncHander() {
      //this.$store.dispatch("asycAddCounter")
      this.asycAddCounter()
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenSceneGraph几何基础教程【OSG】

默认情况下&#xff0c;OSG 使用顶点数组法和显示列表法来渲染几何体。 但是&#xff0c;渲染策略可能会发生变化&#xff0c;具体取决于几何数据的呈现方式。 在本文中&#xff0c;我们将了解在 OSG 中处理几何体的基本技术。 OpenSceneGraph 后端的 OpenGL 使用几何图元&…

Typora 图床教程(阿里云版)

由于码云现在需要登录才能看到相关图片文件后&#xff0c;导致我们已经不能愉快的使用它作为图床了&#xff0c;所以我们需要使用其他工具来作为图床使用了&#xff0c;本文使用阿里云OSS作为Typora的图床。 阿里云OSS相较于其他几个方法来说最大的优点就是稳定了&#xff0c;…

《图机器学习》-Machine Learning for Graphs

Machine Learning for Graphs一、Application of Graph ML一、Application of Graph ML 图机器学习的任务可以分为四个类型&#xff1a; NodelevelNode\ levelNode level(结点级别)EdgelevelEdge\ levelEdge level(边级别)Community(subgraph)levelCommunity(subgraph)\ level…

【rpm】源码包制作rpm包|修改rpm、重新制作rpm包

目录 前言 安装rpmbuild rpmbuild制作rpm 包 同时生成devel包 修改rpm、重新制作rpm包 RPM 打包 工具 SPEC文件 rpmbuild的目录和Spec宏变量和参数说明 preamble部分 Body 部分 标题宏变量/工作目录 spec文件信息 符号说明 CMake制作rpm包 HelloWorld 更多SPEC…

微信小程序开发——小程序的宿主环境—组件

一.小程序的宿主环境—组件1.小程序中组件的分类小程序中的组件也是由宿主环境提供的&#xff0c;开发者可以基于组件快速搭建出漂亮的页面结构。官方把小程序的组件分为了9大类&#xff0c;分别是&#xff1a;1.视图容器 2.基础内容 3.表单组件 4.导航组件5.媒体组件 6.map 地…

企业寄件管理系统使用教程

专为企业量身打造的寄件管理类平台&#xff0c;也就是企业寄件管理系统。其存在的意义在哪里&#xff1f;又是如何运用的&#xff1f;我们往下看看......讨论它存在的意义在哪里&#xff0c;我们先来看看企业普遍存在的寄件场景痛点&#xff1a;1、最早的手写快递单&#xff0c…

一维差分(例acwing重新排序)

一维差分是为了解决访问一个数组中的几个区间&#xff0c;降低时间复杂度使用的差分就是前缀和的逆运算&#xff08;a[i]b[1]b[2]…b[i]&#xff09;差分的作用就是快速实现将数组部分加上一个数。例如给定一个数组 A 和一些查询 Li,Ri&#xff0c;求数组中第 Li 至第 Ri 个元素…

Maven高级-属性-版本管理-资源配置-多环境开发配置-跳过测试

Maven高级-属性 4.2)属性类别 1.自定义属性 2.内置属性 3.Setting属性 4.Java系统属性 5.环境变量属性 4.3)属性类别&#xff1a;自定义属性 作用 等同于定义变量&#xff0c;方便统一维护 定义格式&#xff1a; <!--定义自定义属性--> <properties><…

STM32MP157驱动开发——Linux ADC驱动

STM32MP157驱动开发——Linux ADC驱动0.前言一、ADC 简介1.ADC 简介2.STM32MP157 ADC简介二、ADC 驱动源码解析1.设备树下的 ADC 节点2.ADC 驱动源码分析1&#xff09;stm32_adc 结构体2&#xff09;stm32_adc_probe 函数3&#xff09;stm32_adc_iio_info 结构体三、驱动开发1.…

【深度学习】经典算法解读及代码复现AlexNet-VGG-GoogLeNet-ResNet(二)

链接: 【深度学习】经典算法解读及代码复现AlexNet-VGG-GoogLeNet-ResNet(一) 4.GoogLeNet 4.1.网络模型 GoogLeNet的名字不是GoogleNet&#xff0c;而是GoogLeNet&#xff0c;这是为了致敬LeNet。GoogLeNet和AlexNet/VGGNet这类依靠加深网络结构的深度的思想不完全一样。Go…

创建Vue3项目以及引入Element-Plus

创建Vue3项目以及引入Element-Plus 前提条件&#xff1a;本地需要有node环境以及安装了npm&#xff0c;最好设置了镜像&#xff0c;这样下载包的时候会快些。 1、安装vue脚手架vue-cli3 npm install vue/cli -g2、安装后查看vue的版本 vue -V3、创建Vue项目&#xff0c;项目…

通信电子、嵌入式类面试题刷题计划01

文章目录001——什么是奈奎斯特采样定理&#xff1f;002——有源滤波器和无源滤波器的区别是什么&#xff1f;003——什么是反馈电路&#xff1f;请举出相关应用004——什么是竞争冒险现象&#xff1f;如何消除和避免此类现象005——什么是基尔霍夫定理&#xff1f;006——if e…

揣着一口袋的阳光满载而归--爱摸鱼的美工(13)

-----------作者&#xff1a;天涯小Y 揣着一口袋的阳光满载而归&#xff01; 慷懒周末 睡到自然醒&#xff0c;阳光洒在书桌上 套进宽松自在的衣服里 出门&#xff0c;去楼下坐坐 在阳光里吃午餐 在阳光里打个盹 在阳光里看猫咪上蹿下跳 在阳光里点个咖啡外卖 虚度时光&#xf…

【CANN训练营第三季】TBE算子开发

文章目录直播学习结业考核直播学习 安装准备&#xff1a;https://www.hiascend.com/document/detail/zh/mindstudio/50RC3/instg/instg_000022.html 开发参考: https://www.hiascend.com/document/detail/zh/CANNCommunityEdition/600alpha003/operatordevelopment/opdevg/atla…

基础算法(八)——离散化

离散化 介绍 这里的离散化&#xff0c;特指整数的、保序的离散化 有些题目可能需要以数据作为下标来操作&#xff0c;但题目给出的数据的值比较大&#xff0c;但是数据个数比较小。此时就需要将数据映射到和数据个数数量级相同的区间&#xff0c;这就是离散化&#xff0c;即…

Java学习笔记——继承(上)

目录继承入门继承的好处继承的特点继承中成员变量的访问特点this和super访问成员的格式继承中成员方法的访问特点方法重写概述和应用场景方法重写的注意事项权限修饰符继承入门 继承的好处 好处&#xff1a; 提高了代码的复用性。 提高了代码的维护性。 让类与类之间产生了关系…

static关键字分别在C和C++中的作用

static用于实现多个对象之间的数据共享 隐藏使用静态成员不会破坏隐藏规则默认初始化为0 1. C语言中static的特性&#xff08;面向过程设计中&#xff09; 局部变量&#xff1a;在任意一个函数内部定义的变量&#xff08;不加static&#xff09;&#xff0c;初始值不确定&am…

11、JS笔记-内置内置对象

1.内置对象 js中对象分为三种&#xff1a; 自定义对象、内置对象、浏览器对象&#xff08;js独有&#xff09; 内置对象&#xff1a; js语言自带的对象&#xff0c;供开发者使用&#xff0c;提供一些常用或基本的功能&#xff08;属性和方法&#xff09; 2.Math对象 Math中所…

Docker核心概念总结

文章目录容器容器概念物理机,虚拟机与容器的区别Docker简介Docker介绍Docker思想Docker容器的特点使用Docker的原因容器VS虚拟机对比图容器与虚拟机总结容器与虚拟机可以共存Docker 基本概念镜像&#xff08;Image&#xff09;一个特殊的文件系统容器&#xff08;Container&…

SpringSecurity认证功能的快速上手

简介 SpringSecurity是Spring家族中的一个安全管理框架。相比于另外一个安全框架Shiro&#xff0c;它提供了更丰富的功能&#xff0c;社区资源也比Shiro丰富。一般来说中大型项目都是使用SpringSecurity来做安全框架&#xff0c;小项目用Shiro的比较多&#xff0c;因为相比于S…