官网链接:
https://cn.vuejs.org/
什么是vue:
渐进式JavaScript 框架
vue-cli链接:
https://cli.vuejs.org/
vue-cli安装:
npm install -g @vue/cli
vue -V
创建一个项目:
vue create xxxxxx
模版语法:
文本插值 {{ }}
Message: {{ msg }}
原始 HTML v-html
Using text interpolation: {{ rawHtml }}
Using v-html directive:
Attribute 绑定
简写
同名简写
布尔型 Attribute
当 isButtonDisabled 为真值或一个空字符串 (即
元素会包含这个 disabled attribute。而当其为其他假值时 attribute 将被忽略。
动态绑定多个值
const objectOfAttrs = { id: 'container',class: 'wrapper' }
使用 JavaScript 表达式
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
调用函数
条件渲染:
也可以在 上使用
Hello!
v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。
因此,如果需要频繁切换,则使用 v-show 较好;
如果在运行时绑定条件很少改变,则 v-if 会更合适
当 v-if 和 v-for 同时存在于一个元素上的时候,v-if 会首先被执行
双向绑定:
v-model
Class 与 Style 绑定:
上面的语法表示 active 是否存在取决于数据属性 isActive 的真假值。
const classObject = reactive({ active: true,'text-danger': false })
绑定一个数组来渲染多个 CSS class
绑定内联样式
const styleObject = reactive({ color: 'red',fontSize: '30px' })
路径替代:
@ 代表src根路径
模板中用到的图片,可以放置在assets目录
在数据中定义的路径,图片放置publuc目录
事件处理:
用法:v-on:click="handler" 或 @click="handler"
Count is: {{ count }}
function warn(message, event) {
// 这里可以访问原生事件
if (event) { event.preventDefault() }
alert(message)
}
事件修饰符
页面自适应:
解决方案,引入淘宝的自适应js
- 局部就在页面引入
- 全局就在main引入
组件:
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
return { count }
},
template: ``
// 也可以针对一个 DOM 内联模板:
// template: '#my-template-element'
}
样式局部化:
原理
在节点添加自定义属性 data-v-xxx
根据属性选择器添加样式
插槽:
具名插槽
可以简写为
插件:
下载插件
引用
全局在main导入
局部在组件导入
配置
样式穿透:
::v-deep 通用
>>>
/deep/
生命周期:
data:
export default {
data(){
age = 11 //静态属性不能双向绑定
return { name: 'xxxx' } //属性双向绑定
},
methods:{ //调用多次,执行多次
newName() { this.name = 'yyyy' }
},
computed:{ //计算属性有缓存,只计算一次
changeName(){ return this.name + 'aa'} //不能修改
changeAge(){//这种写法可以修改
get() { return this.age},
set( val ){ this.age = val }
}
}
}
axios二次封装:
import axios from 'axios';
const service = axios.create({// 创建axios实例
baseURL:
process.env.VUE_APP_BASE_API, // api的base_url
timeout: 5000 // 请求超时时间
});
service.interceptors.request.use(// 请求拦截器
config => {
// 可以在这里添加请求头等信息
return config;
},
error => {
// 请求错误处理
console.log(error); // for debug
Promise.reject(error);
}
);
service.interceptors.response.use(// 响应拦截器
response => {
// 对响应数据做处理,例如只返回data部分
return response.data;
},
error => {
// 响应错误处理
console.log('err' + error); // for debug
return Promise.reject(error);
}
);
export default service;
解耦:
import service from '@/utils/request';
// 获取用户列表
export function getUserList(params) {
return service({
url: '/user/list',
method: 'get',
params
});
}
调用:
getUserList({ page: 1, pageSize: 10 }).then(data => {
console.log(data);
});
路由:
// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
// 1. 定义 (路由) 组件。可以从其他文件 import 进来
const Foo = { template: '
const Bar = { template: '
// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [{ path: '/foo', component: Foo },{ path: '/bar', component: Bar }]
// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
routes // (缩写) 相当于 routes: routes
})
// 4. 创建和挂载根实例。 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能
const app = new Vue({ router }).$mount('#app')
路由守卫:
全局前置守卫:
router.beforeEach((to, from, next) => {
if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
// 如果用户未能验证身份,则 `next` 会被调用两次
next()
})
组件内守卫:
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
路由独享守卫:
const router = new VueRouter({
routes: [{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {// ...}
}]
})
watcher 函数:
a: function (val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
},// 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
c: {
handler: function (val, oldVal) { /* ... */ },
deep: true
},// 该回调将会在侦听开始之后被立即调用
d: {
handler: 'someMethod',
immediate: true
},
vuex:
持久化数据:
npm install vuex-persistedstat
vue.config.js配置:
https://blog.csdn.net/muzidigbig/article/details/115665717
output.path:硬盘上的路径,也就是你打算把文件打包到你的哪个目录,也就是各个牛人说的绝对路径!与发布时的路径完全无关。
output.publicPath:主要用来转换url中的相对路径的。如果你引用到包含url的资源,一定要配置output.publicPath。配置了此项,webpack在打包时才能根据配置动态修改uri中的相对值。
-------------------------------------------------------------------------------------------------------------------------
NUXTJS 2 框架:
安装: npx create-nuxt-app <项目名>
选择安装项目:
生命周期:
nuxtServerInit,在store文件夹下建立index.js文件。
此生命周期会全局运行,无论访问那个vue文件,都会走
nuxtServerInit 可接收两个参数store,content
export const state = {
token: "123456",
};
export const mutations = {
setToken(state, token) {
state.token = token;
},
};
export const actions = {
/**
*
* @param {*} store 可获取到vuex上下文的数据
* @param {*} content 可获取到nuxt上下文的数据
*/
nuxtServerInit(store, content) {
store.commit("setToken", "abc123");
console.log("nuxtServerInit", store);
},
};
middleware 中间件,第二个生命周期,也是执行每个vue文件都会运行的
需先在nuxt.config.js中进行配置router,设置的是全局middleware中间件
项目根目录下建立middleware文件夹,再建auth.js文件
export default function ({ store, route, redirect, params, query, req, res }) {
// 根据获取到的参数,可以去判断路由跳转到哪个具体页面,或者根据参数去处理下其他逻辑
console.log("middleware auth");
}
也可以设置局部的中间件,如建立一个list.vue,
middleware文件夹下建立一个list.js,调用如下:
list.vue
list 页面
<script>
export default {
name: "list",
middleware: "list", // 使用局部的中间件
// 第二种写法如下
middleware(){
console.log('middleware list 局部')
}
};
</script>
list.js
export default function () {
console.log("middleware list 局部");
}
全局的中间件会先执行,然后再执行局部的中间件
validate 校验路由参数的,第三个生命周期执行,一般写在vue文件里
首页
<script>
export default {
name: "IndexPage",
validate({ params, query }) {
// 判断路由传参对不对,若是不符合规范,则可让页面跳转到404页面,不至于页面出现空白情况
console.log("validate");
return true;
},
};
</script>
asyncData 方法会在组件(限于页面组件)每次加载之前被调用。
它可以在服务端或路由更新之前被调用。
在这个方法被调用的时候,第一个参数被设定为当前页面的上下文对象,
你可以利用 asyncData方法来获取数据并返回给当前组件
// 注意:由于asyncData方法是在组件 初始化 前被调用的,
//所以在方法内是没有办法通过 this 来引用组件的实例对象。
asyncData({ store, params }) {
// 再此可调用接口,请求数据
console.log("asyncData");
},
fetch 方法的第一个参数是页面组件的上下文对象 context,
我们可以用 fetch 方法来获取数据填充应用的状态树。
为了让获取过程可以异步,你需要返回一个 Promise,
Nuxt.js 会等这个 promise 完成后再渲染组件。
// 警告: 您无法在内部使用this获取组件实例,fetch是在组件初始化之前被调用
fetch({ app, store, params }) {
console.log("fetch");
},
服务端与客户端共有的生命周期
接下来是vue中生命周期,比较常用,就不做解释里。
- beforeCreate
- created
客户端的生命周期
- beforeMount() {},
- mounted() {},
- beforeUpdate() {},
- updated() {},
- beforeDestroy() {},
- destroyed() {},
路由:
重构引用原来的router文件
持久化数据:
style:
nuex.config.js配置,全局样式
使用scss步骤
- 安装插件
- 标记 scoped lang
plugins:
定义全局插件或者第三方插件配置,在页面之前调用
element-ui引用配置
axios:
配置代理:
loading:
重构:
npm install vue-verify-plugin -S
项目上线:
-------------------------------------------------------------------------------------------------------------------------
VUE 3
脚手架:
什么是vite,vite是构建工具,vite 开发效率高
vue-cli 2.0 | 3.0, vue create xxx ,是基于webpack构建
vite创建项
npm init @vitejs/app xxx
选择框架
选择用不用ts
安装路由
创建router文件夹,新建index.js文件
解决@根目录导入问题
创建时的config
修改后的config
导入文件要加.vue后缀
定义数据:
数据截持原理:
setup语法糖插件:
npm install unplugin-auto-import
修改前配置
torefs:
结构数据转变响应式
watch:
生命周期:
路由:
组件传参:
父传子
子传父
兄弟之间传值:
插槽:
传送:
动态组件:
异步组件:
https://vueuse.nodejs.cn/core/useIntersectionObserver/
组件按需引入,用户访问到了该组件再加载组件
场景一
import { useIntersectionObserver } from '@vueuse/core'
const target = ref(null)
const targetIsVisible = ref(false)
const { stop } = useIntersectionObserver( target, ([{ isIntersecting }], observerElement) => { targetIsVisible.value = isIntersecting }, )
Hello world
场景二
美 [s'spens]
场景三
混入:
mixin,分发vue组件中的可复用的功能
创建文件夹mixins,新建文件mixin.js
setup写法
选项势写法:
依赖注入:
provider | inject
vuex:
pinia:
安装
npm install pinia
创建文件夹store,新建文件index.js
组件中使用
持久化
设置代理
登录加密:
一、安装 crypto-js npm install crypto-js
二、引入crypto-js 支持ES6导入、Modular
import CryptoJS from "crypto-js"; 或者 const CryptoJS = require("crypto-js");
三、设置密钥和密钥偏移量
// 十六位十六进制数作为密钥
const SECRET_KEY = CryptoJS.enc.Utf8.parse("1234123412341234");
// 十六位十六进制数作为密钥偏移量
const SECRET_IV = CryptoJS.enc.Utf8.parse("1234123412341234");
四、封装加密方法
/* 加密方法 @param data @returns {string} */
export function encrypt(data) {
if (typeof data === "object") {
try {
// eslint-disable-next-line no-param-reassign
data = JSON.stringify(data);
} catch (error) {
console.log("encrypt error:", error);
}
}
const dataHex = CryptoJS.enc.Utf8.parse(data);
const encrypted = CryptoJS.AES.encrypt(dataHex, SECRET_KEY, {
iv: SECRET_IV,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.ciphertext.toString();
}
五、封装解密方法
/* 解密方法 @param data @returns {string} */
export function decrypt(data) {
const encryptedHexStr = CryptoJS.enc.Hex.parse(data);
const str = CryptoJS.enc.Base64.stringify(encryptedHexStr);
const decrypt = CryptoJS.AES.decrypt(str, SECRET_KEY, {
iv: SECRET_IV,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr.toString();
}
六、使用方法
import { decrypt, encrypt } from "@/utils/encrypt";
const data = "13172"
const encryptText = encrypt(data);
console.log("加密", encryptText);
const decryptText = decrypt(encryptText);
console.log("解密", decryptText);
解决 vite 不能使用 require
文件下载
视频播放
-------------------------------------------------------------------------------------------------------------------------
NUXT3
安装:
npx nuxi@latest init
安装失败解决方法:
运行项目:
- cd 到目录执行 npm i
- npm run dev
文件路由:
seo优化:
useSeoMeta({
title:'',
...
})
https://nuxt.com/docs/getting-started/seo-meta
组件库安装:
npm i @vant/nuxt
nuxt.config.js配置
接口:
export default defineEventHandler(async (event) => { // ... Do whatever you want here })
请求数据:
const { data: count} = awaituseFetch('/api/count')
浏览器插件:
vs插件:
预渲染解决方案: