H5大前端(Web前端)学习笔记(五)- Vue

VUE

Vue开发前的准备

  • 安装Vue工具

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

npm insta11 -g @vue/cli

安装之后,你就可以在命令行中访问vue命令。你可以通过简单运行vue,看看是否展示出了一份所有可用命令的帮助信息,来验证它是否安装成功。

vue --version

在这里插入图片描述

  • 创建一个项目

运行以下命令来创建一个新项目

vue create vue-demo

温馨提示
在控制台中,可以用上下按键调整选择项
在控制台中,可以用空格(spacebar)选择是否选中和取消选中

可以选择默认项目模板,或者选“手动选择特性”来选取需要的特性。
在这里插入图片描述
我们选择 BabelProgressive Web App (PWA) Support 两个选项即可

温馨提示
不要选中 Linter/Fomatter 以避免不必要的错误提示
在这里插入图片描述

Vue目前有两个主流大版本 vue2 和 vue3 ,选择 vue3 最新版本
在这里插入图片描述
配置放在哪里:In dedicated config files专用配置文件或者In package.json 在package.json文件
在这里插入图片描述

将其保存为未来项目的预置?y代表保存,并添加名字,n不保存
在这里插入图片描述

  • 项目创建成功如下提示信息
    在这里插入图片描述

  • 运行项目

    • 第一步:进入项目根目录cd vue-demo
    • 第二步:运行npm run serve启动项目
      在这里插入图片描述
  • 安装Vue高亮插件

    • VSCode中安装vetur或者volar都可,前者针对Vue2版本,后者针对Vue3版本

模板语法

文本

数据绑定最常见的形式就是使用“Mustache”(双大括号)语法的文本插值

<span>Message:{{ message }}</span>

一般配合JS中的data()设置数据

export default {
  name: 'HelloWorld',
  data(){
    return {
      message:"文本"
    }
  }
}

原始HTML

双大括号会将数据解释为普通文本,而非HTML代码。为了输出真正的HTMl,需要使用v-html指令

<div>{{ rawHtml }}</div>
<div v-html="rawHtml"></div>
data(){
    return {
      rawHtml:"<a href='https://www.baidu.com'>百度</a>"
    }
  }

属性Attribute

Mustache语法不能在HTML属性中使用,然而可以使用v-bind指令

<div v-bind:id="dynamicID"></div>
data(){
    return {
      dynamicID:10001
    }
  }

温馨提示
v-bind可以简写成:

使用JavaScript表达式

Vue.js提供了完整的JavaScript表达式支持

{{ number + 1 }}

{{ ok ? 'Yes' : 'No' }}

{{ message.split('').reverse().join('') }}

这些表达式会在当前活动实例的数据作用域下作为JavaScript被解析,有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。

<!-- 这是语句,不是表达式 -->
{{ var a = 1 }}

<!-- 流程控制也不会生效,需要使用三元表达式 -->
{{ if (ok) { return message } }}

列表渲染

  • v-for把一个数组映射为一组元素

我们可以用v-for指令基于一个数组来渲染一个列表。v-for指令需要使用item in items形式的特殊语法,其中items是源数据数组,而item则是被迭代的数组元素的别名

	<ul>
      <li v-for="item in newsList">
        {{item.title}}
      </li>
    </ul>
  data(){
    return {
      newsList:[
        {
          id : 1001,
          title : "今日新闻1"
        },
        {
          id : 1002,
          title : "今日新闻2"
        },
        {
          id : 1003,
          title : "今日新闻3"
        },
      ]
    }
  }
  • 维护状态

当Vue正在更新使用v-for渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue将不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。
为了给Vue一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,需要为每一项提供一个唯一的key attribute:

<li v-for="(item,index) in newsList" :key="item.id | index">

事件处理

  • 监听事件

我们可以使用v-on指令(通常缩写为@符号)来监听DOM事件,并在触发事件时执行一些JavaScript。
用法为v-on:click="methodName"或使用快捷方式@click="methodName"

  • 事件处理方法

许多事件处理逻辑会更为复杂,所以直接把JavaScript代码直接写在v-on指令中时不可行的,因此v-on指令还可以接收一个需要调用的方法名称。

    <button @click="clickHandle">按钮</button>
    <p>{{ message }}</p>
  data(){
    return {
      message:'消息'
    }
  },
  methods:{
    clickHandle(event){
      //在事件中,读取data中的属性,需要通过this.属性
      this.message = "xxxx";
      // event 是原生的DOM event
      console.log(event);
      event.target.innerHTML = "点击之后";
    }
  }
  • 内联处理器中的方法

这是官方的翻译称呼,其实可以称之为“事件传递参数”

    <button @click="say('hi')">say hi</button>
    <button @click="say('hello')">say hello</button>
  methods:{
    say(data){
      console.log(data);
    }
  }

表单输入绑定

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

    <input type="text" v-model="username">
    <p>{{ username }}</p>
  data(){
    return {
      username:""
    }
  }

修饰符

  • .lazy

    • 在默认情况下,v-model在每次input事件触发后将输入框的值与数据进行同步。可以添加.lazy修饰符,从而转为在change(失去焦点/回车)事件之后同步
  • .trim

    • 如果要自动过滤用户输入的首尾空格,可以使用.trim修饰符

组件基础

单文件组件

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

<template>
    <div></div>
</template>

<script>

export default{
    name:"MyComponent",
}

</script>
<!-- scoped:如果在style中添加此属性,戴白哦当前样式只在当前组件中生效 -->
<style scoped>

</style>

加载组件

  • 第一步:引入组件import MyComponent from './components/MyComponent.vue'
  • 第二步:挂载组件components:{MyComponent}
  • 第三步:显示组件<MyComponent /><my-component />

组件的组织

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

Props组件交互

组件与组件之间是需要存在交互的,否则完全没关系,组件的意义就很小了
Prop是你可以在组件上注册的一些自定义attribute

  • 父组件
<MyComponent :title="title" :age="age"/>
  data(){
    return{
      title:"这是一个标题",
      age:20
    }
  }
  • 子组件
<template>
    <div>
        <p>{{ title }}</p>
        <p>age={{ age }}</p>
    </div>
</template>

<script>

export default{
    name:"MyComponent",
    props:{
        title:{
            type:String,
            default:""
        },
        age:{
            type:Number,
            default:0
        }
    }
}

</script>
<style scoped>

</style>

Prop类型

Prop传递参数其实是没有类型限制的

props:{
	title: String,
	likes: Number,
	isPublished: Boolean,
	commentIds: Array,
	author: Object,
	callback: Function
}

温馨提示
数据类型为数组或者对象的时候,默认值是需要返回工厂模式

names:{
	type:Array,
	//数组和对象必须使用函数进行返回
	default:function(){
		return []
	}
}

自定义事件组件交互

自定义事件可以在组件中反向传递数据,prop可以将数据从父组件传递到子组件,可以利用自定义事件$emit实现反向传递

  • 子组件
<template>
  <div>
    <h3>自定义事件</h3>
    <button @click="sendClickHandle">传递数据</button>
  </div>
</template>

<script>

export default{
  name:"MyComponent",
  data(){
    return{
        message:"MyComponent"
    }
  },
  methods:{
    sendClickHandle(){
        //参数1:字符串:理论上是随意的,但是需要具有意义
        //参数2:传递的数据
        this.$emit("onEvent",this.message)
    }
  }
}

</script>
<style scoped>

</style>
  • 父组件
<MyComponent @onEvent="getDataHandle"/>
methods:{
    getDataHandle(data){
      console.log(data);
      this.message = data;
    }
  }

Vue引入第三方

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

温馨提示
官方文档:https://swiperjs.com/vue
安装指定版本:npm install --save swiper@8.1.6

Axios网络请求

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

安装

Axios的应用是需要单独安装的

npm install --save axios

引入

  • 组件中引入:import axios from "axios"
  • 全局引用:
import axios from "axios"

const app = creatApp(App);
app.config.globalProperties.$axios = axios
app.mount('#app')

//在组件中调用
this.$axios

Axios网络请求封装

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

src目录下创建文件夹utils,并创建文件request.js,用来存储网络请求对象axios

import axios from "axios"
import querystring from "querystring"

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;
    }
}

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

// 拦截器最常用

// 发送数据之前
instance.interceptors.request.use(
    config =>{
        // config:包含网络请求的所有信息
        if(config.methods === "post"){
            config.data = querystring.stringify(config.data)
        }
        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;

src目录下创建文件夹api,并创建文件indexpath分别用来存放网络请求方法和请求路径

网络请求跨域解决方案

JS采取的是同源策略

  • 同源策略是浏览器的一项安全策略,浏览器只允许js代码请求和当前所在服务器域名,端口,协议相同的数据接口上的数据,这就是同源策略
  • 也就是说,当协议,域名,端口任意一个不同时,都会产生跨域问题

目前主流的跨域解决方案有两种:

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

vue.config.js中:

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer:{
    proxy:{
      '/api':{
        target: '<url>',//产生跨域的地址
        changeOrigin: true
      }
    }
  }
})

温馨提示
在解决完跨域配置之后,需要重启服务器

Vue引入路由配置

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

在Vue中引入路由

  • 第一步:安装路由npm install --save vue-router
  • 第二步:配置独立的路由文件
import { createRouter, createWebHashHistory } from "vue-router"
import HomeView from "@/views/HomeView.vue"
import About from "@/views/About.vue"

// 配置信息中需要页面的相关配置
const routes = [
    {
        path:"/",
        component:HomeView
    },
    {
        path:"/about",
        component:About
    }
]
const router = createRouter({
    /**
     * createWebHashHistory
     *    home: http://localhost:8080/#/
     *    about: http://localhost:8080/#/about
     * 
     *  原理:a标签锚点链接
     */
    /**
     * createWebHistory
     *    home: http://localhost:8080/
     *    about: http://localhost:8080/about
     *  此种方式需要后台配合做重定向,否则会出现404问题
     *  原理: H5 pushState()
     */
    history: createWebHashHistory(),
    routes
})
export default router;
  • 第三步:引入路由到项目
// main.js
import router from './router'
app.use(router)
  • 第四步:指定路由显示入口
<router-view />
  • 第五步:指定路由跳转
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>

路由传递参数

页面跳转过程中,是可以携带参数的

  • 第一步:在路由配置中指定参数的key
{
	path:"/list/:name",
	name:"list",
	component:() => import("../views/ListView.vue")
}
  • 第二步:在跳转过程中携带参数
<router-link to="/list/xxx"></router-link>
  • 第三步:在详情页面当中读取路由携带的参数
<p>{{ $route.params.name }}</p>

嵌套路由配置

路由嵌套是非常常见的需求

  • 第一步:创建子路由要加载显示的页面
  • 第二步:在路由配置文件中添加子路由配置
{
	path:"/list",
	name:"list",
	redirect:"/list/list1",
	component:() => import("../views/ListView.vue"),
	children:[
		{
			// 二级路径不要加 /
			path:"list1",
			component:() => import("...")
		},
		{
			path:"list2",
			component:() => import("...")
		}
	]
}
  • 第三步:指定子路由显示位置<router-view></router-view>
  • 第四步:添加子路由跳转链接<router-link>
  • 第五步:重定向配置 redirect:"/list/list1"

Vue状态管理(Vuex)

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

引入Vuex的步骤

  • 第一步:安装Vuex npm install --save vuex
  • 第二步:配置Vuex文件
import { createStore } from "vuex"

// Vuex的核心作用就是 管理组件之间的状态
export default createStore({
    // 所有的状态都放在这里(数据)
    state:{
        counter : 0
    }
})
  • 第三步:在主文件中引入Vuex
import store from "./store"
app.use(store)
  • 第四步:在组件中读取状态
<!-- 第一种方式 -->
<p>{{ $store.state.counter }}</p>
<!-- 第二种方式 -->
<p>{{ counter }}</p>
import { mapState } from "vuex"
// 专门读取Vuex的数据
computed:{
	...mapState(["counter"])
}

Vue状态管理核心(Vuex)

Getter

对Vuex中的数据进行过滤

