vue3一天内快速学习
文章目录
简介
最流行的前端框架之一,本篇博文期望快速阅览 vue3 的知识点,1 天内看完,剩下就是熟练加综合应用了
npm 是包管理工具,相当于可以用它从中央仓库中拿到依赖包
node.js 实际上就是 js 的运行环境
vue3 学习
安装
mac 中先通过 brew 安装 node,这样 npm 也会自动帮你安装好
下载常用的 ide 软件 webstorm
使用 npm 安装 vue/cli,注意镜像源可以改成国内
npm install -g @vue/cli
安装好之后,在 webstorm 创建 vue 项目,然后我们运行一下
npm run server
vue3 项目起来了,点击链接即可看到 vue 网页
http://localhost:5173/
项目结构
- project_name
- node_modules 依赖
- public
- src 主要编码处
- assets 存放静态资源,比如 css 文件,图片等
- components vue 的组件
- App.vue 主入口的组件,根组件,所有组件都是从这里开始
- main.js js 主入口
- index.html 首页
基础知识
学习的 vue3 之前您需要先要了解 html+css+javascript 的基础知识才能进行如下学习
应用实例必须挂载到 dom 元素或者 css 选择器之后才能渲染出来
<div id="app"></div>
app.mount('#app')
vue 开发时候,一个页面一般会有多个应用(app1,app2),将他们分别挂在到所需元素上
const app1 = createApp({
/* ... */
})
app1.mount('#container-1')
const app2 = createApp({
/* ... */
})
app2.mount('#container-2')
模版语法
{{}}
双大括号传文本值
<span>Message: {{ msg }}</span>
data() {
return { // 返回一个对象
msg: "文本"
}
}
模版中支持表达式,比如 + 呀,三元运算啊,甚至函数语法,但不支持语句,比如 var 声明一个变量,这是一个语句就不行
// 支持
{{ message.split('').reverse().join('') }}
v-html
使用 v-html 做属性传 html 内容,这样前端展现能看到 div 中有一个 html 了
<div v-html="rawHtml"></div>
data() {
return {
rawHtml: "<a href='www.baidu.com'>百度</a>"
}
}
v-bind
使用 v-bind 传递属性,如下其 id 就等于 1000,v-bind 可以简写成 : 即可
<div v-bind:id="dynamicId"></div>
data() {
return {
dynamicId: 1000
}
}
渲染展示
v-if 和 v-else
条件渲染一块内容,如下为 ture 就渲染
<p v-if="flag">展示</p>
data() {
return {
flag: true
}
}
v-else 可以配合 v-if 一起使用
<p v-if="flag">展示</p>
<p v-else>不展示</p>
v-show
v-show 和 v-if 一样效果,那区别呢
v-if 你在打开网页检查能观察到那个 html 语句被删除了就没有被渲染,但是 v-show 发现那个不展现出来的语句还是被渲染了存在这样的 html 语句只不过 display 属性是 none,也就是说 v-if 开销更大
v-for 和 item in xxx
列表渲染,下面 item 你可以随便起名字,表示 newsList 中一个对象
<ul>
<li v-for="item in newsList">
{{ item.title }}
</li>
</ul>
data() {
return {
newsList: [
{
id: "1001",
title: "新闻1"
},
{
id: "1002",
title: "新闻2"
}
]
}
}
然后有一个点,如果 js 这里多写了一个对象 id: 1003,vue 很好他不会把所有的 1001-1003 全部渲染,只会渲染新的 1003,但是要依赖于你家一个属性 key,vue 通过 key 能知道新加了什么对象
<ul>
<li v-for="item in newsList" :key="item.id">
{{ item.title }}
</li>
</ul>
如果没有 id 怎么办,数组下标也是唯一的,下面这种方式也可以
<ul>
<li v-for="(item,index) in newsList" :key="index">
{{ item.title }}
</li>
</ul>
事件处理
如何监听事件 v-on: 或者 @
简单例子
如下不断点击,就回不断加一显示
<button @click="count+=1"></button>
data() {
return {
count: 1
}
}
触发函数
其实更常见是是 click 触发一个函数,而不是一个简单的表达式
<button @click="foo"></button>
data() {
return {
// 返回值
}
}
methods: {
foo() {
// 函数操作
// 需要读取 data 中是属性,请求用 this.xxx
}
/*
foo(event) { // 这样也可以,可以使用 dom 中 event. 来设置一些东西
// 函数操作
// 需要读取 data 中是属性,请求用 this.xxx
}
*/
}
函数带参数
传参数
<button @click="foo('aaa')"></button>
methods: {
foo(data) { // 使用 data 接收
// 函数操作
// 需要读取 data 中是属性,请求用 this.xxx
}
}
表单数据绑定 v-model
简单例子
如下,就是 v-model 绑定了 data 中返回的 username,然后随着 input 的输入,然后 p 标签中就回出现文本
<input type="text" v-model="username"></input>
<p>{{ username }}</p>
data() {
return {
username: ""
}
}
修饰符
下面 input,textarea,select 效果类似
.lazy
回车或者失去焦点时候触发,如下表示输入 msg 之后,当回车时候 p 中才会显示
<input v-model.lazy="msg"></input>
<p>{{ msg }}</p>
.trim
自动过滤用户输入的文本的首尾空白字符
vue 的组件
单模版文件 SFC
.vue 结尾的 SFC 文件就是组件,后缀名以 .vue 结束
单文件组件包含 3 部分
<template>
</template>
<script>
</script>
<style>
</style>
实际中使用时候,往往App.vue 中会集成很多单文件组件,比如说在 App.vue 中有如下, script 中是不是很想 main 中集成了很多函数方法,通过 import 把这些函数引过来,然后在 components 中进行注册使用,最后在 template 中就可以展现出这个组件。可以把每个组件当成页面上某一个模块,这个模块就像一个函数方法,大家都被放在 App.vue 中使用集成
<template>
<MyComponent />
</template>
<script>
import MyComponent from "./components/MyComponent.vue"
export default {
name: 'App',
components: {
MyComponent
}
}
</script>
<style scoped> // scoped 表示当前样式只在当前组件中生效
</style>
组件之间数据交互
prop 父组件到子组件传递
可以用于父组件到子组件的传递参数,具体看如下示例就明白了
子组件
<template>
{{ key }}
</template>
<script>
export defualt {
name: 'MyComponent',
props: {
key: {
type: String,
default: '' // 默认值
}
}
}
</script>
根组件
<template>
<MyComponent :key="title" /> // 传递数据
</template>
<script>
import MyComponent from './components/MyComponent.vue'
export default {
name: 'App',
data() {
return {
title: "标题"
}
},
components: {
MyComponent
}
}
</script>
但是需要注意的是数组的默认值 default 必须用函数承接,这么写
default: funtion() {
return []
}
$emit 反向传递:自定义事件
其实就是子组件 script 脚本中如果通过 $emit 给某个 key 赋值 value,然后在父组件中就能自定一个事件,这个事件就是@key
,然后函数名中的(data)
就是反向传过来的 value 了
看栗子,子组件
<template>
</template>
<script>
export default {
name: "MyComponent",
methods: {
foo() {
this.$emit("onEvent", "反向传递的数据")
}
}
}
</script>
父组件
<template>
<button @onEvent="bar">按钮</button>
</template>
<script>
import MyComponent from "./"
export default: {
name: "App",
components: {
MyComponent
},
methods: {
bar(data) { // 这里 value 就传递过来了
console.log(data)
}
}
}
</script>
组件生命周期
vue 共有 8 个生命周期
- 创建时:beforeCreate,created
- 渲染时:beforeMount,mounted
- 更新时:beforeUpdate,updated
- 卸载时:beforeUnmount,unmounted
比如我们在刷新页面时候,其实执行的是’创建时’和’渲染时’,当触发某个事件更新了某个布局,其实就是’更新时’被运行了
常见的可以把网络请求放在 mounted 渲染装框完成之后;把一些消耗资源的比如定时器逻辑的销毁放在 beforeUnmount 准备卸载之后
vue 引入第三方
vue 中有很多第三方,在实际工作项目中你可以直接拿来使用,比如轮播图效果人家写好的,你直接拿过来引用即可,而不是你造一个轮子
第三方组件在哪找呢:
- vue 官方网站里头,可以找到 vue 推荐的一些第三方组件生态
- 直接谷歌搜索 vue 某个一个效果的组件
- github 去搜 vue 的组件
- 靠经验知道经常用哪些 vue 组件
推荐一些好用的:
- swiper:(swiper.com.cn)
开源免费,触摸滑动的轮播图组件,纯 js 打造,面向平台,手机,电脑
网络请求
_Axios 网络请求
安装介绍
Axios 其实也是第三方的一个网络请求库,基于 promise 网络请求库
安装
npm install --save axios
get post 使用
一种是组件中引用另一种是全局引用,一般开发中基本都是全局去引用了,因为存在网络请求的组件可是很多的
get:
<script>
import axios from "axios"
export default {
name: "MyComponent",
mounted() { // 生命周期函数,组件已经渲染了
axios({
method: "get",
url: ""
}).then(res => { // 响应数据
console.log(res.data)
})
}
}
</script>
更简单的写法:
axios.get("url").then(res => {
console.log(res.data)
})
post:先要 npm 安装一下 querystring,他是为了把 data 请求对象转成 string,这样才能进行网络请求
<script>
import axios from "axios"
import querystring from "querystring"
export default {
name: "MyComponent",
mounted() { // 生命周期函数,组件已经渲染了
axios({
method: "post",
url: "",
data: querystring.stringify({
username: "",
password: "",
verification_code: ""
})
}).then(res => { // 响应数据
console.log(res.data)
})
}
}
</script>
也有更简单的写法:
axios.post("url", querystring.stringify({
username: "",
password: "",
verification_code: ""
}))
局部和全局使用
上面例子是局部使用
如果需要全局使用,就需要在根组件中 import axios,然后挂载全局
import axios from axios
const app = createApp(App)
app.config.globalProperties.$axios = axios
app.mount('#app')
然后在子组件中就可以通过 this.$axios
拿到
网络请求的封装
可以在 src 下创建一个 util 文件,其中创建一个 request.js
import axios from "axios"
import querystring from "querystring"
// 网络请求公共配置
const instance = axios.create({
timeout: 5000
})
// 发送数据之前拦截器,做一些发送之前的数据处理
instance.interceptors.request.use(
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
}
)
然后在 src 下粗行间 api 文件夹,存放 api 的 js
- src
- api
- base.js
- index.js
- components
- MyComponent.vue
base.js 中有:
const base = {
host: "http://xxxx.com",
router: "/xxxxxx/yyyyyyy"
}
export default base;
index.js 中有
import axios from "../utils/request"
import axios from "../base"
const api = {
getApi1() {
return axios.get(path.host + path.router)
}
}
在 MyComponent.vue 组件中可以 mounted() 函数中绑定这个请求
import api from "../api/index"
export default {
name: "",
props: {
},
mounted() {
api.getApi1().then(
res => {
console.log(res.data)
}
)
}
}
跨域解决方法
简介:
https://zhuanlan.zhihu.com/p/575259175
一般来说,跨域问题是在后端处理。因为浏览器对于同源策略的限制,前端无法直接访问不同域名下的资源。后端可以通过设置响应头,允许指定的域名访问资源,从而解决跨域问题。同时,后端也可以通过代理等方式,在服务端进行跨域请求
跨域问题的异常:
解决方式一般 2 中
- 后台解决 cors
- 前台解决 proxy
这里主要讲解前端解决
下面代码添加到 vue.config.js,添加之后一定要重启前端项目才能生效
devServer: {
proxy: {
'/api': {
target: '产生跨域的地址',
changeOrigin: true
}
}
}
路由配置
vue-router 项目中配置路由
vue router 是 vue.js 官方路由,通过他可以管理页面之间关系
- src
- router
- index.js
- views
- components
- main.js
- App.vue
index.js 为路由的配置文件
import { CreateRouter, createWebHashHistroy } from "vue-router"
// 下面两个 import 是页面
import HomeView from ".../views/HomeView"
import AboutView from ".../views/AboutView"
// 创建路由
const routes = [
{
path: "/",
component: HomeView
},
{
path: "/about",
component: AboutView
}
]
const router = createRouter({
history: createHashHistory(),
routes
})
export default router
然后这个 src/router/index.js 在 main.js 中被引入,使用路由
import { createApp } from "vue"
import App from "App.vue"
import router from "router/index.js"
createApp(App).use(router).mount("#app")
然后我们实际在根组件 App.vue 中使用路由
<template>
<router-link to="/">首页</router-link>
<router-link to="/about">关于</router-link>
<router-view></router-view>
</template>
本质:src/router 下的路由 js 文件被 main.js 所引入注册绑定根组件之后,再在根组件中就可以使用了
路由传递参数
router/index.js 中的路由
const routes = [
{
path: "/",
component: HomeView
},
{
path: "/about/:id", // 通过这种方式引入参数传递
component: AboutView
}
]
在 view 中的文件中可以
<p><router-link to="/about/123"></router-link></p>
在 router/AboutView 这个页面中可以通过如下方式取得 123 参数
{{ $route.params.id }}
嵌套路由配置
场景比如主导航下又有很多子导航
文件结构:
- src
- router
- index.js
- views
- HomeViewSub
- AboutMe.vue
- AboutMe2.vue
- HomeView.vue
- AboutView.vue
- components
router/index.js 中的路由。在 index.js 中可以看到一颗路有树
const routes = [
{
path: "/about",
name: "about",
component: () => import('../views/AboutView.vue'), // 延迟加载引入
redirect: "/about/me", // 在 about 这个父级页面会重定向到它的第一个子页面
children: [ // 二级导航路径不要加斜杠
{
path: "me",
component: () => import("../views/HomeViewSub/AboutMe.vue")
},
{
path: "me2",
component: () => import("../views/HomeViewSub/AboutMe2.vue")
}
]
}
]
vuex 状态管理
vuex 就是更方便管理组件间数据交互,提供一种集中式管理
vuex 基本使用
安装
npm install --save vuex
目录
- src
- store
- index.js
store/index.js
import { createStore } from "vuex"
// 帮忙管理组件和组件之间交互的数据
const store = createStore({
// 所有数据放在这里
state: {
counter: 0 // 这个值可以被多个组件读取
}
})
export default store
然后需要在 main.js 引入
import store from "./store"
createApp(App).use(store).mount("#app")
读取 counter 方式
{{ $store.state.counter }}
getters 过滤数据
getter 对管理起来的数据进行过滤,这是在 store/index.js 中完成
import { createStore } from "vuex"
export default createStore({
state: {
counter: 0
},
// 过滤,设置过滤条件
getters: {
getCounter(state) {
return state.counter > 0 ? state.counter : "数据异常"
}
}
})
读取方式
{{ $store.getters.getCounter }}
mutations 改变数据
export default createStore({
state: {
counter: 0
},
// 过滤,设置过滤条件
getters: {
getCounter(state) {
return state.counter > 0 ? state.counter : "数据异常"
}
}
//
mutations: {
addCounter(state) { // 此函数需要被调用
state.counter++
}
}
})
调用方式:
this.$store.commit("addCounter")
另一种优雅调用方式
methods: {
...mapMutations(["addCounter"]),
addClickHandle() {
this.addCounter() // 这种写法更简单
}
}
action 异步操作
store/index.js 中如下:
import { createStore } from "vuex"
import axios from "axios"
export default createStore({
state: {
},
getters: {
},
mutations: {
addCounter(state) {
}
},
actions: {
// 一个操作
asyncAddCounter({ commit }) {
axios.get("http://xxx.com").then(res => {
commit("addCounter", res.data) // 这里相当于把响应结果数据传给 mutations
})
}
}
})
如果要取数的话:
this.$store.dispatch("asyncAddCounter")
更方便写法
methods: {
...mapActions(["asyncAddCounter"]),
foo() {
this.asyncAddCounter()
}
}
vue3 新特性
组合 API
ref 和 reactive 使用
组件中:
<template>
<p>{{ msg }}</p>
<ul>
<li v-for="(item,index) in names.list" :key="index"></li>
</ul>
</template>
export default {
name: "HelloWorld",
// 组合式 api
setup() {
const msg = ref("消息") // 代替了 data
const names = reactive({
list: ["aa", "bb"]
})
return {
msg
}
}
}
methods 函数
然后以前放在 methods 中的响应函数可以直接放在 setup 里头了
props 怎么用
export default {
name: "HelloWorld",
props: {
msg: String
}
setup(props) {
console.log(props.msg)
return .............
}
}
setup 中无 this 关键字
setup 中的生命周期函数
import { onMounted } from "vue"
export default {
name: "",
setup() {
// 以前生命周期函数同一种只能存在一个,现在可以存在多个
onMounted(() => {
})
}
}
更好 TS 支持
仍然建议 js,js 还是比 ts 多很多在开发时候
结合 Element Plus
vue2 对应 Element UI
vue3 对应 Element plus
安装
npm install --save element-plus
基本使用
完整引用(可能会导致文件变得很大)
import { createApp } from "vue"
import ElementPlus from "element-plus"
import "element-plus/dist/index.css"
import App from "App.vue"
const app = createApp(App)
app.use(ElementPlus).mount("#app")
按需引入,更常用的方式
但是你需要先进行插件安装
npm install -D unplugin-vue-components unplugin-auto-import
再修改 vue.config.js 配置文件(这个文件在 vue 项目中可以找到),具体修改方式可见网络
最后直接是用就行了
然后 element-plus 中的各种样式直接复制粘贴就可以直接使用了
图标使用
element-plus 图标是用需要额外说明,因为要显示它,除了你复制粘贴了,之前你还要 npm install 一下
npm install --save @element-plus/icons-vue
然后你需要在 src 下创建一个文件夹,比如叫 plugins,然后其中添加一个 icons.js 文件,这个文件里头怎么写可以网络下,写法比较固定
然后 main.js 中绑定
import elementIcon from "plugins/icons"
app.use(elementIcon)
相关文章
- EasyCVR对接华为iVS订阅摄像机和用户变更请求接口介绍
- 精选 | 腾讯云CDN内容加速场景有哪些?
- 模块化网络防止基于模型的多任务强化学习中的灾难性干扰
- 用搜索和注意力学习稳健的调度方法
- 用于多变量时间序列异常检测的学习图神经网络
- 助力政企自动化自然生长,华为WeAutomate RPA是怎么做到的?
- 使用腾讯轻量云搭建Fiora聊天室
- TSRC安全测试规范
- 云计算“功守道”
- 助力成本优化,腾讯全场景在离线混部系统Caelus正式开源
- Flink 利器:开源平台 StreamX 简介
- 腾讯云实践 | 一图揭秘腾讯碳中和?解决方案
- 深度学习中的轻量级网络架构总结与代码实现
- 信息系统项目管理师(高项复习笔记三)
- Adobe国际认证让科技赋能时尚
- c++该怎么学习(面试吃土记)
- 面试官问发布订阅模式是在问什么?
- 面试官:请实现一个通用函数把 callback 转成 promise
- 空中悬停、翻滚转身、成功着陆,我用强化学习「回收」了SpaceX的火箭
- 中山大学林倞解读视觉语义理解新趋势:从表达学习到知识及因果融合