Vue
- 属于单页面应用(SPA)只需要加载一次就可以
如何开始一个Vue项目
- 做vue开发的模式都是属于 node 项目开发模式,由于 vue 框架本身非常复杂,需要各种工具包,需要搭建一个vue 的开发框架,官方提供了一个比较全的开发环境工具(cli)
- 安装脚手架工具cli,在命令行执行
npm install -g @vue/cli
- 利用脚手架工具搭建 vue 项目
- 使用命令搭建
vue create xxx
创建项目 - 使用图形化界面搭建(只有脚手架工具3以上可使用)
vue ui
执行完毕浏览器会弹出界面 - 运行已经创建好的项目其实就是执行项目下的 pakeage.json 文件内的script字段下的serve命令,这个命令执行完毕之后,默认的就会将vue的demo项目启动在本机(localhost)下的8000端口,有冲突的顺延
npm run serve
- 使用命令搭建
vue项目默认目录结构
- node_modules 所有的基础依赖,以后通过 npm 或 yarn 下载的所有的包也都在这里
- readme 项目介绍
- package.json node 项目的标志性文件 帮助管理项目,可减少命令,记录一些简单的包
- package-lock.json 项目安装的包的记录
- babel.config.js bable的配置文件 转译高低版本js
- .gitignore 如果该项目是 git 仓库那么 .gitignore 内声明的文件以及文件夹就不会上传到git 该文件就是 git 仓库忽略上传的文件
- public 文件夹,里面放的是单页面应用的 html 模板
- src 文件夹 vue 项目源代码
- assets
- components
- App.vue
- main.js
vue 基础知识
组件
- .vue 后缀的就是 vue 组件,以后也有其他形式的组件。
- App.vue 组件是项目最大的组件,因为只有App组件会被渲染到页面上的#app中
组件的构成
- template 标签
- 基本和以前的 html 标签非常像,但是不一样,一个template内只能有一个子标签
- script 标签
- 一般导出另一个对象,对象下有个一 name 属性属性值和组件名一致
- style 标签
组件的嵌套
- 父组件导入需要使用的子组件
- 在父组件中的 script 标签内的导出对象下,使用 components 属性进行子组件注册
动态组件
- 父组件写 并且需要定义一个 data 属性名和 is 后面的内容一样,这样 currentPage 的值是什么就会显示哪个组件
- 添加 标签不在销毁组件,如果组件发生改变,重新切换回来的时候保存原来的改变
- 标签内可添加 includes=“home” 意思是缓存 home 的数据
- 标签内可添加 excludes=“home” 意思是不缓存 home 的数据
- 也可以添加 :max=“1” 意思是保存几条缓存,但是得通过 includes 指定缓存的页面
使用 keepalive 会增加 activated 和 deactivated 这两个钩子,组件被缓存的时候执行
- 添加 标签不在销毁组件,如果组件发生改变,重新切换回来的时候保存原来的改变
模板语法
- 在开始和结束标签之间使用,需要使用双花括号语法
- 当作属性的属性值使用,需要使用 vue 的指令 v-bind 可以简写成
:
如果传递本地路径不可以这么用,网络路径可以
prop 组件的复用
- prop 的验证 类型检查
- 接收时需要使用对象方式 其中 type 非必须的
- 用来实现简单的组件复用,可以展示不同的子组件内容
- 实现 prop
- 在父组件内传递相应的数据给予组件,直接在子组件的标签上当做属性传递数据,属性名随便定义,属性值是传递的真正数据
- 子组件获取数据,需要在子组件的 script 内的导出对象内使用 props 属性接收。
<!-- 子组件内容 --> <template> <div class="Child"> <img v-bind:src="ImageSrc" alt="" /> <p>{{ ImageTital }}</p> </div> </template> <script> export default { name: "Child", props: ["ImageSrc","ImageTital"], }; </script> <!-- 父组件内容 --> <template> <div id="app"> <div class="contain"> <Child ImageTital="我是第一张图片" ImageSrc="图片路径,必须是网络路径,不可以是本地路径"/> <Child ImageTital="我是第二张图片" ImageSrc="图片路径,必须是网络路径,不可以是本地路径"/> </div> </div> </template>
插槽
- 方法一 属于prop方法
<!-- 子组件内容 --> <template> <div class="Child"> <div class="content" v-html="htmlStr"></div> </div> </template> <script> export default { name: "Child", props: ["htmlStr"], }; </script> <!-- 父组件内容 --> <template> <div id="app"> <div class="contain"> <Child htmlStr="<p>内容</p>" /> <Child htmlStr="<h2>内容</h2>" /> </div> </div> </template>
- 方法二 属于插槽方法(普通插槽)
<!-- 子组件内容 --> <template> <div class="Child"> <div class="content"> <slot /> </div> </div> </template> <!-- 父组件内容 --> <template> <div id="app"> <div class="contain"> <Content> <p>内容</p> </Content> <Content> <h2>内容</h2> </Content> </div> </div> </template>
插槽 slot
- 命名插槽 父级的子组件标签内写 <template #名字> <p>第一段</p> </template>
子组件接收时写 <slot name="名字" />
事件处理
- 在 vue 里面定义方法的时候,如果方法的内容需要使用 this 那么必须将该方法定义成普通函数
- 事件传参
- 事件绑定的时候直接传参
- $event.target.value 可以直接将 value 传递给父级
- 事件函数内获取事件对象,如果绑定函数没用传递额外的参数,那么事件的第一个参数默认就会是 事件对象
- 如果绑定函数的时候传递了参数,那么事件内想要使用事件对象的话,绑定的时候使用 $event 当作实参传递使用
- 事件绑定的时候直接传参
class 与 style 的绑定
- class的绑定
- 直接使用 :(v-bind)后面加
? :
判断 (只有用了:后面才可以用js语法) - 对象语法 后面如果值为真则有这个名字,如果值为假则没用这个名字
- 数组语法
- 数组语法嵌套对象语法
- 直接使用 :(v-bind)后面加
- 普通js语法的实现 <button @click=“show = !show”>控制 可以直接写
- v-show 语法 控制展示或消失
- v-if 语法 控制展示或消失 彻底删除 后面可以在加个有v-else的标签,当if消失的时候else出现,v-if适合只显示一次的标签
- 简单样式的切换
- 模板字符串语法
- 对象语法
全局样式
- 在 assets 内写一个 css 文件然后引到 main 内
vue 组件的生命周期钩子
- 组件的渲染到销毁,不同的生命周期阶段对应着组件内的不同的生命周期函数,在对应阶段对应的函数会自动触发
- 初始渲染阶段
- beforeCreate() 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
- created() 在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),property 和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el property 目前尚不可用。可以修改data
- beforeMount() 在挂载开始之前被调用:相关的 render 函数首次被调用。该钩子在服务器端渲染期间不被调用。
- mounted() 组件完全渲染到了页面上 可以获取真实的 dom 节点
- 数据更新渲染
- beforeUpdate()发生在数据更新之前
- update()数据更新完毕
- 销毁
- beforeDestroy()销毁之前调用,可以用,组件依然存在
- destroy() 销毁了
- 初始渲染阶段
组件之间的交互
- 父子组件之间
- 父子件想要修改子组件的 data,将子组件的 data 定义到父组件,然后将其当做 prop 传递给子组件,如果子组件想要修改的话,可以在父组件定义修改的方法,将该方法传递给子组件执行
- 兄弟之间
自定义事件
- 子组件写<div @click=" e m i t ( ′ c l o s e ′ ) " c l a s s = " c l s " > × < / d i v > ‘ emit('close')" class="cls">×</div> ` emit(′close′)"class="cls">×</div>‘emit(‘close’)`意思是执行父组件的事件
- 父组件写<Dialog @close=“visibility = false”>
sync
- 父组件写
nextTick 异步操作函数
- 用法 this.$nextTick(()=>console.log(‘111’)) 这个函数会比 setTimeout 执行的快
异步请求解决方案
- 使用 await 可以将 promise 的异步请求变成同步请求 函数需要 async 开头
async changePage(page) { const res = await axios.get( `http://localhost:3008/posts?_page=${page}&_limit=10` ); this.tableArr = res.data; }
ref
- document 方式获取真实dom节点,需要替换成ref
- vue中提供了获取真实dom节点的方式就是ref
- 当给普通的 html 添加 ref 属性的时候,ref 指的就是 html 节点的真实 dom ,当 ref 属性添加到组件上时 ref 值得就是组件本身
- 获取 ref 就是使用组件 this.$refs.名字------需要先在标签上写上 ref=‘名字’
动画过渡
- 需要动画的部分得用 包裹 可以在transition 上写上自定义动画的名字
- 动画名-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
- 动画名-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
- 动画名-enter-to:2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 动画名-enter 被移除),在过渡/动画完成之后移除。
- 动画名-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
- 动画名-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
- 动画名-leave-to:2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 动画名-leave 被删除),在过渡/动画完成之后移除。
- 给 动画名-enter-active 和 动画名-leave-active 加时间为动画执行的时间
- 如果引用 animate 可以直接将 animate 引入到 index.html 中 直接在 transition 标签写 leave-active-class=“动画名” 和 enter-active-class=“动画名” 为执行的动画 如果此时加上 appear 意思为打开网页自动执行 进入的动画 同时也可以加上 appear-active-class=“动画名” 为打开网页自动执行的动画
- 列表过渡 需要用 需要用 tag 指定一个元素,一般写 p 标签就行 并且里面的 v-for 需要 key 此时可以加个 move 的事件控制列表移动时的动画时间 .flip-list-move{具体时间}
过滤器
- filters:{函数名1:函数体} 调用方法 {{实参|函数名}}
- 优点:不依赖事例,可以写一个全局的过滤器 实参可以是 data 中的变量,也可以不是,只可以读不可以改
- v-html 中默认不可以使用过滤器 需要使用$option.filters.过滤器名字
watch 监听器
- 对象写法 监听的数据名:{handler(newval,oldval){函数部分}, immediate(是否打开页面就执行一次),deep(是否深度监听)}
计算属性
- 父组件写 computed: { 函数体 (函数体内必须有返回值)} 父组件使用 :传递
- 子组件需要 props 接收
在浏览器存储信息
- localStorage 生命周期是永久,这意味着除非用户显示在浏览器提供的UI上清除localStorage信息,否则这些信息将永远存在。
- sessionStorage 生命周期为当前窗口或标签页,一旦窗口或标签页被永久关闭了,那么所有通过sessionStorage存储的数据也就被清空了。
vue 组件通信
- 在 vue-advance 中
- vuex
- 父传子 prop
- 父传子 slot
- 父传子 .sync
- 父子互传 v-model
- 子传父 $emit
- 子传父 给子组件定义 ref 父组件直接使用
- $children 获取子组件的信息 $parent 获取父组件的信息
- $attr 获取当前组件的所有html属性。就是父组件使用我的时候标签内传递的所有属性
- $listeners 获取当前组件的所有html属性。就是父组件使用我的时候标签内传递的所有事件
渲染函数 和 JSX
-
使用渲染函数 render 时需要将 template 部分删除,因为 render 函数,可以帮我们创建 template
-
创建template需要使用createElement方法 render函数自带的参数createElement
-
createElement的使用
- 参数1 字符串(标签名)| 对象 | 函数
- 参数2 对象一个与模板中 attribute 对应的数据对象 非必选
- 该对象内可以设置 class style事件绑定prop插槽…
- 参数3 字符串 | 数组 表示的都是标签里面的内容,注意标签添加子标签需要使用createElement
render(createElement) { return createElement( // 第一个参数 标签名 "h" + this.Level, // 第三个参数 this.$slots接收所有的slot this.$slots.default ); },
-
jsx 语法就是可以在 js 中写 html
-
使用 jsx 语法简化 render 函数
-
如果在 html 内想要写 js 的话 需要使用 {} 包裹
render() { const tag = "h" + this.Level; return <tag>{this.$slots.default}</tag>; },
函数组件
- 函数组件需要在 template 标签加上 functional
- 函数组件和普通组件没区别
- 如果一个组件只接受 props 没有自己的 data ,没有 data 的组件可以称为无状态组件。此时可以将这个组件设置成函数组件
- 两种组件使用和创建都一样只不过函数组件渲染会快
- 函数组件一般不需要设置 script 标签
- 接受的 props 直接在 template 使用 props.xx 接收并使用
使用 js 文件创建组件
- 普通的局部函数组件就是一个对象,对象内必须添加 render 方法,返回 vnode 节点
- 也可以接收 props slot 同样执行生命周期
export default { render(){ return <div style='color:red'>局部函数组件</div> } }
组件混入
- 在 vue-advance 中 mixins下index.js 和 MixinDemo.vue
- mixin 混入之后会自动和组件内的内容进行合并或者覆盖,不冲突时都执行,冲突时 mixin 会被覆盖,mixin 先执行