import { createStore } from "vuex"
export default createStore({
    state:{
        counter : 0
    },
    getters:{
    	getCounter(state){
    		return state.counter > 0 ? state.counter : "counter数据异常"
    	}
    }
})

读取数据

// 第一种
<p>{{ $store.getters.getCounter }}</p>
// 第二种
<p>{{ getCounter }}</p>
import { mapGetters } from "vuex"
computed:{
	...mapGetters(["getCounter"])
}

Mutation

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

import { createStore } from "vuex"
export default createStore({
    state:{
        counter : 0
    },
    getters:{
    	getCounter(state){
    		return state.counter > 0 ? state.counter : "counter数据异常"
    	}
    },
    mutations:{
    	addCounter(state, num){
    		state.counter += num
    	}
    }
})

调用事件

// 第一种
methods:{
	addClickHandle(){
		// 固定调用方式
		this.$store.commit("addCounter", 15)
	}
}
// 第二种
import { mapMutations } from "vuex"
methods:{
	...mapMutation(["addCounter"]),
	addClickHandle(){
		this.addCounter(15)
	}
}

Action

Action类似于Mutation,不同在于:

  • Action提交的是mutation,而不是直接改变状态
  • Action可以包含任意异步操作
// actions 为异步操作所准备的
actions:{
	asyncAddCount({ commit }){
		// 假设数据来源于网络请求
		axios.get("...").then(res => {
			// 使用方式
			commit("addCounter", res.data[0])
		})
	}
}

调用事件

// 第一种
methods:{
	addAsyncClickHandle(){
		// 固定调用方式
		this.$store.dispatch("asyncAddCount")
	}
}
// 第二种
import { mapActions} from "vuex"
methods:{
	...mapActions(["asyncAddCount"]),
	addClickHandle(){
		this.asyncAddCount();
	}
}

Vue3新特性

  • 六大亮点
    • Performance:性能更比Vue 2.0强。
    • Tree shaking support:可以将无用模块“剪辑”,仅打包需要的。
    • Composition APl: 组合API
    • Fragment, Teleport, Suspense:“碎片”,Teleport即Protal传送门,“悬念”
    • Better TypeScript support:更优秀的Ts支持
    • Custom Renderer APl:暴露了自定义渲染API

ref或者reactive

在2.x中,通过组件data的方法来定义一些当前组件的数据

data(){
	return {
		name: "xxx",
		list: [],
	}
}

在3.x中,通过ref或者reactive创建响应式对象

import { ref,reactive } from "vue"
export default {
	name: 'ListView',
	// 组合式API
	setup(){
		// ref
		const message = ref("这是一条message")// reactive
		const names = reactive({
			list:['x1','x2','x3']
		})
		return{
			message,
			names
		}
	}
}

methods中定义的方法写在setup()

在2.x中methods来定义一些当前组件中的内部方法

methods:{
	fun(){}
}

在3.x中直接在setup方法中定义并return

setup(){
	const fun = ()=>{
		// some code
	}
	return{
		fun
	}
}

setup()中使用props和context

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

export default {
	props:{
		name:String,
	},
	setup(props,ctx){
		console.log(props.name)
		// setup中没有this关键字
		ctx.emit('event')
	},
}

setup()中使用生命周期函数

可以通过在生命周期钩子前面加上“on”来访问组件的生命周期钩子。

import { onMounted } from "vue"
export default{
	setup(){
		// 比2.x有优势,以前同一个生命周期函数只能存在一个,现在可以存在多个
		onMounted(() =>{
			// some code 1
		}),
		onMounted(() =>{
			// some code 2
		})
	}
}

Provide / Inject

  • provide()inject()可以实现嵌套组件之间的数据传递。
  • 这两个函数只能在 setup() 函数中使用。
  • 父级组件中使用 provide()函数向下传递数据。
  • 子级组件中使用 inject()获取上层传递过来的数据。
  • 不限层级
// 父组件
import { provide } from "vue"
setup(){
	provide("customVal", "父组件向子组件传递的值");
}
// 子组件
import { inject } from "vue"
setup(){
	const customVal = inject("customVal");
	return{
		customVal
	}
}

Fragment

  • 不再限于模板中的单个根节点
  • 30
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

30ring

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值