Vue学习笔记

文章目录

前端框架

vue官网:https://cn.vuejs.org/guide/introduction.html

Vue基础知识

环境搭建

线上尝试

  • 想要快速体验 Vue,你可以直接试试我们的演练场。

  • 如果你更喜欢不用任何构建的原始 HTML,可以使用 JSFiddle 入门。

  • 如果你已经比较熟悉 Node.js 和构建工具等概念,还可以直接在浏览器中打开 StackBlitz 来尝试完整的构建设置。

CDN使用

<script
src="https://unpkg.com/vue
@3/dist/vue.global.js">
</>

通过CDN使用Vue时,不涉及“构建步骤”。这使得设置更加简单,并且可以用于增强静态的HTML或与后端框架集成。但是,你将无法使用单文件组件(SFC)语法。

Vue CLI

Vue CLI 是官方提供的基于 Webpack 的 Vue 工具链,它现在处于维护模式。我们建议使用 Vite 开始新的项目,除非你依赖特定的 Webpack 的特性。在大多数情况下,Vite 将提供更优秀的开发体验。

Vite

Vite 是一个轻量级的、速度极快的构建工具,对 Vue SFC 提供第一优先级支持。作者是尤雨溪,同时也是 Vue 的作者!要使用 Vite 来创建一个 Vue 项目,非常简单:

npm init vue@latest

这个命令会安装和执行 create-vue,它是 Vue 提供的官方脚手架工具。跟随命令行的提示继续操作即可。

开发准备

安装Vue工具Vue CLI

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

npm install -g  @vue/cli

安装之后,就可以在命令行中访问vue命令。验证是否安装成功。

vue --version

创建一个项目

运行以下命令

vue create vue-demo(必须全小写)

1.选择Manually select features
2.空格选中,再次空格取消选择
3.去除“Linter / Formatter”
4.选择该选择的安装

运行项目

1.进入项目根目录 cd vue-demo
2.npm run serve

安装Vue高亮插件

Volar:vue3
Vetur: vue2

  • 推荐使用的 IDE 是 VSCode,配合 Vue 语言特性 (Volar) 插件。该插件提供了语法高亮、TypeScript 支持,以
    及模板内表达式与组件 props 的智能提示。
  • Volar 取代了我们之前为 Vue 2 提供的官方 VSCode 扩展 Vetur。如果你之前已经安装了 Vetur,请确保在
    Vue 3 的项目中禁用它

模板语法

文本

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

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

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

export default {
  name: 'HelloWorld',
  data(){
    return{
      msg:"消息提示"
    }
  }
}

原始HTML

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

<p>Using mutaches:{{rawhtml}}</p>
<p>Using v-html directive:<span v-html="rawhtml"></span></p>
data(){
    return{
      rawhtml:"<a href='https://www.baidu.com' target=_blank>baidu</a>"
    }
  }

属性Attribute

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

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

v-bind: 可以简写为:

使用javascript表达式

在我们的模板中,我们一直都只绑定简单的property键值,vue.js都提供了完全的js表达式支持。

{{ number + }}
{{ ok ? 'yes' : 'no'}}
{{ message.split('').reverse().join('') }}

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

<!-- 这是语句,不是表达式 -->
{{var a = 1}}
<!-- 流程控制也不会生效,请使用三元表达式 -->
{{if (ok) {return message} }}

条件渲染

v-if

v-if 指令用于条件性渲染一块内容。这块内容只会在指令的表达式返回true值时被渲染。

<p v-if ="flag">Vue</p>
  data(){
    return{
      flag:true
    }
  }

v-else

使用v-else指令来表示v-if的“else”块

<p v-if ="flag">你是猴子</p>
<p v-else ="flag">你不是猴子</p>
data(){
    return{
    flag:true
    }
}

v-show

用于条件性展示元素的选项是v-show指令

<h1 v-show="flag">hello</h1>
  • v-if he v-show 的区别
  1. v-if是真正的条件渲染,因为它会确保在切换过程中,条件块内的事件监听器和子组件适当地被销毁和重建。
  2. v-if也是惰性的:如果在初始渲染时条件为假,则什么也不做一一直到条件第一次变为真时,才会开始渲染条件快。
  3. 相比之下,v-show不管初始条件是什么,元素总是会被渲染。并且只是简单的基于css进行切换。display:none
  4. 一般来说,v-if有更高的切换开销,而v-show有更高的初始渲染开销。因此,如果需要非常频繁的切换,则使用v-show较好;如果在运行时条件很少改变,则使用v-if较好。

列表渲染

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

用v-for指令基于一个数组来渲染一个列表。v-for指令需要使用item in items形式的特殊语法。

<ul>
    <li v-for="item in items">{{ item.msg }}</li>
</ul>
data(){
    return{
        items:[{msg:"foo"},{msg:"bar"}]
    }
}

维护状态

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

<div v-for="(item,index) in items" :key="item.id|index">
    <!-- content -->
</div>

事件处理

监听事件

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

<button @click="counter +=1"> add {{ counter }}</button>
data(){
    return{
        counter:0
    }
}

事件处理方法

直接把js代码写在v-on指令中时不可行的。因此v-on还可以接收一个需要调用的方法名称。

<button @click="clickhandle"> {{greet}}</button>
  methods:{
    clickhandle(event){
      // event 是原生dom event
      console.log(event)
      // 在事件中,读取data中的属性,是需要通过this.属性
      // this.greet = "触发点击"
      event.target.innerHtml = "点击之后"
    }
  }

内联处理器中的方法

也叫“事件传递参数”

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

表单输入绑定

双向数据绑定

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

<input v-model= "message" placeholder="edit me "/>
<p> message is :{{ message }}</p>
  data(){
    return{
      message:""
    }
  }

修饰符

  • .lazy
    在默认情况下,v-model在每次input事件触发后将输入框与数据进行同步。可以添加lazy修饰符,从而转为在change事件之后进行同步。
<input v-model.lazy = "message"/>
<p> msg:{{message}} </p>
  data(){
    return{
      message:""
    }
  }
  • .trim
    如果要自动过滤用户输入的首尾空白字符,可以给v-model添加trim修饰符。
<input v-model.trim = "message"/>
  data(){
    return{
      message:""
    }
  }

组件基础

单文件组件

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

<template>
    <h3>我是单文件组件</h3>
</template>

<script>
export default {
    name:"MyComponent",
}    
</script>

<!-- scoped:如果在style中添加此属性,就代表着,当前样式只在当前组件中生效。 -->
<style scoped>
    h3{
        color:red
    }
</style>

加载组件

1.引入组件 import MyComponent from "./components/MyComponent.vue"
2.挂载组件 components:{MyComponent}
3.显示组件<my-MyComponent->

组件的组织

以一棵嵌套的组件树的形式来组织
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-31QullNr-1691407438335)(image-2.png)]

Props组件交互

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

<MyComponent :title="title"/>

export default {
  name: 'App',
  data(){
    return{
      title:"标题"
    }
  },
<template>
    <h2>prop 传递数据</h2>
    <p>{{ title }}</p>
</template>
  
<script>
export default {
    name: 'Mycomponent',
    props:{
        title:{
            type:String,
            default:""
        }
    }
}
</script>

props类型

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

props:{
        title:{
            type:String,
            default:""
        },
        likes:{
            type:Number,
            default:0
        },
        ispublished:{
            type:Boolean,
            default:false
        },
        commentIds:{
            type:Array,
            // 数组和对象必须使用函数进行返回
            default:function(){
                return []
            }
        },
        // author:Object,
        // calllback:Function
    }
}

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

自定义事件组件交互

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

<template>
    <button @click="sendClickHandle">点击传递</button>
</template>
  
<script>
export default {
    name: 'Mycomponent',
    data(){
        return {
            message:"我来自子组件"
        }
    },
    methods:{
        sendClickHandle(){
            // 参数1:字符串:理论上是随便的,但是需要具有意义
            // 参数2:传递的数据
            this.$emit("onEvent",this.message)
        }
    }
}
</script>
<MyComponent @onEvent="getDataHandel"/>

methods:{
    getDataHandel(data){
      console.log(data);
    }
  }

组件的生命周期

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

<template>
    <h3>生命周期函数</h3>
    <p>{{ message }}</p>
    <button @click="message='数据'">点击</button>
</template>
  
<script>
export default {
    name: 'Mycomponent',
    data(){
        return {
            message:"我是组件"
        }
    },
    beforeCreate(){
        console.log("beforeCreate:组件创建前")
    },
    created(){
        console.log("beforeCreate:组件创建完成")
    },
    beforeMount(){
        console.log("beforeCreate:组件渲染之前")
    },
    mounted(){
        console.log("beforeCreate:组件渲染完成")
        // 网络请求放到这里
    },
    beforeUpdate(){
        console.log("beforeCreate:组件更新之前")
    },
    updated(){
        console.log("beforeCreate:组件更新完成")
    },
    beforeUnmount(){
        console.log("beforeCreate:组件卸载之前")
        // 卸载之前,把消耗性能的处理都干掉
        // 定时器
    },
    unmounted(){
        console.log("beforeCreate:组件卸载完成")
    },
}

Vue引入第三方

github合作第三方(注意vue3和vue2区别):https://github.com/vuejs/awesome-vue

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CHnzfwKz-1691407438335)(image-3.png)]

swiper

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

结合vue官方文档:https://swiperjs.com/vue
安装指定版本并直接放到package.json:npm install --save swiper@8.1.6

Axios网络请求

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

安装

axios的应用是需要单独安装的npm install --save axios

引入

组件中引入:import axios from “axios”
全局引用:在main.js文件中引入

import axios from 'axios'

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

get请求

// get请求方式
axios({
    method:"get",
    url:"http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php"
}).then(res =>{
console.log(res.data)
})

// 全局快速
this.$axios.get("http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php")
.then(res =>{
console.log(res.data)
})

post请求

post请求参数是需要额外处理的
安装依赖:npm install --save querystring
转换参数格式:qs.stringify({})

import qs from "querystring"


axios({
    method:"post",
    url:"http://iwenwiki.com/api/blueberrypai/getChengpinDetails.php",
    data:qs.stringify({
    user_id:"iwen@qq.com",
    password:"iwen123",
    verification_code:"crfvw"
    })
}).then(res =>{
console.log(res.data)
})

// 全局快速
this.$axios.post("http://iwenwiki.com/api/blueberrypai/login.php",qs.stringify({
        user_id:"iwen@qq.com",
        password:"iwen123",
        verification_code:"crfvw"
      }))
      .then(res =>{
        console.log(res.data)
      })

Axios网络请求封装

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

import axios from "axios"
import { Promise } from "core-js"
import qs from "querystring"

// 参考文档
// https://www.axios-http.cn/docs/req_config
// https://www.kancloud.cn/yunye/axios/234845/234845

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 =>{
        if(config.method === "post"){
            config.data = qs.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;

网络请求跨域解决方案

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

跨域错误提示信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-11XJQHLk-1691486336485)(image.png)]

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

1.后台解决:cors
2.前台解决:proxy
在vue.config.js添加一下配置,最后重启服务器。

devServer:{
    proxy:{
      '/api':{
        target:"域名",
        changOrigin:true
      }
    }
  }

Vue引入路由配置

注意:如果在@vue/cli安装中勾选了路由,就会自动创建路由配置
在vue中,通过vue-router路由管理页面之间的关系。
vue router是vue.js的官方路由。它与vue.js核心深度集成,让vue.js构建单页应用轻而易举。

Vue中引入路由

1.安装路由 npm install --save vue-router
2.配置独立的路由文件

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

// 配置信息中需要页面的相关配置
const routes = [
    {
        path:"/",
        name:"home",
        component : HomeView
    },
    {
        path:"/about",
        name:"about",
        // 异步加载方式
        component : () => import('../views/AboutView.vue')
    },
]

const  router = createRouter({
    createWebHashHistory
        http://localhost:8080/#/about
    原理:a标签锚点连接

    createWebHistory
        http://localhost:8080/about
    此种方式,需要后台配合做重定向,否则会出现404问题
    原理:H5 pushState()


    history:createWebHashHistory(),
    routes
})

export default router

3.引入路由到项目

// main.js
import router from "./router"
app.use(VueRouter)

4.指定路由显示入口
5.指定路由跳转

<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>

路由传递参数

1.在路由配置中指定参数的key

{
    path:"/list/:name(/:class)",
    name:"list",
    component:() => import("../views/ListView.vue")
}

2.在跳转过程中携带参数

<li><router-link to= "/list/内蒙">内蒙旅游</router-link></li>
<li><router-link to= "/list/北京">北京旅游</router-link></li>
<li><router-link to= "/list/四川">四川旅游</router-link></li>

3.在详情页面读取路由携带的参数

<p>{{ $route.params.name}}城市旅游</p>

嵌套路由配置

1.创建子路由要加载的显示页面
2.在路由配置文件中添加子路由配置

{
    path:"/news",
    name:"news",
    redirect:"/news/baidu",
    component:() => import("../views/NewsView.vue"),
    // 二级导航的路径不要加/
    children:[
        {
            path:"baidu",
            component:() => import("../views/NewsList/Baidu.vue"),
        },
        {
            path:"wangyi",
            component:() => import("../views/NewsList/Wangyi.vue"),
        }
    ]
}

3.指定子路由显示位置
4.添加子路由跳转链接

<router-link to="/news/baidu">Home</router-link>
<router-link to="/news/wangyi">About</router-link>

5.重定向配置redirect:“/news/baidu”

Vue状态管理(Vuex)

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3uCl6t7Q-1691486336486)(image-1.png)]

引入Vuex的步骤

安装vue-cli时可以直接集成

1.按照Vuex npm install --save vuex
2.配置Vuex文件

