vue网址总结
官网: https://cn.vuejs.org/
官方教程: https://cn.vuejs.org/v2/guide/
官方API: https://cn.vuejs.org/v2/api/
axios: http://www.axios-js.com/
swiper: https://github.com/surmon-china/vue-awesome-swiper
swiper案例: https://github.surmon.me/vue-awesome-swiper/
vue-router路由: https://router.vuejs.org/zh/
Vuex: https://vuex.vuejs.org/zh/
总结:
1. MVVM: 界面View+模型Model+视图模型ViewModel
2. Vue绑定原理: 访问器属性+虚拟DOM树
变量被修改时: 访问器属性发出通知,虚拟DOM树扫描并仅更新受影响的元素
3. 虚拟DOM树优点:
(1). 小: 只包含可能变化的元素。
(2). 遍历查找快
(3). 修改效率高: 只修改受影响的元素。
(4). 避免重复编码: 已封装DOM增删改查代码
4. Vue功能3步:
(1). 先创建增强版的界面:
a. 整个界面必须包含在一个唯一的父元素下:
通常是<div id="app">
b. 可能变化的元素内容用{{自定义变量名}} 标记
c. 触发事件的元素用@click="自定义处理函数名" 标记
(2). 再创建new Vue()对象,其中el: 指向new Vue()要监控的页面区域
(3). 在new Vue()对象内定义模型对象data 和methods
a.界面所需的所有变量都放在data中
b.界面所需的所有事件处理函数都放在methods中
5. 总结: 绑定语法+13种指令
(1). 如果元素的内容需要随变量自动变化: {{}}
(2). 如果元素的属性值需要随变量自动变化: :
(3). 控制一个元素显示隐藏: v-show //使用display:none隐藏元素
(4). 控制两个元素二选一显示: v-if v-else //使用删除元素方式隐藏元素
(5). 多个元素多选一显示: v-if v-else-if v-else
(6). 只要反复生成多个相同结构的元素组成列表时: v-for :key="唯一标识"
强调: 为什么必须加:key="i"?给每个元素副本添加唯一标识。修改数组中某个元素值时,避免重建整个
列表,只需要修改一个DOM元素副本即可!提高修改效率。
(7). 带有参数的事件, 绑定事件: @事件名="方法名(参数, 参数, $event)
(8). 防止用户短暂看到{{}}: v-cloak
(9). 只要绑定原始HTML代码片段内容: v-html
(10). 如果元素的内容只在首次加载时绑定一次,之后都不会改变: v-once
优化: 减少虚拟DOM树中元素个数。
(11). 保护内容中的{{}}不被编译: v-pre
(12). 今后只要想获得表单元素的值或状态: v-model
6. 绑定样式:
(1). 需要精确修改某一个css属性,就绑定 :style="{属性名:值}"
(2). 只要批量修改一个元素的多个css属性就绑定class
7. 只要希望在页面加载时自动对元素执行一些初始化操作时就用自定义指令:
(1). 添加自定义指令:
(2). 使用自定义指令:
<元素 v-自定义指令名>
8. 今后只要根据其他变量的值动态计算出一个属性值就用计算属性:
`<元素 style="固定样式" :style="{css属性:变量名, ...}"`
data:{
变量名:css属性值
... : ...
}
b. <元素 style="固定样式" :style="变量名"
data:{
变量名:{
css属性名: 属性值,
... : ...
}
}
<元素 class="固定class" :class="{class名:变量名, ...}"
data:{
变量名:true或false,
... : ...
}
b. <元素 class="固定class" :class="变量名"
data:{
变量名:{
class名:true或false,
... : ...
}
}
Vue.directive("自定义指令名",{
inserted(domElem){
对domElem执行DOM操作
}
}
9. 希望将变量的原始值先加工后再显示给用户看时就用过滤器:
10. 只要在vue中发送ajax请求,就用axios
11. vue生命周期4个阶段 8个钩子函数
beforeCreate(){ ... }
(1). 创建(create)
created(){ ... }
beforeMount(){ ... }
(2). 挂载(mount)
mounted(){ ... 经常在这里发送ajax请求 ... }
beforeUpdate(){ ... }
(3). 更新(update)
updated(){ ... }
<元素>{{计算属性}}</元素>
new Vue({
el:"#app",
data:{...},
methods:{...},
computed:{
计算属性名(){
计算过程
return 计算结果
}
}
})
Vue.filter(“过滤器名”,function(oldVal, 自定义形参,…){ return 加工后的新值 }) <元素>{{ 变量 | 过滤器(实参值, …) | … }}</元素>
axios用法
axios.defaults.baseURL="服务器端接口的公共基础地址部分"
axios.get(
"服务器端接口地址的相对路径",
{
params:{ 参数名: 参数值, ... }
}
).then(result=>{
... result.data...
})
或
axios.post(
"服务器端接口地址的相对路径",
"参数名1=参数值1&参数名2=参数值2&..."
).then(result=>{
... result.data...
})
强调: 在vue内使用axios,then中必须用箭头函数,保持then内this与外部this一致,都指向当前new
Vue()对象
中添加父组件标签。 (2). 运行时:
,发现父组件标签,创建并替换父组件
beforeDestroy(){ ... }
(4). 销毁(destroy)
destroyed(){ ... }
补: this.$nextTick(function(){ ... })
注定只能在本轮生命周期结束后才自动执行的回调函数
可防止原生DOM操作被vue挂载阶段覆盖
12. 只要希望重用一块独立的功能区域就用组件:
(1). 定义组件
(2). 在HTML中使用自定义组件
<组件标签名/>或双标记也行
(3). 原理: new Vue()扫描到自定义组件标签,
a.组件的template中的HTML内容代替页面中<组件标签>位置。
b. 并为这个小区域专门创建一个缩微版的vue类型对象。
1). 调用组件的data()函数为当前组件副本创建一个专属数据对象副本。
2). 引入组件对象中的methods等其他内容到当前组件对象副本中
13. 组件化开发:
(1). 步骤:
a. 拿到页面先划分功能区域
1). 从上到下,按功能不同划分区域
2). 按是否重用划分
b. 为每个组件创建独立的.js文件,其中包含一个组件对象及其内容
c. 将所有组件引入唯一完整的html页面中,并在
a. new Vue()扫描
b. 父组件扫描自己内部的template内容,创建并替换子组件
3). 父组件template中用<子组件标签名/> 引入子组件内容
components会将子组件对象名的驼峰命名自动翻译为-分隔
所以, 使用子组件标签时,要用-分隔多个单词
(2). 组件间传参: 父给子
a. 父组件给:
<子组件 :自定义属性名="父组件变量">
b. 子组件取:
props:["自定义属性名"]
结果: 在子组件内,props中的"自定义属性名"与子组件自己data中的变量用法完全相同!
14. SPA : Single Page web Application 单页应用
网站只有一个页面, 通过局部内容的切换实现内容变化
依赖于 路由系统
Vue.component(`组件标签名`,{
template:`HTML内容片段`,
data(){ return { 变量 } },
//其余和new Vue()完全相同
})
路由系统的重要标签:
<router-view/> : 一个占位符, 会随路由配置的路径变化
<router-link to="" /> : 代替a标签实现路由切换
1). 创建路由字典对象:
(3). 路由跳转: 2种:
a. html中: <router-link to="/相对路径">文本<router-link>
b. js中: this.$router.push("/相对路径")
(4). 路由传参:
a. 修改路由字典:
{path:"/相对路径/:自定义参数名", component:页面组件对象, props:true}
b. 跳转时:
<router-link to="/相对路径/参数值"
或
this.$router.push("/相对路径/参数值")
c. 下一个页面接:
1). props:[ '自定义参数名' ]
2). 可将"自定义参数名"用作绑定或程序中都行
15. 安装vue脚手架:
(1). 设置npm默认使用国内淘宝镜像仓库:
npm config set registry http://registry.npm.taobao.org
备选: npm i -g cnpm --registry=http://registry.npm.taobao.org
(2). 安装可反复生成项目脚手架代码的工具:
npm i -g @vue/cli
备选: cnpm i -g @vue/cli
(3). npm run serve
启动vue脚手架项目
(4). 打开浏览器,地址栏输入: http://localhost:8080
16. 脚手架文件夹结构:
(1). 唯一完整的HTML页面: 一分为三:
a. public文件夹
1). 图片img文件夹放在public文件夹下
2). 第三方css的压缩版和第三方js的压缩版都放在public文件夹下
3). 唯一完整的HTML文件index.html中,head中引入第三方的css和js
b. src/App.vue
1). <template> 下只包含公共的页头组件和<router-view>
2). <style> 下包含所有网页都要用到的公共css样式,比如css重置代码
c. src/main.js
var routes=[
{path:"/", component:首页组件对象名},
{path:"/相对路径" , component: 其它页面组件对象名},
{path:"*", component: 404页面组件对象 }
]
1). import引入App.vue,router,axios,以及其他全局组件
2). 将全局组件对象转为真正的全局组件: Vue.component( "组件标签名", 全局组件对象 )
(2). 为每个页面创建.vue组件文件,都放在src/views文件夹下。每个.vue文件中:
a. <template> 标签内,包含这个页面的HTML内容
b. <script>export default{ ... }</script> 中包含组件对象的js内容。
c. <style> 标签内包含仅这个页面组件内才使用的css
d. <template> 中的HTML内容以及<script>export default{...} </script> 中的js内容,和前四天将的
是完全一样的写法,绑定,指令,函数,生命周期,axios 请求等都一样。前四天怎么用,这里就怎么用。
(3). 路由字典和路由器对象,在src/router/index.js文件中
a. 仅import首页组件对象,不要过早引入其它页面组件
b. 路由字典中首页组件: { path:"/", component:首页组件对象}
c. 其余页面组件都做成懒加载:
(4). 全局组件都放在src/components 文件夹下,每个全局组 件.vue文件中。但是,全局组件必须在main.js
引入,并用Vue.component()转化为真正的全局组件,才能在其它组件的HTML中使用。
(5). 运行时: 路由器router对象监视浏览器地址栏路径变化,并查找对应的页面组件内容,先代替App.vue中
的<router-view> ,然后main.js再将包含要加载的页面内容的 App.vue组件内容,替换到唯一完整的
index.html中空<div id="app">位置。
17. 懒加载:
(1).异步延迟下载:
(2).彻底懒加载:
项目根目录创建vue.config.js
18. http-proxy方式跨域:
在服务器端没有配置CORS或JSONP跨域的情况下:
(1). vue.config.js中
{
path: '/相对路径',
component: () => import(/* webpackChunkName: "组件名" */ '../views/其它页面组件.vue')
}
src/router/index.js
//不要import Details from "../views/Details"
const routes=[
...
{
path:"/details/:lid",
component: () => import(
/* webpackChunkName: "details" */
'../views/Details.vue'
),
props:true
]
module.exports={
chainWebpack:config=>{
config.plugins.delete("prefetch")
//删除index.html开头的带有prefetch属性的link,不要异步下载暂时不需要的页面组件文件
},
}
19. 避免组件间样式冲突:
(1) <style scoped>
(2) 对于引入样式的局部用法: <style scoped src="css样式路径"
20. 事件修饰符:
@事件.13 按回车时才执行
@事件.stop 阻止冒泡
@事件.prevent 阻止默认行为
21. 插槽 slot:
组件只负责结构搭建 或者 某个部分内容需要外部传入
写法: <slot/> 或 <slot name='名称'/>
使用时:
默认插槽
22. Vuex: 全局状态共享
(1). 今后只要多个组件都需要共用一批数据时,都可用vuex
(2). 5个核心属性
state: 共享的属性值
mutations: 变更state中值的方法
actions: 异步方法存放此处
getters: 计算属性
modules: 模块化
module.exports={
... ,
devServer: {
proxy: {
'/api': {
target: `http://服务器端接口地址统一前缀部分`,
changeOrigin: true,
pathRewrite: {
'^/api' : '' //将程序中的/api,替换为空字符串,再和target中的基础路径 拼接起来作为发送到
服务器的最终请求地址。
}
}
}
}
}
<组件>
<template>
默认插槽
</template>
<template slot='名称'>
具名插槽: 旧写法
</template>
<template v-slot:名称>
具名插槽: 新写法
</template>
<template #名称>
具名插槽: 简化写法
</template>
</组件>
(3). 任意组件中想用state中的变量:
c. <template> 中可用state中某变量名用于绑定和指令
d. js中可this.$state 中某变量名来读取变量值
(4). 任意组件中想修改state中的变量值:
c. js中可用this.$store.commit() 中某方法名(实参值)修改 state中变量值
23. TypeScript
1. 变量: var或let或const 变量名:数据类型=值;
2. 函数:
(1). function 函数名(形参:数据类型, ...):返回值类型{
... ...
}
(2). 不确定参数个数:
单个参数不确定有没有
function 函数名(形参1:数据类型, 形参2?:数据类型)...
或
function 函数名(形参1: 数据类型, 形参2:数据类型=默认值)...
多个参数不确定有没有
function 函数名(形参1:数据类型, ...形参2:数据类型[])...
重载:
a. 先定义空的函数声明,列举所有重载的可能:
function 函数名():返回值类型;
function 函数名(形参1: 数据类型):返回值类型;
function 函数名(形参1: 数据类型, 形参2:数据类型):返回值类型;
b. 正式实现功能的函数:
function 函数名(){
根据arguments中的元素个数,决定具体执行何种逻辑
}
3. class: 新规定:
import { mapState } from "vuex"
export default {
computed:{
...mapState([ "state中某变量名", ... ]),
其它计算属性
}
}
import { mapMutations } from "vuex"
export default {
methods:{
...mapMutations ([ "Mutations中某方法名", ... ]),
其它方法
}
}
class 类型名{ //必须提前声明属性,才能使用
属性1: 数据类型=初始值
属性2: 数据类型=初始值
...
(2). 访问修饰符: 今后,只要想控制一个class中属性的使用范围时。
class 父{
public 公有属性:数据类型=值
protected 受保护的属性:数据类型=值
private 私有属性:数据类型=值
父的函数(){
以上三种属性都能用
}
}
class 子 extends 父{
子的函数(){
只能用父的公有属性和父的受保护的属性
不能用父的私有属性
}
}
除父子class以外的程序区域:
只能用父class的对象的公有属性
(3). 接口: 保证开发人员按照要求实现类的成员
a. 先定义接口:
interface I接口名{
属性名:数据类型
...
方法名(形参:数据类型, ...):返回值类型;
}
4. 模块化开发:
(1). 模块中只抛出一个东西:
export default 一个东西
import 别名 from "相对路径"
(2). 模块中同时抛出多个东西:
//构造函数必须定义数据类型
constructor(形参1:数据类型, 形参2:数据类型,...){
this.属性1=形参1;
this.属性2=形参2;
...
}
/*方法定义...*/
}
export { 多个东西用逗号分隔 }
import { 想要的个别东西用逗号分隔 } from "相对路径"
4. Vue3
(1). 绑定原理:ES6 Proxy代理对象+虚拟DOM树
(2). main.ts中:
a. 默认: createApp(App).use(store).use(router).mount('#app’)
b. 全局组件:
页面/组件中:
<template> 里和<style> 里与Vue2基本一样:
小差别是: template 不再要求唯一的父元素
<script> 里几乎全变:
import 组件对象 from “组件文件相对路径”
var app= createApp(App);
app.use(store).use(router).mount('#app’)
import { defineComponent, ref, toRefs, watch, computed, onMounted } from 'vue’;
import axios from “axios” //axios对象是单例模式,整个项目中只有一个axios对象,哪里使用都一
样。
import 子组件对象 from “子组件相对路径”
export default defineComponent({
components:{ 子组件对象 },
directives:{
“自定义指令名”:{
mounted(DOM元素){
DOM操作
}
}
},
setup(){
// 只有包裹在 ref 中的变量, 才能引起DOM变化
// ref生成的变量, 使用时必须写 a.value
let a = ref(10)
// reactive: 适合声明多个变量, 并且使用时更加便捷; data.b 即可
const data=reactive({
b:33
});
const methods={
界面所需方法(){
ref的变量要写 a.value
data中的变量, 不需要value: data.b
},
计算属性:computed(()=>{ //vue3中没有过滤器了,计算属性兼顾过滤 器职能
//计算过程
return 返回值
})
}
(5). 新声明周期钩子函数: 背过:
beforeCreate -> setup()
created -> setup()
beforeMount -> onBeforeMount
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> onUpdated
beforeDestroy -> onBeforeUnmount
destroyed -> onUnmounted
|