Vue笔记(基于Vue2)
笔记所用版本为Vue CLI v5.0.8,对个人开发项目中所用到的部分进行记录,除Vue外可能含部分其他技术的内容
查看下方目录来确定有无需要的内容
目录
安装
Vue2,并带Router和Vuex
=>vue create 项目名称
=>Manually select features
=>Bable & Router & Vuex & Linter
=>2.x
=>n
=>ESLint with error prevention only
=>Lint on save
=>In package.json
=>根据需求选择是否保存该配置
目录构成
-
src
存放源代码
- assets
存放静态资源,例如引入的CSS,JS,图片
- components
存放项目组件,比如存放公用组件或拆分的view文件(防止原view内容过于庞大)
- router(安装时选择Router)
存放Rouer路由配置
- store(安装时选择Vuex)
存放Vuex状态管理库
- views
存放页面
- App.vue
文件为应用的根组件,应用的主要入口,可定义整体所需的布局、样式或全局行为
- main.js
文件为应用入口文件,用于创建Vue实例并挂载应用,引入全局配置和插件
-
public
存放无打包处理的静态资源,例如存放纯html文件或者固定的文件
-
node_modules
存放项目的模块,安装模块:
npm install
,因内容过于零碎与庞大,请上传时删除,由下载端自行安装 -
dist
存放打包好的静态网站,打包:
npm run build
,文件可直接放在服务器上使用 -
package.json
文件包含项目名称、版本、依赖等信息(依赖版本一般自动处理)
-
vue.config.js
文件用于配置Vue CLI构建工具,比如配置打包文件在本地打开而不是在服务器
-
babel.config.js
文件可将新版本的JavaScript转换为旧版本,以确保浏览器的兼容性(一般不用处理)
常用插件
Element UI(页面组件库)
页面组件库,Element UI
npm install element-ui
=>在main.js引用
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
axios
npm install axios
i18n(多语言)
网站多语言/国际化
npm install [email protected]
=>在src下创建i18n文件夹
=>创建index.js和需要的语言文件(zh-CN.json、en.json等)
=>index.js
// author:e4glet
// 引入 vue
import Vue from 'vue';
// 引入 vue-i18n
import VueI18n from 'vue-i18n'
// 注册 vue-i18n
Vue.use(VueI18n)
// 利用 webpack 的 require.context 方法遍历读取 i18n 目录下的所有 .json 语言文件
// 这样做省去了逐一引入语言文件的工作量,只需要将创建的语言文件 xx.json 直接放入 i18n这个目录中就行
function loadLocaleMessages() {
const locales = require.context('.', true, /.json$/i)
const messages = { };
locales.keys().forEach(key => {
messages[key.replace('./', '').replace('.json', '')] = locales(key);
});
// 返回语言配置对象
return messages;
}
// 初始化语言配置
const i18nConfig = {
locale: 'en',
messages:loadLocaleMessages()
}
// 创建 vue-i18n 实例
const i18n = new VueI18n(i18nConfig)
// 导出实例
export default i18n;
=>语言.json
{
"index.title": "Hello World",
"index.more": "more information"
}
=>在main.js引用
import i18n from './i18n';
new Vue({
i18n,
// others
}).$mount('#app')
=>可选:修改xxx.vue实现手动配置语言
<template>
<div class="home">
<div>标题:{{ $t('index.title') }}</div>
<div @click="setLang('en')">切换英语</div>
<div @click="setLang('zh-Hans')">切换中文</div>
</div>
</template>
<script>
export default {
methods: {
// 点击切换语言
setLang(value) {
this.$i18n.locale = value;
}
}
}
</script>
=>可选:修改App.vue实现自动配置语言
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
mounted() {
// 通过浏览器自动切换国际化语言版本
let lang = navigator.language;
if (lang) {
this.$i18n.locale = lang;
} else {
this.$i18n.locale = 'en'
}
},
}
</script>
=>使用
<template>
<div class="home">
{{ $t('index.title') }}
</div>
</template>
<script>
export default {
methods: {
data() {
return {
more: $t('index.more')
}
},
},
}
</script>
moment(时间日期)
时间日期库
npm install moment
=>在main.js引用
import moment from 'moment';
Vue.prototype.$moment = moment;
=>使用
<template>
<div class="home">
{{ currentDate }}
</div>
</template>
<script>
export default {
components: {
data() {
return {
// 转化为需要的格式,并作为String输出
currentDate: this.$moment().format('YYYY-MM-DD HH:mm:ss'),
}
},
}
}
</script>
UUID(通用唯一标识符)
生成不重复的随机UUID
可选版本为v1-v5
v1、v2:基于时间和节点生成(v2已被弃用)
v3、v5:基于名字和命名空间,前者为MD5后者为SHA1,需传递两个参数:name和namespace(UUID格式)(如果二者与之前使用的参数相同则会重复),如果需要根据已有信息延伸可以使用
v4:全随机生成,一般无特殊需求可直接使用
npm install uuid
=>在main.js引用
import { v4 as uuidv4, v5 as uuidv5 } from 'uuid';
Vue.prototype.$uuidv4 = uuidv4;
Vue.prototype.$uuidv5 = uuidv5;
=>使用
<template>
<div class="home">
<div>UUID v4: {{ uuidv4 }}</div>
<div>UUID v5: {{ generateUuidv5('name', '一段UUID,不是这个格式会报错') }}</div>
</div>
</template>
<script>
export default {
data() {
return {
uuidv4: this.$uuidv4(),
}
},
methods: {
generateUuidv5(name, namespace) {
return this.$uuidv5(name, namespace);
},
},
}
</script>
jQuery
[不常用]简化DOM操作和处理事件的JavaScript库
虽然特殊情况可能需要混合二者使用,但因为实现方法(Vue为数据驱动,jQuery为操作DOM)、设计理念、性能、组件化、生态等原因请尽量避免使用
npm install jquery
=>在main.js引用
import $ from 'jquery';
Vue.prototype.$ = $;
new Vue({
$,
// others
}).$mount('#app')
=>使用
<template>
<div class="home">
<button @click="useJQuery">Use jQuery</button>
</div>
</template>
<script>
export default {
methods: {
useJQuery() {
this.$('button').css('background-color', 'lightblue');
}
}
};
</script>
基础
初始样式CSS
用于清空网页基础的页面宽高保留
=>assets->css->index.css
html {
height: 100%;
}
body {
margin: 0;
padding: 0;
}
* {
border: 0;
padding: 0;
margin: 0;
text-decoration: none;
}
App.vue
<script>
import "@/assets/css/index.css";
</script>
简洁的App.vue
视图方面只负责视图容器,不进行任何页面相关的处理(使用其他页面或组件控制跳转)
样式方面可包含基础样式import "@/assets/css/index.css";
方法方面可包含挂载mounted和创建时created
=>App.vue
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
import "@/assets/css/index.css";
export default {
name: 'App',
mounted() {
},
created() {
},
}
</script>
<style>
/* default */
</style>
组件化
尽量将公用组件独立为组件,如果需要也要将过于庞大的页面完全拆分
演示为使用一个简单的顶部组件
=>HomeView.vue
<template>
<div class="home">
<el-header>
<BasicTop></BasicTop>
</el-header>
</div>
</template>
<script>
import BasicTop from '@/components/BasicTop.vue'
export default {
components: {
BasicTop
},
}
</script>
=>BasicTop.vue
<template>
<el-row :gutter="20" style="margin-left: 200px">
<el-col :offset="1" :span="12" style="text-align: left">
Hello World
</el-col>
</el-row>
</template>
基础指令
// 安装node-modules
npm install
// 启动服务器
npm run serve
// 将项目打包
npm run build
export default
export default {
// name:组件名称
name: 'MyComponent',
// data:数据
data() {
return {
propA: 'propA',
deepObject: {
propA: 'deepPropA',
propB: 'deepPropB',
},
};
},
// computed:计算属性
computed: {
computedProp() {
return this.propA + ' computed';
},
},
// methods:包含组件方法
methods: {
someFunc() {
},
},
// props:包含组件接收的属性
props: {
propertyName: {
type: String,
default: '',
},
propertyName2: String,
},
// watch:监视器
watch: {
'propertyName': function (newValue, oldValue) {
console.log(`'propertyName' 从 ${oldValue} 变为 ${newValue}`);
},
deepObject: {
handler: function (newVal, oldVal) {
console.log('deepObject changed:', newVal);
},
deep: true,
},
},
// components:子组件,配合import ChildComponent from '@/components/ChildComponent.vue'
components: {
// 子组件
ChildComponent,
},
// 生命周期类
// beforeCreate:生命周期钩子,实例创建之前调用
// 实例初始化,数据观测前,事件配置前
// 无data和methods
beforeCreate() {
console.log('beforeCreate');
},
// [常用]created:生命周期钩子,在实例创建完成后调用
// 实例创建完成
// 有data和methods
created() {
console.log('created');
},
// beforeMount:生命周期钩子,在挂载前调用
// 模板渲染成虚拟DOM前
beforeMount() {
console.log('beforeMount');
},
// [常用]mounted:生命周期钩子,在挂载完成后调用
// DOM操作,调用第三方库,异步请求
mounted() {
console.log('mounted');
},
// beforeUpdate:生命周期钩子,在更新前调用
// 类比beforeMount
// 可获取更新前状态
beforeUpdate() {
console.log('beforeUpdate');
},
// updated:生命周期钩子,在更新完成后调用
// 类比mounted
// 获取更新后状态
updated() {
console.log('updated');
},
// [常用]beforeDestroy:生命周期钩子,在销毁前调用
// 实例销毁前
// 清理定时器,取消监听,清理可能泄露的资源
beforeDestroy() {
// 取消监听
// 一般Vue.js会自动取消所有的监听,除非过于复杂造成内存泄露
this.$nextTick(() => {
this.$watch('deepObject', null);
});
console.log('beforeDestroy');
},
// destroyed:生命周期钩子,在销毁完成后调用
// 实例销毁后
// 清理工作,释放资源
destroyed() {
console.log('destroyed');
}
};
仅在本地运行(不使用服务器运行)
由于特殊情况(比如暂时没有服务器框架测试(比如Nginx)),或只想在本地运行静态网页
如果不添加此项,直接打开打包好的网页,网页会为一片空白
=>vue.config.js
// others
module.exports = defineConfig({
publicPath: './',
// others
})
技巧
父子传递数据
父组件->子组件
=>FatherView.vue
<template>
<div class="father">
<ChildView :messageFromParent="messageToChild" />
</div>
</template>
<script>
import ChildView from './ChildView.vue';
export default {
components: {
ChildView,
},
data() {
return {
messageToChild: 'Hello from parent!',
};
},
};
</script>
=>ChildView.vue
<template>
<div class="child">
<p>{{ messageFromParent }}</p>
</div>
</template>
<script>
export default {
props: {
messageFromParent: String,
},
};
</script>
子组件->父组件
[笔者注:总感觉子传父复杂的一匹]
=>ChildView.vue
<template>
<div class="child">
<button @click="sendMessageToParent">发送消息给父组件</button>
</div>
</template>
<script>
export default {
methods: {
sendMessageToParent() {
// 在点击按钮时,通过 $emit 发送自定义事件 'messageToParent',并传递一个数据
this.$emit('messageToParent', 'Hello from child!');
},
},
};
</script>
=>FatherView.vue
<template>
<div class="father">
<ChildView @messageToParent="receiveMessageFromChild" />
<p>从子组件接收到的消息: {{ messageFromChild }}</p>
</div>
</template>
<script>
import ChildView from './ChildView.vue';
export default {
components: {
ChildView,
},
data() {
return {
messageFromChild: '',
};
},
methods: {
// 父组件中的方法,用于接收来自子组件的消息
receiveMessageFromChild(message) {
this.messageFromChild = message;
},
},
};
</script>
Vuex
集中式状态管理库,介绍加在下代码块中
=>store->index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import moment from 'moment';
export default new Vuex.Store({
state: {
// 状态,存储状态(数据)
// 使用1:this.$store.state.变量名
// 使用2:
// import { mapState } from 'vuex';
// export default {
// computed: {
// ...mapState(['变量名']),
// },
// },
// 方法2注释过长,使用方法下同,不再赘述
count: 0,
},
getters: {
// 获取器,从state派生出的get方法
// 使用:this.$store.getters
doubleCount(state) {
return state.count * 2;
},
},
mutations: {
// 变更,修改state的方式
// 使用:this.$store.commit
increment(state) {
state.count++;
},
},
actions: {
// 动作,类似mutations,但是提交mutations而不是直接变更state,可以包含异步
// 使用:this.$store.dispatch
asyncIncrement(context) {
// 异步操作,此处调用延迟1秒
setTimeout(() => {
// context.state/getters/commit/dispatch
// 此处调用mutation
context.commit('increment');
}, 1000);
},
},
modules: {
// 模块,允许将state分割成模块,每个模块拥有上述的四种使用
}
})
calc计算CSS属性(在任意标签内)
通过calc进行实时计算,并可传递已有数据
100vh为100%显示窗口高度,100vw为100%显示窗口宽度
<div :style="{ height: `calc(100vh - ${headerHeight})` }">
</div>
定期/延期执行
mounted() {
// 定时执行
// 此处分为需要清理和无需清理,按需选择,下延迟执行同理,不再赘述
// 方法1:简易执行
// 简易执行如果出现作用域问题,使用箭头函数版本
setInterval(
this.someFunc
, 1000);
// 方法2:箭头函数
setInterval(() => {
this.someFunc();
}, 1000);
//方法3:设定方法名以供清理定时器
this.someFuncInterval = setInterval(() => this.someFunc(), 1000);
// 延迟执行,一次
this.someFuncTimeout = setTimeout(() => this.someFuncOnce(), 20000);
// 清理定时器
if (someCondition) {
clearInterval(this.someFuncInterval);
clearTimeout(this.someFuncTimeout);
}
}
简易当前时间
export default {
data() {
return {
currentTime: this.$moment().format('YYYY-MM-DD HH:mm:ss'),
}
},
methods: {
currentTimeFunc() {
this.currentTime = this.$moment().format('YYYY-MM-DD HH:mm:ss')
},
},
mounted() {
setInterval(
this.currentTimeFunc
, 1000)
}
}
标签:Vue,default,笔记,vue,export,Vue2,组件,import
From: https://www.cnblogs.com/meng25290/p/17864766.html