//store/index.js
import {createStore} from 'vuex'

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

3.在主文件中引入Vuex

// main.js
import store from './store'
app.use(store)

4.在组件中读取状态

<p>counter:{{ $store.state.counter}}</p>
// 或者vuex提供的快捷读取方式
import {mapstate} from 'vuex'
computed:{
    ...mapstate(["counter"])
}

Vue状态管理核心(Vuex)

最常用的核心概念包含:State、Getter、Mutation、Action

Getter

对Vuex中的数据进行过滤

//store/index.js
import {createStore} from 'vuex'
export default createStore({
    state:{
        counter:0
    },
    getters:{
        getCount(state){
            return state.counter > 0 ?state.counter:"counter小于0,不符合要求"
        }
    }
})
import { mapGetters } from 'vuex';
computed:{
    ...mapGetters(["getCount"])
},
Mutation

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

//store/index.js
import {createStore} from 'vuex'

//Vuex的核心作用就是帮我们管理组件之间的状态
export default createStore({
    // 所有的状态都放在这里(数据)
    state:{
        counter:0
    },
    getters:{
        getCount(state){
            return state.counter > 0 ?state.counter:"数据异常"
        }
    },
    mutations:{
        addCounter(state,num){
            state.counter +=num
        }
    }
})
// 应用
<button @click="addClickHandle">add</button>
import { mapGetters,mapMutations } from 'vuex';

 methods:{
    ...mapMutations(["addCounter"]),
    addClickHandle(){
    //   // 固定调用方法
    //   this.$store.commit("addCounter",15)
      this.addCounter(20)
    }
  }
Action

Action类似于mutation,不同在于:

  • Action提交的是mutation,而不是直接变更状态
  • Action可以包含任意异步操作
import axios from 'axios'
import {createStore} from 'vuex'

//Vuex的核心作用就是帮我们管理组件之间的状态
export default createStore({
    // 所有的状态都放在这里(数据)
    state:{
        counter:0
    },
    getters:{
        getCount(state){
            return state.counter > 0 ?state.counter:"数据异常"
        }
    },
    mutations:{
        addCounter(state,num){
            state.counter +=num
        }
    },
    // 为异步操作所准备的
    actions:{
        asyncAddCounter({commit}){
            axios.get("http://iwenwiki.com/api/generator/list.php")
            .then(res =>{
                // 调用mutations
                commit("addCounter",res.data[0])
            })
        }
    }
})
// 应用
<button @click="addAsyncClickHandle">async——add</button>

import {mapActions } from 'vuex';

methods:{
    ...mapMutations(["addCounter"]),
    ...mapActions(["asyncAddCounter"]),
    addAsyncClickHandle(){
      // this.$store.dispatch("asyncAddCounter")
      this.asyncAddCounter();
    }
  }

Vue3新特性

六大亮点

  • performance:性能比vue2.0强
  • tree shaking support:可以将无用模块“剪辑”,仅打包需要的。
  • composition api:组合api
  • fragment,teleport,suspense:“碎片”,teleport即protal传送门,“悬念”
  • better TypeScript support:更优秀的ts支持
  • custom renderer api:暴露了自定义渲染api

ref 或者reactive

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

data(){
    return {
        name:'soner',
        list:[]
    }
}

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

import {ref,reactive} from "vue"
export default{
    name:"helloworld",
    setup(){
        const name = ref("soerr")
        const state = reactive({
            list:[]
        })
        return {
            name,
            state
        }
    }
}

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

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

methods:{
    http(){}
}

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

setup(){
    const http =>()=>{
        // do something
    }
    return {
        http
    }
}

setup()中使用prop和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)
        ctx.emit('event')
    }
}

在setup中使用生命周期函数

可以通过生命周期钩子前面加上“on”来访问组件的生命周期钩子。
下表包含如何在setup()内部调用生命周期钩子
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s9bWLGSP-1691486336486)(image-2.png)]

export default {
    setup(){
        // 相比于之前的生命周期函数,这里可以使用多次
        onMounted(() => {
            // do something 
        })
    }
}

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

Fragment 翻译为“碎片”

  • 不再限于模板中的单个根节点
<template>
    <img alt="vue logo" src= "./assets/logo.png">
    <helloworld msg="welcome to your vue.js app"/>
    <div></div>
</template>

vue3加载element-plus

https://element-plus.org/zh-CN/guide/quickstart.html#%E6%8C%89%E9%9C%80%E5%AF%BC%E5%85%A5

vue基础知识

什么是Vue

概念:Vue (读音 /vjuː/,类似于 view) 是一套 **构建用户界面 ** 的 渐进式 框架

Vue2官网:https://v2.cn.vuejs.org/

