目录
前言
Vue.js,这个轻量级且灵活的JavaScript框架,就像一位魔术师,用它的魔法棒将数据和视图巧妙地连接在一起。当数据发生变化时,Vue.js就像变魔术一样,让视图自动更新,为开发者带来了极大的便利。
Vue.js的诞生,源于一位名叫尤雨溪的开发者对前端开发的热爱与追求。在Google工作期间,他受到了Angular的启发,决定开发一款更加轻量、灵活的框架。于是,Vue.js应运而生,它的名字来源于“View”的缩写,寓意着它专注于视图层的开发。Vue.js不断地完善和发展。它引入了响应式数据绑定、组件化开发等核心概念,让前端开发变得更加高效和可维护。
👋 Vue环境搭建
首先,搭一个打代码的环境
1.安装node.js
在使用VS Code之前,需要安装Vue的开发环境。
安装Vue的最简单方法是使用npm包管理器,先安装Node.js和npm。
2.配置环境变量
在nodejs安装目录下新建node_cache(nodejs缓存)、node_global(全局包存放)两个文件夹,如下图所示。
打开cmd命令提示符,配置文件路径如下:
配置环境变量
系统属性->高级->环境变量->新增环境变量:
系统变量
3.VSCode配置
以管理员身份运行VSCode
VSCode安装插件ESLint
安装js打包工具
npm install -g webpack
4.安装Vue CLI
npm install -g vue-cli
(vue-cli npm install @vue/cli -g --unsafe-perm)
5.在VS Code中打开Vue项目
5.1. 在VS Code中,File > Open Folder... 选择“文件”> “打开文件夹”。
5.2. 找到Vue项目文件夹,选择“文件夹”并打开。
可以根据需要,在Extensions安装VSCode的中文扩展。
5.3也可以通过Vue UI 创建一个新的Vue项目然后打开
vue ui
6.运行Vue项目
在VS Code中打开 Terminal 终端,切换到Vue项目文件夹,然后运行以下命令:
npm install
install完会node_modules
npm run dev
(npm run serve)
npm run build
生成打包完会有dist文件夹放着打包好的文件
可直接放到服务器上运行
另外,也可通过 HBuilder 来敲代码
内置浏览器
👀 Vue基础学习
1.引入vue.js
<script src="vue.js" type="text/javascript" charset="utf-8"></script>
<div id="app">
{{ message }} {{name}} {{himan}}
</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
name : "Vue",
himan:"hhhhhhh"
}
});
</script>
2.数据方法
<div id="app">
{{a}}
</div>
<script type="text/javascript">
var data = { a : 1 };
var vm = new Vue({
el : "#app",
data : data
});
//data.a = 121212
vm.$watch('a', function(newVal, oldVal){
console.log(newVal, oldVal);
})
vm.$data.a = "123123."
</script>
3.生命周期
每个 Vue 组件实例在创建时都需要经历一系列的初始化步骤,比如设置好数据侦听,编译模板,挂载实例到 DOM,以及在数据改变时更新 DOM。在此过程中,它也会运行被称为生命周期钩子的函数,让开发者有机会在特定阶段运行自己的代码。
befroreCreate 在实例初始化之后
数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
created 在实例创建完成后被立即调用。
在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。
然而,挂载阶段还没开始,$el 属性目前不可见。
beforeMount 在挂载开始之前被调用
相关的渲染函数首次被调用
mounted 在组件被挂载之后调用
beforeUpdate 数据更新时调用
updated //组件 DOM 已经更新, 组件更新完毕
注意:生命周期不能用箭头函数
<div id="app">
{{msg}}
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
msg : "hi vue",
},
beforeCreate:function(){
console.log('beforeCreate');
},
created :function(){
console.log('created');
},
beforeMount : function(){
console.log('beforeMount');
},
mounted : function(){
console.log('mounted');
},
beforeUpdate : function(){
console.log('beforeUpdate');
},
updated : function(){
console.log('updated');
}
});
setTimeout(function(){
vm.msg = "change msg";
console.log("change msg");
}, 10000);
4.模板语法
v-bind v-html
js表达式
<p>{{ number + 1 }}</p>
<p>{{ 1 == 1 ? 'YES' : 'NO' }}</p>
<p>{{ message.split('').reverse().join('') }}</p>
<div id="app">
{{msg}}
<p>Using mustaches: {{ rawHtml }}</p>
<p v-html="rawHtml"></p>
<div v-bind:class="color">test...</div>
<p>{{ number + 1 }}</p>
<p>{{ 1 == 1 ? 'YES' : 'NO' }}</p>
<p>{{ message.split('').reverse().join('') }}</p>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
msg : "hi vue",
rawHtml : '<span style="color:red">this is should be red</span>',
color:'blue',
number : 10,
ok : 1,
message : "vue"
}
});
vm.msg = "hi....";
</script>
<style type="text/css">
.red{color:red;}
.blue{color:blue; font-size:14px;}
</style>
v-if @clikck @click.stop stop修饰 表示只执行click2
<div id="app">
<p v-if="seen">HIHI</p>
<a v-bind:href="url">...</a>
<div @click="click1">
<div @click.stop="click2">
click me
</div>
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
seen : false,
url : "HTTPS://WWW.BAIDU.COM"
},
methods:{
click1 : function () {
console.log('click1......');
},
click2 : function () {
console.log('click2......');
}
}
});
</script>
5.对象语法
class style绑定
<div id="app">
<div
class="test"
v-bind:class="[ isActive ? 'active' : '', isGreen ? 'green' : '']"
style="width:200px; height:200px; text-align:center; line-height:200px;">
hahaha
</div>
<div
:style="{color:color, fontSize:size, background: isBlue ? 'blue' : ''}">
hihihihi
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
isActive : true,
isGreen : true,
color : "#111111",
size : '50px',
isRed : true,
isBlue:true
}
});
</script>
<style>
.test{font-size:30px;}
.green{color:#00FF00;}
.active{background:gray;}
</style>
6.条件渲染
v-if v-show
<div id="app">
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
<h1 v-show="ok">Hello!</h1>
<h1 v-show="nok">Hello!</h1>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
type : "D",
ok : true//ok : false
}
});
</script>
如果需要频繁切换 ,用v-show show有写入dom
7.列表渲染
v-for
<div id="app">
<ul>
<li v-for="item,index in items" :key="index">
{{index + 1 }} {{ item.message }}
</li>
</ul>
<ul>
<li v-for="value, key in object">
{{key}} : {{ value }}
</li>
</ul>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
items : [
{ message: 'zhangsan' },
{ message: 'liwu' }
],
object: {
title: 'tt',
author: 'zhangsan',
createAt: '2024-01-01'
}
}
});
</script>
8.事件
9.表单绑定
<div id="app">
<div id="example-1">
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
<textarea v-model="message2" placeholder="add multiple lines"></textarea>
<p style="white-space: pre-line;">{{ message2 }}</p>
<br />
<div style="margin-top:20px;">
<input type="checkbox" id="z" value="z" v-model="checkedNames">
<label for="z">z</label>
<input type="checkbox" id="x" value="x" v-model="checkedNames">
<label for="x">x</label>
<input type="checkbox" id="a" value="a" v-model="checkedNames">
<label for="a">a</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
</div>
<div style="margin-top:20px;">
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<br>
<span>Picked: {{ picked }}</span>
</div>
<button type="button" @click="submit">提交</button>
</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el : "#app",
data : {
message : "himsg",
message2 :"himsg2",
checkedNames : ['a', 'z'],
picked : "Two"
},
methods: {
submit : function () {
console.log(this.message + " "+this.message2 );
}
}
});
</script>
10.组件基础
<div id="app">
<button-counter title="123"></button-counter>
<button-counter title="title1 " @clicknow="clicknow">
<h3>hi...h3</h3>
</button-counter>
<button-counter title="title2 : "></button-counter>
</div>
<script type="text/javascript">
Vue.component('button-counter', {
props: ['title'],
data: function() {
return {
count: 0
}
},
template: '<div><h1>hi...</h1><button v-on:click="clickfun">{{title}} You clicked me {{ count }} times.</button><slot></slot> </div>',
methods: {
clickfun: function() {
this.count++;
this.$emit('clicknow', this.count);//传出去
}
}
})
var vm = new Vue({
el: "#app",
data: {
},
methods: {
clicknow: function(e) {
console.log(e);
},
}
});
</script>
component('xxx',{}) xxx组件名称 {}对象内容
props:["title"]定义属性
<slot></slot> 插槽 可插入html标签
<script type="text/javascript">
Vue.component('button-counter', {
props: ['title'],
data: function () {
return {}
},
template: '<div><h1>hi...</h1></div>',
methods:{
}
})
var vm = new Vue({
el : "#app",
data : {
},
methods:{
clicknow : function (e) {
console.log(e);
}
},
components:{
test : {
template:"<h2>h2...</h2>"
}
}
});
</script>
Vue.component('button-counter'...是全局注册
components:{... } 局部注册
11.单文件组件
<template>
<div>
<h1>Hello, Vue!</h1>
<HelloWorld />
</div>
</template>
<script>
// 引入 HelloWorld 组件
import HelloWorld from './HelloWorld.vue';
export default {
name: 'App',
components: {
// 注册引入的组件
HelloWorld
}
}
</script>
<style>
/* 样式 */
</style>
🌱Vue组件学习
Vue Router
Vue Router 是 Vue.js 官方的路由管理器。它允许构建单页应用(SPA),在不同的 URL 之间进行导航,同时还可以实现诸如路由参数、嵌套路由、路由导航守卫等功能。
1.安装 Vue Router
npm install vue-router
2.router.js
Vue 项目中,需要创建一个路由实例并将其挂载到 Vue 实例上。通常情况下,名为 router.js
或者类似的文件中定义路由,然后在主 Vue 实例中引入它。
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Login from '../components/Login.vue'
import Setting from '../components/Setting.vue'
import UserManagement from '../components/UserManagement.vue'
import imtest from '../components/WebIMTest.vue'
const routes = [
{ path: '/Login', component: Login }, // _ // 设置空默认路由为Login.vue
{ path: '/Setting', component: Setting },
{ path: '/UserManagement', component: UserManagement },
{ path: '/imtest', component: imtest }
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
createRouter
函数用于创建路由实例,而 createWebHistory
函数则用于创建基于 HTML5 History API 的路由模式,也就是使用浏览器的 History API 来处理 URL 的变化
3.引入路由实例
Vue 实例中,需要引入这个路由实例,并将其应用到 Vue 实例中。
// main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router';
const app = createApp(App)
app.use(router) // 使用路由
app.mount('#app')
4.路由导航
可以使用 <router-link>
来实现路由导航,使用 <router-view>
来渲染当前路由匹配到的组件。
<!-- App.vue -->
<template>
<div id="app">
<router-link to="/login" class="nav-link">Login</router-link>
<router-link to="/setting" class="nav-link">Setting</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
};
</script>
5.运行实例
点击Setting 则来到/setting , <router-view></router-view> 展示的是Setting的内容
Axios
Axios 是一个流行的基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js 环境。它允许你以简单、直观的方式发送异步HTTP请求,并处理响应。Axios 具有许多功能,包括:
支持 Promise API:Axios使用Promise对象进行异步操作的处理,使得代码更加清晰和易于理解。
支持浏览器和Node.js:Axios可以在浏览器和Node.js环境中使用,这使得它成为跨平台开发的理想选择。
拦截请求和响应:你可以在发送请求或接收响应时,使用拦截器对请求或响应进行全局处理。
自动转换JSON数据:Axios会自动将接收到的JSON数据转换为JavaScript对象,方便在代码中进行处理。
取消请求:Axios允许你取消未完成的HTTP请求,防止不必要的网络请求。
客户端端口支持防止CSRF:Axios可以自动识别和处理CSRF保护。
错误处理:Axios提供了丰富的错误处理机制,方便你处理各种网络请求可能出现的错误。
适用于前端和后端开发,使得发送和处理HTTP请求变得更加简单和高效。
1.安装Axios
可以通过npm或者yarn进行安装。
npm install axios
2.引入axios
import axios from 'axios';
3.axios请求方法
<script>
import axios from 'axios';
export default {
methods: {
AxiosTest() {
const url = '/api/getLogByID';
const id = '3';
// 使用Axios发送GET请求
axios.get(url, {
params: {
id: id
}
})
.then(response => {
// 请求成功时的处理逻辑
console.log(response.data); // 输出获取到的日志数据
})
.catch(error => {
// 请求失败时的处理逻辑
console.error('There was an error!', error);
});
}
};
</script>
4.调用方法
在Vue模板中调用方法:通过事件绑定或其他方式来调用上面定义的方法。
<button @click="AxiosTest">获取 </button>
5.运行实例
户点击按钮时,AxiosTest
方法被调用,它会使用Axios发送GET请求来调用GetLogByID
方法,并处理返回的数据或错误。 console.log 输出 返回的数据
Vue-i18n 国际化
在Vue应用中使用Vue I18n时,可以按照以下步骤操作:
1.安装Vue I18n
首先,需要安装Vue I18n。可以通过npm或者yarn来安装Vue I18n
npm install vue-i18n
or
yarn add vue-i18n
2.创建语言文件
接下来,创建语言文件。这些文件可以是JSON格式的,用来存储不同语言的翻译信息。例如en.json、zh.json和fr.json等文件,分别存储英语、中文和法语的信息。
// en.json
{
"Welcome": "Welcome",
"Login": "Login",
"Setting": "Setting",
}
// en.json
{
"Welcome": "Welcome",
"Login": "Login",
"Setting": "Setting",
}
// zh.json
{
"Welcome": "欢迎",
"Login": "登录",
"Setting": "设置",
}
3.在Vue组件中使用Vue I18n
在Vue组件中引入Vue I18n,并创建一个实例。
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import { createI18n } from 'vue-i18n'
import router from './router'
// 引入语言文件
import en from './locales/en.json'
import zh from './locales/zh.json'
import fr from './locales/fr.json'
// 创建 Vue I18n 实例
const i18n = createI18n({
locale: 'en', // 默认语言
messages: {
en,
zh,
fr
}
})
// 创建 Vue 应用实例
const app = createApp(App)
// 使用 Vue I18n 和路由
app.use(i18n)
app.use(router)
// 挂载应用
app.mount('#app')
4.在组件中使用翻译
使用 $t
方法来进行翻译。
<!-- HelloWorld.vue -->
<template>
<div>
<h1>{{ $t('Welcome') }}</h1>
<p>{{ $t('Login') }}</p>
<p>{{ $t('Setting') }}</p>
</div>
</template>
<script>
export default {
}
</script>
5.切换语言: 最后,通过修改Vue I18n实例的locale属性来切换语言。
// 切换到中文
i18n.global.locale = 'zh';
// 切换到法语
i18n.global.locale = 'fr';
在2.创建语言文件时也可以只创建一个json,减少后续维护成本如:
// lan.json
{
"en": {
"Welcome": "Welcome",
"Login": "Login",
"Setting": "Setting",
"UserManagement": "User Management"
},
"zh": {
"Welcome": "欢迎",
"Login": "登录",
"Setting": "设置",
"UserManagement": "用户管理"
},
"fr": {
"Welcome": "Bienvenue",
"Login": "Connexion",
"Setting": "Réglage",
"UserManagement": "Gestion des utilisateurs"
},
"ru": {
"Welcome": "Добро пожаловать",
"Login": "Войти",
"Setting": "Настройки",
"UserManagement": "Управление пользователями"
},
"hk": {
"Welcome": "歡迎",
"Login": "登錄",
"Setting": "設置",
"UserManagement": "用戶管理",
}
}
//main.js
import translations from './lan.json'
// 创建 Vue I18n 实例
const i18n = createI18n({
locale: 'en', // 默认语言
messages: translations
})
5.运行实例
Vue-SignalR 实时通讯
在Vue应用中使用SignalR,可以按照以下步骤进行
1.安装SignalR客户端库
首先,需要安装SignalR的JavaScript客户端库。可以通过npm或者yarn来安装。
npm install @microsoft/signalr
or
yarn add @microsoft/signalr
2.在Vue组件中使用SignalR
在Vue组件中引入SignalR库,并创建一个SignalR连接,然后订阅服务器发送的消息。
<script>
import { HubConnectionBuilder } from '@microsoft/signalr';
export default {
data() {
return {
messageText: '',
hubConnection: null,
messages: []
};
},
methods: {
sendMessage() {
if (!this.messageText) return;
// 发送消息给SignalR Hub
this.hubConnection.invoke('SendMessage2','user1', this.messageText)
.then(() => {
console.log('Message sent: ', this.messageText);
// 清空输入框
this.messageText = '';
})
.catch(error => {
console.error('Error sending message: ', error);
});
}
},
created() {
this.hubConnection = new HubConnectionBuilder()
.withUrl("/chatHub") // SignalR Hub的URL
.build();
this.hubConnection.start()
.then(() => console.log("SignalR connection established."))
.catch(err => console.error("SignalR connection failed: ", err));
this.hubConnection.on("ReceiveMessage", (user, message) => {
this.messages.push({ user, message });
});
}
}
</script>
/chatHub 是服务端通讯地址
SignalR服务端 👉 .NET SignalR Redis
3.在模板中显示消息
最后,在你的Vue模板中显示从SignalR收到的消息。
<template>
<div>
<input type="text" v-model="messageText">
<button @click="sendMessage">Send</button>
<br>
<div v-for="(message, index) in messages" :key="index">
<p>{{ message.user }}: {{ message.message }}</p>
</div>
</div>
</template>
这里创建了一个messageTex 获取用户输入的文本点击按钮Send时,会调用sendMessage 方法来发送消息给SignalR Hub。并将输入框中的消息作为参数传递给它。
4.运行实例
可以看到消息实时传递到另一个客户端
Vuex
Vuex 是 Vue.js 的状态管理库,用于集中管理应用的状态
用于全局状态管理 数据共享
1.安装Vuex
npm install vuex
2.导入依赖
import { createStore } from 'vuex';
这里做个简单的登录Vuex store例子
import { createStore } from 'vuex';
import api from '../services/api';
export default createStore({
state: {
isLoggedIn: false,
user: null
},
mutations: {
login(state, user) {
state.isLoggedIn = true;
state.user = user;
},
logout(state) {
state.isLoggedIn = false;
state.user = null;
}
},
actions: {
async login({ commit }, loginForm) {
try {
const response = await api.post('/api/userApi/GetUserByMobilePwd', loginForm);
// 登录成功,更新用户信息并设置登录状态
commit('login', response.data.rsData); //rsData
return response.data;
} catch (error) {
// 登录失败,抛出错误
throw new Error(error.response.data.message || 'Login failed');
}
},
logout({ commit }) {
// 清除用户信息并设置登录状态为未登录
commit('logout');
}
}
});
state 对象包含应用的全局状态,其中 isLoggedIn 是否已经登录,user 存储用户信息。
mutations
login 方法用于将用户登录状态设置为已登录,并存储用户信息,
logout 方法用于将用户登录状态设置为未登录,并清空用户信息。
actions
login 方法用于发起登录请求,并根据响应结果提交 login mutation 来更新用户登录状态和用户信息,
logout 方法用于处理用户登出逻辑。
getters 包含一些计算属性,用于从 state 中派生出一些衍生状态。
这里的 isLoggedIn getter 返回 state.isLoggedIn,以确保状态的响应性。
3.在Vue组件中使用
//main.js
import store from './services/store.js';
...
app.provide('store', store) // 注入 Vuex store
4.编写组件
login logout
<template>
<div class="login-container">
<div class="login-card">
<h2 class="login-title" style="margin-top: ;">{{ $t('Login') }}</h2>
<form @submit.prevent="login" class="login-form">
<div class="form-group">
<label for="mobile">{{ $t('username') }}</label>
<input type="text" id="mobile" v-model="loginForm.mobile" >
</div>
<div class="form-group">
<label for="pwd">{{ $t('password') }}</label>
<input type="password" id="pwd" v-model="loginForm.pwd" >
</div>
<button v-if="!isLoggedIn" type="submit" class="btn btn-primary">{{ $t('Login') }}</button>
</form>
<div v-if="isLoggedIn" class="user-info">
<p>Welcome, {{ user && user.UserName }}!</p>
<button @click="logout" class="btn btn-danger">{{ $t('Logout') }}</button>
</div>
<!-- 添加按钮用于测试
<button @click="checkIsLoggedIn" class="btn btn-primary">Check isLoggedIn</button> -->
</div>
</div>
</template>
5.编写脚本
Vue3 setup() 函数设置组件逻辑
export default {
setup() {
const store = useStore();
const loginForm = ref({
mobile: '',
pwd: ''
});
const isLoggedIn = computed(() => store.state.isLoggedIn); // 使用 computed 获取响应式的 isLoggedIn
const user = computed(() => store.state.user); // 使用 computed 获取响应式的 user
const login = async () => {
try {
console.log('isLoggedIn before login:', isLoggedIn.value); // 在调用接口前输出 isLoggedIn
const result = await store.dispatch('login', loginForm.value);
if (result) {
console.log('Login successful');
console.log('isLoggedIn after login:', isLoggedIn.value); // 在调用接口后输出 isLoggedIn
} else {
console.error('Login failed: Login unsuccessful');
}
} catch (error) {
console.error('Login failed:', error.message);
}
};
const logout = async () => {
try {
await store.dispatch('logout');
console.log('Logout successful');
} catch (error) {
console.error('Logout failed:', error.message);
}
};
// 新增方法用于测试
const checkIsLoggedIn = () => {
console.log('isLoggedIn:', isLoggedIn.value);
};
return { loginForm, login, logout, isLoggedIn, user, checkIsLoggedIn };
}
};
</script>
当 isLoggedIn 在 mutations 中被修改时,组件中使用该属性的地方会立即更新。
6.运行实例
当然,还有很多组件值得学习。
愿在前端的旅程,不断进步!🐶