vue3详细学习笔记记录

VUE3学习笔记

1.工具准备

HBuilderX 3.2.8

2.项目目录

src中有四个目录文件:
1.第一个assets,存放的是项目的静态资源,例如图片
2.componets,存放的是相关的显示组件
3.App.vue,应用开发的主app页面
4.main.js,app的配置页面
一个VUE界面主要包含三个部分:template,script,style。其中,template用来写代码,script用来写脚本,style用来写CSS样式

3.模版语法

template:

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

script:

export default {
 data(){
  return{
   msg:"消息内容传送"
  }
 }
}

将字符串放进data函数的return中进行返回标记使用。

原始Html支持:

template:

<span v-html="rawHtml">百战</span>

script:

export default {
 data(){
  return{
   rawHtml:"<a href=' '>百战</a >"
  }
 }
}

4.条件渲染

template:

<span v-if="flag">1</span>
<span v-else>2</span>

script:

export default {
 data(){
  return{
   flag:true
  }
 }
}

通过flag的判断控制字符的显示,除此之外,还可以使用v-if,v-else if,v-else结合div嵌套多个span等块选择性显示你想显示的内容
template:

<span v-show="flag">1</span>

script:

export default {
 data(){
  return{
   flag:true
  }
 }
}

v-show只有两种状态,要么显示,要么不显示。

5.条件渲染

template:

<ul>
    <il v-for="item in items">{{item.msg}}</il>
</ul>

script:

export default {
 data(){
  return{
   items:[{msg:"01"},{msg:"02"}]
  }
 }
}

数据中存在列表,使用v-for语法进行循环,每一组的属性attr,使用单项.attr进行显示。

维护显示

template:

<ul>
    <il v-for="(item,index) in items" :key="item.id|index">{{item.msg}}</il>
</ul>

script:

export default {
 data(){
  return{
   items:[{msg:"01"},{msg:"02"}]
  }
 }
}

通常每个数据传过来是有ID的,使用ID处理即可,减少渲染时间。
这里面涉及到了属性绑定,:key
属性绑定,意思就是将标签的属性进行绑定,原名称为v-bind:,为了简化,可以写成一个冒号:,主要是将脚本的数据与标签中数据进行绑定显示。

6.事件处理

template:

<button @click="greet">Greet</button>

script:

export default {
 methods:{
    greet(event){
        if(event){
            alert(event.target.tagNane)
        }
    }
 }
}

事件传递参数
template:

<button @click="sya{'so'}">{{msg}}</button>

script:

export default {
   data(){
      return{
          msg=""
      }
   },
 methods:{
    say(msg){
        this.msg = msg
    }
 }
}

7.表单输入绑定

可以在inputtextarea,select等进行双向数据绑定
template:

<input type="text" v-model="msg"/>
<p>msg is {{msg}}</p >

script:

export default {
   data(){
      return{
          msg=""
      }
   }
}

这种是实时进行跟踪的

.lazy属性

改变在
template:

<input type="text" v-model.lazy="msg"/>
<p>msg is {{msg}}</p >

.trim属性

改变在
template:

<input type="text" v-model.trim="msg"/>
<p>msg is {{msg}}</p >

8.组件基础

1.单文件组件(以建立myComponents.vue文件为例),并建立在项目名/src/components目录下
文件初始内容为下

<template>

</template>
<script>
export default {
    name:myComponents,
}
</script>
<style scoped>

</style>

scoped属性的加入是为了style只在本页面生效,如果不加,其它页面也会受到影响。

2.引入
在根组件App.vue中引入组件,在App.vue的script中

<script>
import myComponents from "./components/myComponents.vue"
export default {
}
</script>

3.挂载组件
在App.vue的script中

<script>
import myComponents from "./components/myComponents.vue"
export default {
    name:'App',
    components:{
        myComponents
    }
}
</script>

4.引用组件
在App.vue的template中

<template>
    <myComponents />
</template>

当然,可以组件套组件,形成组件的组织。

9.Props组件交互

App.vue

<template>
    <myComponents :title="title" :age="age" :names="names"/>
</template>

<script>
import myComponents from "./components/myComponents.vue"
export default {
    name:'App',
    data(){
        return{
            title:"Test",
            age:20,
            names:["ime","frank","smith"]
        }
    },
    components:{
        myComponents
    }
}
</script>
<style scoped>

</style>

myComponents.vue

<template>
    <span>{{title}}</span>
    <span>{{age}}</span>
    <ul>
        <il v-for="(items,index) in names" :key="index">{{item}}</il>
    </ul>
</template>
<script>
export default {
    name:myComponents,
    Props:{
        title:{
            type:String,
            default:""
        },
        age:{
            type:Number,
            default:""
        },
        names:{
            type:Array,
            default:function(){
                return []
            }
        }
    }
}
</script>
<style scoped>

</style>

Props接收的数据类型:
String,Number,Boolean,Array,Object,Function
其中,在传递数组或者对象时,需要返回工厂模式(函数形式)。
简单梳理一下props的用法:首先,他是从父组件向子组件进行数据传递,在引入组件的基础上,将所要传递的数据放进template的组件标签中,在组件标签中,在script中加入props,在其中添加要接受的数据名称,接收数据的类型以及默认接收值即可,之后便可以在子组件页面引用传递的值了。

10.自定义事件组件交互

myComponents.vue

<template>
    <button @click="sendClickHandle">点击发送</button>


</template>
<script>
export default {
    name:myComponents,
    data(){
        return{
            message:"Test"
        }
    },
    methods:{
        sendClickHandle(){
            this.$emit("onEvent",this.message)
        }
    }
}
</script>
<style scoped>

</style>

App.vue

<template>
    <myComponents @onEvent="getDataHandle"/>
    <span>{{msg}}</span>
</template>

<script>
import myComponents from "./components/myComponents.vue"
export default {
    name:'App',
    components:{
        myComponents
    },
    data(){
        return {
            msg:""
        }
    }
    methods:{
        getDataHandle(data){
            this.msg=data
        }
    }
}
</script>
<style scoped>

</style>

简述:在子组件中,使用函数出发$emit(eventName,data)去传递数据,在父组件的子组件标签中,使用所使用的方法获取子组件的事件名eventName,并传递给父组件一个方法名parentEventName,在父组件的脚本中,使用方法去获取到这个数据,就可以使用了。

通过上述两个案例,我发现,子组件标签在父组件的使用中,既可以给子组件传递多个数据,也可以给父组件使用自定义事件反向传递数据,十分方便。

11.组件生命周期

export default {
    
    data(){
        return {
            msg:""
        }
    }
    beforeCreate(){
    },
    created(){
    },
    beforeMount(){
    },
    mounted(){
        用到最多的地方,比如网络请求加载
    },
    beforeUpdate(){
    },
    Updated(){
    },
    beforeUnmount(){
        资源卸载
    },
    unmounted(){
    },
}

一共8个生命,分为四类,即创建,渲染,更新,卸载。

12.引入第三方组件

引入第三方组件,过程与第8节组件基础的组件引入是一样的,这里不在进行详细说明,组件的使用语法详见官方文档。

13.axios网络请求

1.安装
打开项目终端机输入:
npm install --save axios
2.引入
组件引入:

全剧引入:
main.js文件:

import axios from "axios"
const app = createApp(App);
app.config.globalProperties.$axios = axios
app.mount('#app');

在组建中调用: t h i s . this. this.axios

网络请求基本示例:

'get'
axios({
    method:"get",
    url:"http://......."
}).then(res=>{
//进行数据处理
    res.data
})

简洁方式:

'get'
axios.get("http://......."
).then(res=>{
//进行数据处理
    res.data
})
'post'
axios({
    method:"get",
    url:"http://......."
    data:{querystring.stringify({
        user_id:"",
        password:"",
        verification_code:""
    }
}).then(res=>{
//进行数据处理
    res.data
})

简洁方式:

'post'
axios.post(
    url:"http://.......",querystring.stringify({
        user_id:"",
        password:"",
        verification_code:""
})).then(res=>{
//进行数据处理
    res.data
})

14.axios网络请求封装

在src目录下创建utils目录,并在其下建立一个request,js的文件,内容如下:

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

//使用const 声明一个自己定义的变量

const instance = axios.create({
//网络请求的公共配置
    timeout:5000
})
//发送数据之前
instance.interceptors.request.use(
    config=>{
        if(config.method === "post"){
        config.data = querystring.stringify(config.data)
        }
        return config;
    },
    error=>{return Promise.reject(error)
})

//错误信息处理
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("");
            break;
    }
}
//获取数据之前
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; 

建立一个api目录,并在其下创建index.js,path.js
配置文件路径path.js:

const base = {
    baseUrl:"域名地址",
    pages:"/api/.....php"
}
export default base;

结合文件路径与封装的请求,在index.js写业务逻辑。

import axios from "../utils/request"
import path from "./path"

const api = {
    getpagges(){
        return axios.get(path.baseUrl+path.pages)
    }
}
export default api;