1.什么是构建用户界面

基于数据渲染出用户可以看到的界面

在这里插入图片描述

2.什么是渐进式

所谓渐进式就是循序渐进,不一定非得把Vue中的所有API都学完才能开发Vue,可以学一点开发一点

Vue的两种开发方式:
  1. Vue核心包开发

    场景:局部模块改造

  2. Vue核心包&Vue插件&工程化

    场景:整站开发

3.什么是框架

所谓框架:就是一套完整的解决方案

举个栗子

如果把一个完整的项目比喻为一个装修好的房子,那么框架就是一个毛坯房。

我们只需要在“毛坯房”的基础上,增加功能代码即可。

提到框架,不得不提一下库。

  • 库,类似工具箱,是一堆方法的集合,比如 axios、lodash、echarts等
  • 框架,是一套完整的解决方案,实现了大部分功能,我们只需要按照一定的规则去编码即可。

下图是 库 和 框架的对比。

在这里插入图片描述

框架的特点:有一套必须让开发者遵守的规则或者约束

咱们学框架就是学习的这些规则 官网

创建Vue实例

我们已经知道了Vue框架可以 基于数据帮助我们渲染出用户界面,那应该怎么做呢?

在这里插入图片描述

比如就上面这个数据,基于提供好的msg 怎么渲染后右侧可展示的数据呢?

核心步骤(4步):

  1. 准备容器
  2. 引包(官网) — 开发版本/生产版本
  3. 创建Vue实例 new Vue()
  4. 指定配置项,渲染数据
    1. el:指定挂载点
    2. data提供数据

在这里插入图片描述

总结:创建Vue实例需要执行哪4步

插值表达式 {{}}

插值表达式是一种Vue的模板语法

我们可以用插值表达式渲染出Vue提供的数据

在这里插入图片描述

1.作用:利用表达式进行插值,渲染到页面中

表达式:是可以被求值的代码,JS引擎会讲其计算出一个结果

以下的情况都是表达式:

money + 100
money - 100
money * 10
money / 10 
price >= 100 ? '真贵':'还行'
obj.name
arr[0]
fn()
obj.fn()

2.语法

插值表达式语法:{{ 表达式 }}

<h3>{{title}}<h3>

<p>{{nickName.toUpperCase()}}</p>

<p>{{age >= 18 ? '成年':'未成年'}}</p>

<p>{{obj.name}}</p>

<p>{{fn()}}</p>

3.错误用法

1.在插值表达式中使用的数据 必须在data中进行了提供
<p>{{hobby}}</p>  //如果在data中不存在 则会报错

2.支持的是表达式,而非语句,比如:if   for ...
<p>{{if}}</p>

3.不能在标签属性中使用 {{  }} 插值 (插值表达式只能标签中间使用)
<p title="{{username}}">我是P标签</p>

响应式特性

1.什么是响应式?

​ 简单理解就是数据变,视图对应变。

2.如何访问 和 修改 data中的数据(响应式演示)

data中的数据, 最终会被添加到实例上

① 访问数据: “实例.属性名”

② 修改数据: “实例.属性名”= “值”

在这里插入图片描述

Vue开发者工具安装

  1. 通过谷歌应用商店安装(国外网站)
  2. 极简插件下载(推荐) https://chrome.zzzmh.cn/index

安装步骤:

在这里插入图片描述

安装之后可以F12后看到多一个Vue的调试面板

在这里插入图片描述

Vue中的常用指令

概念:指令(Directives)是 Vue 提供的带有 v- 前缀 的 特殊 标签属性

为啥要学:提高程序员操作 DOM 的效率。

vue 中的指令按照不同的用途可以分为如下 6 大类:

  • 内容渲染指令(v-html、v-text)
  • 条件渲染指令(v-show、v-if、v-else、v-else-if)
  • 事件绑定指令(v-on)
  • 属性绑定指令 (v-bind)
  • 双向绑定指令(v-model)
  • 列表渲染指令(v-for)

指令是 vue 开发中最基础、最常用、最简单的知识点。

内容渲染指令

内容渲染指令用来辅助开发者渲染 DOM 元素的文本内容。常用的内容渲染指令有如下2 个:

  • v-text(类似innerText)

    • 使用语法:<p v-text="uname">hello</p>,意思是将 uame 值渲染到 p 标签中
    • 类似 innerText,使用该语法,会覆盖 p 标签原有内容
  • v-html(类似 innerHTML)

    • 使用语法:<p v-html="intro">hello</p>,意思是将 intro 值渲染到 p 标签中
    • 类似 innerHTML,使用该语法,会覆盖 p 标签原有内容
    • 类似 innerHTML,使用该语法,能够将HTML标签的样式呈现出来。

