安装node.js、vue4.0脚手架
-
安装node.js
https://nodejs.org/en/download/
查看版本号 node –v、npm –v 出现版本号即安装成功。(如未出现,请重启电脑后再试) -
管理nodejs版本(非必装)
执行命令安装:npm install -g n
n latest (升级node.js到最新版)
n stable(升级node.js到最新稳定版)
n 后面也可以跟随版本号,例如:$ n v0.10.26 或者 $ n 0.10.26 -
全局安装vue-cli4.0脚手架
卸载:如果已经全局安装了旧版本的vue-cli(1.x 或 2.x),需要先卸载:npm uninstall vue-cli -g
安装:npm install -g @vue/cli
查看版本号:vue -V,出现版本号即安装成功。 -
安装淘宝镜像 cnpm (非必装,网络慢的情况可安装)
npm install -g cnpm --registry=https://registry.npm.taobao.org
构建项目
-
Github
Github:http://www.github.com/(免费)
Coding:https://coding.net/(免费)
Gitlab:gitlab.com(免费30天) -
GIT基础命令(粘贴 shift + insert)
拷备项目:git clone <仓库地址>
创建分支:git branch
创建并进入分支:git checkout –b
查看状态:git status
添加所有文件:git add .
提交:git commit –m ‘这里是当前提交的描述’
拉取:git pull
推送:git push
查看分支:git branch --list
查看分支(包含远程分支):git branch -a
构建项目
- 构建项目
vue create vue-admin
- 配置信息
路由模式有两种:hash、history
hash - 即地址栏URL中的 # 符号;如:http://www.abc.com/#/hello
history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(此方法需要后端 Apache 或 Nginx 进行简单的路由配置,否则会报404。)
注:这两个配置就是解决URL有没有 “#” 号的问题,如果不在意 “#” 号这个东西,就用hash。在意就用 history。
2.x、3.x的差异
3.x目录
1、去除了 static、config、build
2、新增了 public
3、自动依赖node_modules
4、默认配置 webpack,通过 vue.config.js 修改
5、vue inspect 可查看webpack 默认配置
6、内置了 vue-cli-service serve 服务
7、浏览器打开图形界面,vue ui 查看
- Vue3 API
https://v3.vuejs.org/api/composition-api.html - Vue3 的底层介绍
https://v3.vuejs.org/guide/introduction.html
依赖 element-ui
- 官网
https://doc-archive.element-plus.org/#/zh-CN - 安装依赖
npm install element-plus --save - 全局引入
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
app.use(ElementPlus)
- vue.config.js
https://cli.vuejs.org/zh/config/ 手册 - 配置全局样式
css: { // css预设器配置项
loaderOptions: {
sass: {
data: `@import "./src/styles/common.scss";`
}
}
- 路由重定向
redirect: “login”
vue文件规则
- 固定的3块内容
template、script、style - template
必须有一层父元素,否则会报错。元素不一定是div标签,其他的也可以 - Script 按上图规则,
Name:当前的名称
Components:组件,有引入组件时,放置组件名称。
Data:数据,v-model绑定数据使用
Created:创建完成时(生命周期其中一个)
Mounted:挂载完成时(生命周其其中一个)
Methods:定义函数
Props、watch:子组件接收父组件参数 - style
Lang=“scss”:写义类型
Scoped:局部,定义时:只有当前文件应用样式。否则为全局样式
Vue指令
- v-model
在表单控件或者组件上创建双向绑定。
Input、select、textarea、component - v-for(简单理解就是数据循环)基于源数据多次渲染元素或模板块。
基础模式:
<div v-for=“item in items“ :key=“item.id”>
{{ item.text }}
</div>
带索引
<div v-for=“(item, index) in items“ :key=“item.id”>
{{ item.text }}
</div>
注:必须要有唯一的key。
当和 v-if 一起使用时,v-for 的优先级比 v-if 更高。
但是,不建设在同一标签上使用。避免产生不友好现象。
- v-show 与 v-if 区别
v-show:在元素中添加 display,隐藏DOM元素
v-if:直接删除DOM元素。DOM元素中有接口时,当v-if值为true时,会请求接口。 - v-bind 绑定属性
绑定方式:v-bind:class 或 :class
正则表达式
邮箱验证正则
验证邮箱:var reg = /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/;
字母+数字:let reg = /^(?!\D+$)(?![^a-zA-Z]+$)\S{6,20}$/
字母 或 数字:left reg = /^[a-z0-9]{6}$/
过滤特殊字符:
function stripscript(s) {
var pattern = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?]")
var rs = "";
for (var i = 0; i < s.length; i++) {
rs = rs + s.substr(i, 1).replace(pattern, '');
}
return rs;
}
:class 的几种绑定方式
- 最简单的绑定
- 判断是否绑定一个active
- 绑定并判断多个
- 单纯数组
- 数组对象结合动态判断
- 数组与三元运算符结合判断选择需要的class
VUE3.0新特性语法
- setup函数
按照官方给出的说法,setup函数是一个新的Vue组件选项,是用于在组件中使用Composition API的入口。
export default {
setup(props, context) {
context.attrs
context.slots
context.parent
context.root
context.emit
context.refs
………
}
}
- Reactive(声明单一对象时使用)
取得一个对象并返回原始对象的响应数据处理。
const obj = reactive({ count: 0 })
- ref(声明基础数据类型变量时使用)
内部值并返回一个响应性且可变的ref对象。ref对象具有.value指向内部值的单个属性。
const number = ref(0);
获取值方式:number.value
- isRef 和 toRefs
检查一个对象是否是ref对象:
const unwrapped = isRef(foo) ? foo.value : foo;
--------
function useMousePosition() {
const pos = reactive({
x: 0,
y: 0
});
return toRefs(pos);
}
const { x, y } = useMousePosition();
toRefs将reactive对象转换为普通对象,保证对象解构或拓展运算符不会丢失原有响应式对象的响应。
- watch 侦听器
const count = ref(100);
watch(()=>count.vlaue,()=>{
console.log('count数值发生变化了')
})
count.value = 200; // count重新赋值,watch则被执行
- Computed (可传入get和set,用于定义可更改的计算属性)
const count = ref(1);
const plusOne = computed({
get: () => count.value + 1,
set: val => { count.value = val - 1 }
});
plusOne.value = 1;
console.log(count.value); // 0
- $refs 实例属性
<template>
<div>
<hello-world ref="helloWold"></hello-world>
<button ref="btn"></button>
</div>
</template>
import {ref} from "@vue/composition-api"
export default {
setup() {
const helloWorld = ref(null);//helloworld组件实例
const btn = ref(null);//button dom节点对象
return {
btn,
helloWorld
}
}
}
- Props 外部属性(一般在组件用的多)
export default {
props:{
name:String
},
setup(props) {
console.log(props.name)
}
}
- 生命周期挂钩
import { onMounted, onUpdated, onUnmounted } from 'vue'
const MyComponent = {
setup() {
onMounted(() => {
console.log('mounted!')
})
onUpdated(() => {
console.log('updated!')
})
onUnmounted(() => {
console.log('unmounted!')
})
}
}
axios前后端联调
Router路由
- router-link
- 不带参数
<router-link :to="{name:'home'}">
<router-link :to="{path:'/home'}">
- 带参数
<router-link :to="{name:'home', params: {id:1}}">
// 路由配置 path: "/home/:id" 或者 path: "/home:id"
url的参数不可见,刷新后参数会消失
<router-link :to="{name:'home', query: {id:1}}">
// 路由可不配置
url带的参数是可见的,刷新后参数不会消失
- this.$router.push() (函数里面调用)
- 不带参数
this.$router.push('/home')
this.$router.push({name:'home'}) this.$router.push({path:'/home'})
- query传参
this.$router.push({name:'home',query: {id:'1'}}) this.$router.push({path:'/home',query: {id:'1'}})
url带的参数是可见的,刷新后参数不会消失
- params传参
this.$router.push({name:'home',params: {id:'1'}})
// 路由配置 path: "/home/:id" 或者 path: "/home:id" ,
// 不配置path ,,刷新页面参数会消失
// 配置path,刷新页面id会保留
- query和params区别
query跳转配合路由 path 属性,传参为明文,url上参数可见,刷新后参数不会消失
Params路转配合路由 name 属性,传参为密文,url上参数不可能,刷新后参数会消失 - Query参数跳转
this.$router.push({
path:'/select', //跳转的路径
query:{
id:this.id ,
}
})
参数接收:this.$route.query.xxxxxxx
- Params参数路转
this.$router.push({
name:‘Select', //跳转的路径
params:{
id:this.id ,
}
})
参数接收:this.$route.params.xxxxxxx
propsData、watct、computed
- prop、propsData
props 可以是基础数据或对象,用于接收来自父组件的数据。
Vue3.0中,初始化时已经在setup中注入。
- 简单语法:
props: [‘size’, ‘myMessage’] //不限制数据类型
- 规定数据类型
props: {
iconClass: {
type: String,
required: true
},
className: {
type: Array,
default: () => []
}
}
- type: (规定数据类型 )
String:字符串
Number:数字
Boolean:布尔
Array:数组
Object:对象
Date:日期
Function:函数
Symbol:示独一无二的值(ES6) - default:(默认值)
基础数据类型:直接赋值
对象数据类型:用函数赋值 () => [] - required: (必填项)
默认为false,说明父级必须传入数据,否则会报错 - validator:校验(验证传入的值是否符合规则)
- watch (观察值变化)
deep:深度监听,无论数据被嵌套多深
immediate:初始监听(简单理解,组件被加载时就监听)
2.0
wacth: {
data: {
handler(newValue, oldValue){
console.log(newValue)
},
deep: true,
immediate: true
}
}
3.0
// 基础数据监听
watch(bb, (val)=>{
console.log(val)
})
// 对象数据监听
watch(() => chooseItems.value, (val) => { console.log(val) })
// 多个监听
watch([
() => cons.page,
() => cons.pageSize,
() => query.value
], ([val1, val2, val3]) => {
console.log(val1, val2, val3)
})
- computed (计算属性)
computed: {
iconName() {
return this.a * 1
}
}
- get、set方法
2.0
computed: {
iconName: {
get: () => {
return this.a + 1
},
set: () =>{
this.a = v - 1
}
}
}
3.0
const plusOne = computed(() => count.value + 1)
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: val => { count.value = val - 1 }
})
plusOne.value = 1
console.log(count.value) // 0
vuex
5个模块
- state
储存初始化数据this.$store.state.xxxxx
- getters
对State 里面的数据二次处理(对数据进行过滤类似filter的作用)比如State返回的为一个对象,我们想取对象中一个键的值用这个方法
this.$store.getters.xxx
- mutations
对数据进行计算的方法全部写在里面(类似computed) 在页面中触发时使用this.$store.commit('mutationName')
触发Mutations方法改变state的值 - actions (异步)
action的功能和mutation是类似的,都是去变更store里的state,不过action和mutation有两点不同:
- action主要处理的是异步的操作,mutation必须同步执行,而action就不受这样的限制,也就是说action中我们既可以处理同步(视图触发Action,Action再触发Mutation),也可以处理异步的操作
- action改变状态,最后是通过提交mutation
this.$store.dispatch(actionName) - 角色定位基于流程顺序,二者扮演不同的角色。
Mutation:专注于修改State,理论上是修改State的唯一途径。
Action:业务代码、异步请求。
- modules
模块化Vuex
浏览器端储存
- cookie_js
npm install cookie_js –save
储存
cookie.set('key', 'value');
cookie.set({ key1: 'value1', key2: 'value2' });
获取
cookie.get('key');
cookie.get(['key1', 'key2']);
清除
cookie.remove('key');
cookie.remove('key1', 'key2');
cookie.remove(['key1', 'key2']);
携带请求头 cookie 业务需求
- HTML5本储存
sessionStorage(关闭浏览器时即清除) 临时性
存储
window.sessionStorage.setItem("key","value");
获取
window.sessionStorage.getItem("key");
删除
window.sessionStorage.removeItem("key");
清空所有
sessionStorage.clear();
localStorage(手动清除) 长期性
存储
window.localStorage.setItem("key","value");
获取
window.localStorage.getItem("key");
删除
window.localStorage.removeItem("key");
清空所有
localStorage.clear();
字符串与对象转换
JOSN.parse() 字符串转为对象
JSON.stringify() 对象转为字符串
router.beforeEach 路由跳前之前
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next() 执行了to里面的路由对象
进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false):
中断当前的导航。
如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next(’/’) 或者 next({ path: ‘/’ }):
跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 toprop 或 router.push 中的选项。
next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
确保要调用 next 方法,否则钩子就不会被 resolved。
全局方法 vue
全局注册,多文件调用(注册全局方法)
export default {
install (Vue, options) {
Vue.prototype.xxxxxx = function () {
console.log('Plugin Test')
}
}
}
定义单独的方法,调用时需要引入export function xxxxxx(value){
let reg = /^[a-z0-9]{6}$/;
return !reg.test(value) ? true : false;
}
VUE3.0方法
export function global(){
const aaa = () => {} const bbb = ref(''); return {
aaa,
bbb
}
}
传参方式、接收方式
- 明文传参; ( URL路径会显示传递的参数)
优势:页面刷新参数不会丢失,劣势:参数公开
- HTML:跳转
<router-link :to="{name:xxx,query:{page:1,code:8899}}"></router-link>
- JS跳转
this.$router.push({
name: `xxx`,
query: {
page: '1', code: '8989'
}
})
接收:this.$route.query.xxxxxx
- 密文传参; ( URL路径不会显示传递的参数)
优势:参数不显示,劣势:页面刷新参数消失
- HTML:跳转
<router-link :to="{name:xxx,params:{page:1,code:8899}}"></router-link>
- JS跳转
this.$router.push({
name: `xxx`,
params: {
page: '1', code: '8989'
}
})
接收: this.$route.params.page
富文本编辑器
依赖
npm install vue-quill-editor --save
引入
import { quillEditor } from "vue-quill-editor";
import 'quill/dist/quill.core.css';
import 'quill/dist/quill.snow.css';
import 'quill/dist/quill.bubble.css';
Template
<quillEditor v-model="form.content" ref="myQuillEditor" :options="data.editorOption"/>
API:
https://www.npmjs.com/package/vue-quill-editor
vue组件化
概念性
页面开发中的组件其实就是页面组成的一部分,就像电脑中的每一个元件(如硬盘、键盘、鼠标),它是一个具有独立的逻辑和功能或界面,同时又能根据规定的接口规则进行相互融合,变成一个完整的应用。
更简单的理解就是,将页面的业务逻辑拆分各个小块,再重新的组合起来,形成一个完整的体系。
当不需要某个组件,或者想要替换某个组件时,可以随时进行替换和删除,而不影响整个应用的运行。
组件大致的类:
- 页面级别的组件:页面级别的组件,通常是views目录下的.vue组件,是组成整个项目的一个大的页面。一般不会有对外的接口。
- 业务上可复用的基础组件:在业务中被各个页面复用的组件,这一类组件通常都写到components目录下,然后通过import在各个页面中使用。
- 与业务无关的独立组件:与业务功能无关的独立组件。这类组件通常是作为基础组件,在各个业务组件或者页面组件中被使用。目前市面上比较流行的ElementUI和iview等中包含的组件都是独立组件。如果是自己定义的独立组件,比如富文本编辑器等,通常写在utils目录中。
组件三要素:
Prop:用于定义组件的属性(组件属性参数)。
Event:自定义事件用于触发组件的事件(经常会回调父组件方法)。
Slot:用于组件功能的扩展。(插槽),父组件的内容传入子组件,在子组件中显示。
定义组件
全局组件:
Vue.component('child-component', {
template: `
<div>
<slot>
<p>如果父组件没用插入内容,我将作为默认出现</p>
</slot>
</div>`
});
注册的全局组件,vue项目中.vue页面都会挂载此组件,有点资源浪费。
局部组件:
import Users from './components/Users‘
按需加载,只在有需要的.vue页面中引用,不浪费资源,就是有点麻烦;
父、子组件通讯 props、emit、.sync
A.vue(父组件)
<template>
<B data.sync="100“ @eventFn=“parent” />
</template>
<script>
export default {
setup(props) {
eventFn = (number) => {}
return {}
}
}
</script>
<style lang="scss" scoped></style>
B.vue(子组件)
<template>
<div>{{ data }}</div>
</template>
<script>
export default {
props: {
data: {
type: String,
defaule: ""
}
},
setup(){
emit(“parent”, 100) // 回调父组件的方法
emit(“update:data”, 111111)
}
}
</script>
<style lang="scss" scoped></style>
keep-alive 组件缓存
vue内置组件,能在组件切换过程中将状态保留在内存中DOM元素,防止重复渲染DOM
语法:
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
属性:
include: 字符串或正则表达式,只有名称匹配的组件会被缓存
exclude: 字符串或正则表达式,名称匹配的组件不会被缓存
max: 数字,最多可以缓存多少组件实例
生命周期:
onActivated:进入页面
onDeactivated:离开页面
顺序:created-mouted-activated