在组建页面:
script中引用api:
//api.index 自动寻找
import api from "../api"
然后去引用API。

15.请求跨域

当协议,域名,端口任意一个不同时,都会产生跨域问题。
目前,解决跨域问题的有两个:
后台:cors
前台:proxy
在vue.config.js文件中进行配置,如下:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  //以下为添加内容
  devServer:{
  proxy:{
  '/api':{
    target:'<url>',
    changeOrigin:true
  }
  }
  }
  
})

16.路由

简单来说,路由就是可以管理页面之间的关系,我们使用vue-router来使用,可以很简单的实现单页应用。 是一个组件,该组件用于设置一个导航链接,切换不同 HTML 内容。 to 属性为目标地址, 即要显示的内容。
1.安装
npm install --save vue-router
2.配置独立的路由文件,建立router文件夹并在其下建立index.js文件,其中:

import {craeteRouter, createWebHashHistory} from 'vue-router'
impoert 需要引入跳转的页面
//假如存在首页index,page1,page2

//配置信息中需要页面的相关配置
const routers = [
    {
    path:"/",
    name:"index",
    component:index
    },
    {
    path:"/page1",
    nsme:"page1",
    component:page1
    },
    {
    path:"/page2",
    component:page2
    },
] 
const router = createRouter({
    history:createWebHashHistory(),
    routers
})

export default router;

使用:
在main.js中进行配置

import { createApp } from 'vue'
import App from './App.vue'
import router from "./router/router"

createApp(App).use(router).mount('#app')

在App.vue开始应用

<template>

<router-link to="/">首页</router-link>
<router-link to="/page1">页面1</router-link>
<router-link to="/page2">页面2</router-link>
//. 下面代码开启路由路口,主页要写,其它页面不需要写
<router-view> </router-view>
</template>

17.路由传参

通常,在页面加载中,只有主页面被引入,其他页面采用异步加载,节省资源:

const routers = [
    {
    path:"/",
    nsame:"index",
    component:index
    },
    {
    path:"/page1",
    name:"page1",
    component:()=>import("../page1.vue")
    },
    {
    path:"/page2",
    namee:"page2",
    component:)=>import("../page2.vue")

    },
] 

如果有page1和page2需要跳转相同的页面,但是这个页面显示的内容不同,但是都是需要显示内容,则应该传递的参数不同,让它显示对应页面参数的内容。

1.首先,在路由配置中指定参数

    {
    path:"/page1/:name",
    name:"page1",
    component:()=>import("../page1.vue")
    },

路径后冒号加参数

2.跳转过程引入数据

<router-link to="/page1/数据">页面1</router-link>

3.详情页面调取参数(详情显示页)
<span>{{$route.params.name}} </span>

18.路由嵌套

通常在一级菜单下有的还存在二级菜单,那么如何在一级页面创建二级菜单呢,
假设page2页面还有分类,需要跳转页面,这时候新建页面page2_1,page2_2,他们均属于page2的子页面,
在路由中添加修改:

{
    path:"page2",
    namee:"page2",
    component:)=>import("../page2.vue")
    children:[
    {
    //二级导航不要加斜线
    path:"/page2_1",
    name:"page2_1",
    component:()=>import("../page2_1.vue")
    },
    {
    path:"page2_2",
    name:"page2_2",
    component:()=>import("../page2_2.vue")
    }
    ]
}

在page2页面加上子路由跳转开启转接

<template>

<router-link to="/page2/page2_1">页面1</router-link>
<router-link to="/page2/page2_2">页面2</router-link>
//. 下面代码开启路由路口,主页要写,其它页面不需要写
<router-view> </router-view>
</template>

当然页面最开始存在初始页面,如何设定在,路由中添加修改:

{
    path:"page2",
    namee:"page2",
    component:)=>import("../page2.vue"),
    //重定向默认页面
    redirect:"/page2/page2_1",
    children:[
    {
    //二级导航不要加斜线
    path:"/page2_1",
    name:"page2_1",
    component:()=>import("../page2_1.vue")
    },
    {
    path:"page2_2",
    name:"page2_2",
    component:()=>import("../page2_2.vue")
    }
    ]
}

19.axios网络请求

1.安装
打开项目终端机输入:
npm install --save axios
2.引入
组件引入:

全剧引入:
main.js文件:

import axios from "axios"
const app = createApp(App);
app.config.globalProperties.$axios = axios
app.mount('#app');

在组建中调用: t h i s . this. this.axios

网络请求基本示例:

'get'
axios({
    method:"get",
    url:"http://......."
}).then(res=>{
//进行数据处理
    res.data
})

简洁方式:

'get'
axios.get("http://......."
).then(res=>{
//进行数据处理
    res.data
})
'post'
axios({
    method:"get",
    url:"http://......."
    data:{querystring.stringify({
        user_id:"",
        password:"",
        verification_code:""
    }
}).then(res=>{
//进行数据处理
    res.data
})

简洁方式:

'post'
axios.post(
    url:"http://.......",querystring.stringify({
        user_id:"",
        password:"",
        verification_code:""
})).then(res=>{
//进行数据处理
    res.data
})

20.axios网络请求封装

在src目录下创建utils目录,并在其下建立一个request,js的文件,内容如下:

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

//使用const 声明一个自己定义的变量

const instance = axios.create({
//网络请求的公共配置
    timeout:5000
})
//发送数据之前
instance.interceptors.request.use(
    config=>{
        if(config.method === "post"){
        config.data = querystring.stringify(config.data)
        }
        return config;
    },
    error=>{return Promise.reject(error)
})

//错误信息处理
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("");
            break;
    }
}
//获取数据之前
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; 

建立一个api目录,并在其下创建index.js,path.js
配置文件路径path.js:

const base = {
    baseUrl:"域名地址",
    pages:"/api/.....php"
}
export default base;

结合文件路径与封装的请求,在index.js写业务逻辑。

import axios from "../utils/request"
import path from "./path"

const api = {
    getpagges(){
        return axios.get(path.baseUrl+path.pages)
    }
}
export default api;

在组建页面:
script中引用api:
//api.index 自动寻找
import api from "../api"
然后去引用API。

21.请求跨域

当协议,域名,端口任意一个不同时,都会产生跨域问题。
目前,解决跨域问题的有两个:
后台:cors
前台:proxy
在vue.config.js文件中进行配置,如下:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  //以下为添加内容
  devServer:{
  proxy:{
  '/api':{
    target:'<url>',
    changeOrigin:true
  }
  }
  }
  
})

22.路由

简单来说,路由就是可以管理页面之间的关系,我们使用vue-router来使用,可以很简单的实现单页应用。 是一个组件,该组件用于设置一个导航链接,切换不同 HTML 内容。 to 属性为目标地址, 即要显示的内容。
1.安装
npm install --save vue-router
2.配置独立的路由文件,建立router文件夹并在其下建立index.js文件,其中:

import {craeteRouter, createWebHashHistory} from 'vue-router'
impoert 需要引入跳转的页面
//假如存在首页index,page1,page2

//配置信息中需要页面的相关配置
const routers = [
    {
    path:"/",
    name:"index",
    component:index
    },
    {
    path:"/page1",
    nsme:"page1",
    component:page1
    },
    {
    path:"/page2",
    component:page2
    },
] 
const router = createRouter({
    history:createWebHashHistory(),
    routers
})

export default router;

使用:
在main.js中进行配置

import { createApp } from 'vue'
import App from './App.vue'
import router from "./router/router"

createApp(App).use(router).mount('#app')

在App.vue开始应用

<template>

<router-link to="/">首页</router-link>
<router-link to="/page1">页面1</router-link>
<router-link to="/page2">页面2</router-link>
//. 下面代码开启路由路口,主页要写,其它页面不需要写
<router-view> </router-view>
</template>

23.路由传参

通常,在页面加载中,只有主页面被引入,其他页面采用异步加载,节省资源:

const routers = [
    {
    path:"/",
    nsame:"index",
    component:index
    },
    {
    path:"/page1",
    name:"page1",
    component:()=>import("../page1.vue")
    },
    {
    path:"/page2",
    namee:"page2",
    component:)=>import("../page2.vue")

    },
] 

如果有page1和page2需要跳转相同的页面,但是这个页面显示的内容不同,但是都是需要显示内容,则应该传递的参数不同,让它显示对应页面参数的内容。

1.首先,在路由配置中指定参数

    {
    path:"/page1/:name",
    name:"page1",
    component:()=>import("../page1.vue")
    },

路径后冒号加参数

2.跳转过程引入数据

<router-link to="/page1/数据">页面1</router-link>

3.详情页面调取参数(详情显示页)
<span>{{$route.params.name}} </span>

24.路由嵌套

通常在一级菜单下有的还存在二级菜单,那么如何在一级页面创建二级菜单呢,
假设page2页面还有分类,需要跳转页面,这时候新建页面page2_1,page2_2,他们均属于page2的子页面,
在路由中添加修改:

{
    path:"page2",
    namee:"page2",
    component:)=>import("../page2.vue")
    children:[
    {
    //二级导航不要加斜线
    path:"/page2_1",
    name:"page2_1",
    component:()=>import("../page2_1.vue")
    },
    {
    path:"page2_2",
    name:"page2_2",
    component:()=>import("../page2_2.vue")
    }
    ]
}

在page2页面加上子路由跳转开启转接

<template>

<router-link to="/page2/page2_1">页面1</router-link>
<router-link to="/page2/page2_2">页面2</router-link>
//. 下面代码开启路由路口,主页要写,其它页面不需要写
<router-view> </router-view>
</template>

当然页面最开始存在初始页面,如何设定在,路由中添加修改:

{
    path:"page2",
    namee:"page2",
    component:)=>import("../page2.vue"),
    //重定向默认页面
    redirect:"/page2/page2_1",
    children:[
    {
    //二级导航不要加斜线
    path:"/page2_1",
    name:"page2_1",
    component:()=>import("../page2_1.vue")
    },
    {
    path:"page2_2",
    name:"page2_2",
    component:()=>import("../page2_2.vue")
    }
    ]
}

25.setup

setup函数在beforecreated钩子函数前执行,此时setup中的this还不是组件实例,此时this是undefined.
第1个参数为props。props为一个对象,内部包含了父组件传递过来的所有prop数据
第2个参数为一个对象context。context对象包含了attrs,slots, emit属性,
如果在data()中也定义了同名的数据,则以setup()中为准。
attrs: 除了 props 中的其他属性
slots: 父组件传入插槽内容的对象
emit: 和用于父子组件通信

26.ref,reactive

ref

定义/转为 响应式
作用:定义一个响应式的数据
语法: const xxx = ref(initValue)
创建一个包含响应式数据引用对象(reference对象)
JS中操作数据:xxx.value
模板中读取数据:不需要.value,直接:
{ {xxx}}
备注:
接收的数据可以是:基本类型、也可以是对象类型
基本类型的数据:响应式依然靠的是Object.defineProperty()的get和set完成的
对象类型的数据: 内部”求助“了Vue3.0中的一个新的函数——reactive函数

reactive 函数

作用:定义一个对象类型的响应式数据(基本类型别用他,用ref函数)
语法:const 代理对象 = reactive(被代理对象)接收一个对象(或数组),返回一个代理对象(proxy对象)
reactive定义的响应式数据是”深层次的“
内部基于ES6的Proxy实现,通过代理对象操作源对象内部数据进行操作

区别

eactive对比ref
从定义数据角度对比:

ref用来定义: 基本数据类型
reactive用来定义: 对象(或数组)类型数据
备注: ref也可以用来定义对象(或数组)类型数据,它内部会自动通过reactive转为代理对象
从原理角度对比:

ref通过Object.defineProperty()的get和set来实现响应式(数据劫持)
reactive通过Proxy来实现响应式(数据劫持),并通过Reflect操作源对象内部的数据
从使用角度对比:

ref定义数据:操作数据需要 .value ,读取数据时模板中直接读取不需要 .value
reactive 定义的数据: 操作数据和读取数据均不需要 .value

toRef和toRefs

toRef和toRefs整两个方法,它们不创造响应式,而是延续响应式。创造响应式一般由ref和reactive来解决,而toRef和toRefs则把对象的数据进行分解和扩散,其这个对象针对的是响应式对象(reactive)而非普通对象。

27.生命周期

onBeforeMount
onMounted
onBeforeUpdate
onUpdated
onBeforeUnmount
onUnmounted
onActivated
onDeactivated

28.Teleport

Teleport是一种能够将我们组件html结构移动到指定位置的技术(开发的时候非常有用)

29.provide / inject

作用:实现祖孙组件间的通信
套路:父组件有一个provide选项提供数据,子组件有一个inject选项来开始使用这些数据

30.侦听器

watch

语法:watch(监听源|[多个], (val, oldVal) => {}, {immediate?: false, deep: false})
watch写法上支持一个或者多个监听源,这些监听源必须只能是getter/effect函数,ref数据,reactive对象,或者是数组类型

watchEffect

它立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数

watch 和 watchEffect的区别

两者都可以监听 data 属性变化;
watch 需要明确监听哪个属性;
而 watchEffect 会根据其中的属性,自动监听其变化。

31.computed 计算属性

computed函数调用时, 要接收一个处理函数, 处理函数中, 需要返回计算属性的值

32.readonly 和 shallowReadonly

readonly:让一个响应式的数据变成只读的(深只读)
shallowReadonly: 让一个响应式数据变成只读的(浅只读)
应用场景:不希望数据被修改的时候

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值