代码演示:

 
  <div id="app">
    <h2>个人信息</h2>
	// 既然指令是vue提供的特殊的html属性,所以咱们写的时候就当成属性来用即可
    <p v-text="uname">姓名:</p> 
    <p v-html="intro">简介:</p>
  </div> 

<script>
        const app = new Vue({
            el:'#app',
            data:{
                uname:'张三',
                intro:'<h2>这是一个<strong>非常优秀</strong>的boy<h2>'
            }
        })
</script>

条件渲染指令

条件判断指令,用来辅助开发者按需控制 DOM 的显示与隐藏。条件渲染指令有如下两个,分别是:

  1. v-show

    1. 作用: 控制元素显示隐藏
    2. 语法: v-show = “表达式” 表达式值为 true 显示, false 隐藏
    3. 原理: 切换 display:none 控制显示隐藏
    4. 场景:频繁切换显示隐藏的场景

在这里插入图片描述

  1. v-if

    1. 作用: 控制元素显示隐藏(条件渲染)
    2. 语法: v-if= “表达式” 表达式值 true显示, false 隐藏
    3. 原理: 基于条件判断,是否创建 或 移除元素节点
    4. 场景: 要么显示,要么隐藏,不频繁切换的场景

在这里插入图片描述

示例代码:

  <div id="app">
    <div class="box">我是v-show控制的盒子</div>
    <div class="box">我是v-if控制的盒子</div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        flag: false
      }
    })
  </script>
  1. v-else 和 v-else-if

    1. 作用:辅助v-if进行判断渲染
    2. 语法:v-else v-else-if=“表达式”
    3. 需要紧接着v-if使用

示例代码:

  <div id="app">
    <p>性别:♂ 男</p>
    <p>性别:♀ 女</p>
    <hr>
    <p>成绩评定A:奖励电脑一台</p>
    <p>成绩评定B:奖励周末郊游</p>
    <p>成绩评定C:奖励零食礼包</p>
    <p>成绩评定D:惩罚一周不能玩手机</p>
  </div>
  
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>

    const app = new Vue({
      el: '#app',
      data: {
        gender: 2,
        score: 95
      }
    })
  </script>

事件绑定指令

使用Vue时,如需为DOM注册事件,及其的简单,语法如下:

  • <button v-on:事件名=“内联语句”>按钮
  • <button v-on:事件名=“处理函数”>按钮
  • <button v-on:事件名=“处理函数(实参)”>按钮
  • v-on: 简写为 @
  1. 内联语句

    <div id="app">
        <button @click="count--">-</button>
        <span>{{ count }}</span>
        <button v-on:click="count++">+</button>
      </div>
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
      <script>
        const app = new Vue({
          el: '#app',
          data: {
            count: 100
          }
        })
      </script>
    
  2. 事件处理函数

    注意:

    • 事件处理函数应该写到一个跟data同级的配置项(methods)中
    • methods中的函数内部的this都指向Vue实例
<div id="app">
    <button>切换显示隐藏</button>
    <h1 v-show="isShow">黑马程序员</h1>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        isShow: true
      }
    })
  </script>

3.给事件处理函数传参

  • 如果不传递任何参数,则方法无需加小括号;methods方法中可以直接使用 e 当做事件对象

  • 如果传递了参数,则实参 $event 表示事件对象,固定用法。

 <style>
    .box {
      border: 3px solid #000000;
      border-radius: 10px;
      padding: 20px;
      margin: 20px;
      width: 200px;
    }
    h3 {
      margin: 10px 0 20px 0;
    }
    p {
      margin: 20px;
    }
  </style>

 <div id="app">
    <div class="box">
      <h3>小黑自动售货机</h3>
      <button>可乐5</button>
      <button>咖啡10</button>
      <button>牛奶8</button>
    </div>
    <p>银行卡余额:{{ money }}</p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        money: 100
      }
    })
  </script>

属性绑定指令

  1. **作用:**动态设置html的标签属性 比如:src、url、title
  2. 语法:**v-bind:**属性名=“表达式”
  3. **v-bind:**可以简写成 => :

比如,有一个图片,它的 src 属性值,是一个图片地址。这个地址在数据 data 中存储。

则可以这样设置属性值:

  • <img v-bind:src="url" />
  • <img :src="url" /> (v-bind可以省略)
  <div id="app">
    <img v-bind:src="imgUrl" v-bind:title="msg" alt="">
    <img :src="imgUrl" :title="msg" alt="">
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        imgUrl: './imgs/10-02.png',
        msg: 'hello 波仔'
      }
    })
  </script>

列表渲染指令

Vue 提供了 v-for 列表渲染指令,用来辅助开发者基于一个数组来循环渲染一个列表结构。

v-for 指令需要使用 (item, index) in arr 形式的特殊语法,其中:

  • item 是数组中的每一项
  • index 是每一项的索引,不需要可以省略
  • arr 是被遍历的数组

此语法也可以遍历对象和数字

//遍历对象
<div v-for="(value, key, index) in object">{{value}}</div>
value:对象中的值
key:对象中的键
index:遍历索引从0开始

//遍历数字
<p v-for="item in 10">{{item}}</p>
item从1 开始

v-for中的key

语法: key=“唯一值”

作用:给列表项添加的唯一标识。便于Vue进行列表项的正确排序复用

**为什么加key:**Vue 的默认行为会尝试原地修改元素(就地复用

实例代码:

<ul>
  <li v-for="(item, index) in booksList" :key="item.id">
    <span>{{ item.name }}</span>
    <span>{{ item.author }}</span>
    <button @click="del(item.id)">删除</button>
  </li>
</ul>

注意:

  1. key 的值只能是字符串 或 数字类型
  2. key 的值必须具有唯一性
  3. 推荐使用 id 作为 key(唯一),不推荐使用 index 作为 key(会变化,不对应)

双向绑定指令

所谓双向绑定就是:

  1. 数据改变后,呈现的页面结果会更新
  2. 页面结果更新后,数据也会随之而变

作用:表单元素(input、radio、select)使用,双向绑定数据,可以快速 获取设置 表单元素内容

**语法:**v-model=“变量”

**需求:**使用双向绑定实现以下需求

  1. 点击登录按钮获取表单中的内容
  2. 点击重置按钮清空表单中的内容

在这里插入图片描述

<div id="app">
    账户:<input type="text"> <br><br>
    密码:<input type="password"> <br><br>
    <button>登录</button>
    <button>重置</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <script>
    const app = new Vue({
      el: '#app',
      data: {
        username: '',
        password: ''
      },
    })
  </script>

Vue2全家桶实战项目

概念

一个完整的项目,除了有组件有数据等跨域完成页面的渲染外,还需要一些其他功能。例如:路由、状态机、网络请求、UI框架等。在Vue官方配套的插件中,提供了Vue Router(路由) 和 Vuex(状态机)。所以,有些人会将Vue+Vue Router + Vuex称为“Vue全家桶”。

搭建Vue全家桶

1.创建项目

cmd到指定的路径,执行以下命令创建Vue项目:

vue create hx_web

说明:项目名,可更改,注意不要用中文和大写字母

2.选择创建模式

选择项目的安装方式(Manually)

Vue CLI v5.0.8
? Please pick a preset: (Use arrow keys)
 Default ([Vue 3] babel, eslint)    # 默认方式(vue3)
  Default ([Vue 2] babel, eslint)  # 默认方式(vue2)
>  Manually select features # 自定义安装

3.选择插件

选择项目中需要安装的插件,通过“空格”来切换是否选中。

 (*) Babel
 ( ) TypeScript
 ( ) Progressive Web App (PWA) Support
 (*) Router
 (*) Vuex
 (*) CSS Pre-processors
>( ) Linter / Formatter
 ( ) Unit Testing
 ( ) E2E Testing

说明:这一次我们总共选择4个插件:

  • Babel:用于将高版本的js语法转换为浏览器能够支持的低版本语法。
  • Router:路由插件;
  • Vuex:状态机插件
  • Css Pre-processors:CSS预处理器

4.选择Vue的版本

目前我们选择Vue2的版本:

? Choose a version of Vue.js that you want to    
start the project with
  3.x
> 2.x

5.选择路由模式

? Use history mode for router? (Requires proper  
server setup for index fallback in production)   
(Y/n) y

说明:后续可以在代码中更改

6.选择css预处理器

? Pick a CSS pre-processor (PostCSS, Autoprefixer
 and CSS Modules are supported by default): (Use 
arrow keys)
> Sass/SCSS (with dart-sass) 
  Less
  Stylus

7.选择插件配置代码的位置

我们选择的插件,会自动生成相关配置代码,需要选择这些配置的保存位置

? Where do you prefer placing config for Babel,  
ESLint, etc.? (Use arrow keys)
> In dedicated config files   # 保存在独立的文件中
  In package.json  # 保存在package.json中

8.是否保存以上配置

选择是否保存供下一次使用(当前的配置已生效)

? Save this as a preset for future projects?     
(y/N) y

save preset as :vue2_all

9.项目创建成功

🎉  Successfully created project hx_web.
👉  Get started with the following commands:     

 $ cd hx_web
 $ npm run serve

下载第三方插件

1.网络请求

npm i axios

2.UI框架

适配vue2:https://element.eleme.cn/#/zh-CN

vue add element
 WARN  There are uncommitted changes in the current repository, it's recommended to commit or stash them first.
? Still proceed? Yes

📦  Installing vue-cli-plugin-element...


added 1 package in 2s
✔  Successfully installed plugin: vue-cli-plugin-element

? How do you want to import Element? Fully import
? Do you wish to overwrite Element's SCSS variables? Yes
? Choose the locale you want to load zh-CN

说明:如果报错,卸载sass相关插件后再安装

npm uninstall node-sass sass sass-loader
npm install node-sass sass sass-loader

路由与SPA

SPA的概念

SPA是single Page Application的缩写,表示“单页应用”。单页应用,指的是整个项目中,只有一个.html页面。例如Vue项目中的public/index.html。

路由的概念

因为spa中只有一个页面,那么在组件中进行切换时,需要一个工具来进行辅助,帮助我们管理组件与浏览器路径之间的关系。所以,Vue Router路由插件,就为我们提供了这样的功能:

  1. 可以通过路由来管理路径和组件之间的对应关系
  2. 当路径发生改变时,路由会切换页面中对应的组件

路由的配置

src/router/index.js文件,是路由的配置文件。

  • 基础配置

import HomeView from '../views/HomeView.vue'
import RegisterVuew from '../views/RegisterVuew.vue'
import LoginVuew from '../views/LoginVuew.vue'


// 用于配置项目中所有需要的页面(组件和路径)
const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/register',
    name: 'register',
    component: RegisterVuew
  },
  {
    path: '/login',
    name: 'register',
    component: LoginVuew
  },

说明:每个路由对象,都对应着项目中的一个页面。其中每个路由对象都有两个必选的属性。

  • path:路由路径,实际上就是浏览器中每一个页面的路径。(建议首字母不要大写)

  • component:路由组件,指的是浏览器中需要渲染的组件。

  • name(可选):路由名称

  • 路由出口
    通过路由配置,当浏览器的路径发生改变时,浏览器会加载对应的组件。但是,路由配置并没有告诉浏览器组件要渲染在什么地方。因此,我们需要通过路由出口,告诉浏览器组件渲染在什么位置。

<template>
    <router-view></router-view>
</template>

有了路由的基本配置和路由出口后,就可以在浏览器中手动切换路径,来实现页面组件的切换。

嵌套路由

  • 基础配置
import CompanyNews from '../views/news/CompanyNewsView.vue'
import MediaNews from '../views/news/MediaNewsView.vue'

const routes = [
    {
        path: '/',
        name: 'home',
        component: HomeView,
        children: [
            {
                // 子路由的path不能以 / 开头
                path: "companynews",
                name: "companynews",
                component: CompanyNews
            },
            {
                path: "medianews",
                name: "medianews",
                component: MediaNews
            },

        ]
    },
]

以上两个路由配置成功后,可以在浏览器中通过/home/companynews 和/home/medianews来访问对应的子路由

  • 路由出口

嵌套子路由对应的组件,也需要在父组件中设置一个路由出口

<router-view></router-view>
  • 默认子路由
    通常我们在配置嵌套路由时,都会再单独设置一个path路由路劲,这样我们访问子路由时,就可以通过 /父级路由/子级路由 来渲染对应的组件。
    但是,如果我们希望当用户访问 /父级路由 路径时,依然可以在子组件的位置中渲染一个默认的组件,这种情况下,就可以配置一个默认子路由。
const routes = [
    {
        path: '/',
        component: HomeView,
        children: [
            {
                path:""// path为空字符串
                name: "home" //父级路由的name属性,设置在默认子路由身上
                component: ChartsView,
            }
            {
                path: "companynews",
                name: "companynews",
                component: CompanyNews
            },
            ...其他子路由

访问 / 路劲时 ,在页面中会先渲染homeView父组件,然后在父组件内部渲染子组件Charts。

路由的跳转

Vue Router中提供了两种方式来实现路由的跳转:
1.组件跳转(标签)
2.API跳转(方法跳转)

组件的跳转

Vue Router中提供了一个 组件来实现路由的跳转.(二级路也需要完整路由)

<router-link to="/register">注册</router-link>
API跳转
<el-button @click="register">登录</el-button>

export default {
    methods:{
        register(){
            // 注册成功后跳转到登录页面
            this.$router.push('/login')
        }
    }
}

push()跳转完成后,用户可以通过浏览器的回退按钮,返回上一页。
如果我们希望用户跳转之后,不能再返回上一页,可以通过replace实现跳转。(删除上一个页面的访问记录)

export default{
    methods:{
        logout(){
            this.$router.replace('/login')
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值