Vue

day01

1. 原生DOM vs 函数库 vs 框架

原生DOM: 优点: 跨平台好
        缺点: 繁琐
函数库jQuery: 优点: 对原生DOM的每个API进行了简化
        缺点: 并没有简化开发的步骤
框架Vue,AngularJS,React: 优点: 彻底简化了开发的步骤
        缺点: 需要转变观念

2. 什么是Vue:

Vue是基于MVVM设计模式的渐进式的前端js框架
渐进式: 可以有选择的逐步使用框架中的组件
“全家桶”: 必须全盘使用所有组件
前端js框架: 不需要nodejs,仅靠浏览器就可独立运行
为什么后续需要nodejs?将Vue框架中浏览器不认识的新技术翻译为浏览器认识的ES5的对等标准——已经封装好了

何时: 侧重于以数据操作为主的前端项目开发

3. 如何使用Vue:

下载: cn.vuejs.org
最新稳定版: 2.6
开发版: 未压缩的,包含完备注释和错误提示信息
优: 可读性好
缺: 体积大,不便于传输
生产版: 代码经过压缩,删除了所有注释和错误提示信息
优: 体积最小化,便于传输
缺: 不便于学习和阅读
使用Vue 2种方式:

  1. 下载独立的vue.js,在网页中引入:
  2. 用脚手架代码:

原理: MVVM设计模式:
旧的前端代码划分:
html: 定义网页的内容
css: 定义网页的样式
js: 增删改查,事件绑定
MVVM设计模式将前端内容重新划分: (步骤)

  1. 界面(View): html+css
    为HTML添加了动态功能: 变量,if else, for
  2. 模型数据(Model): 所有页面上需要的/可能发生变化的数据。集中定义在data={ 数据1:值1, 数据2:值2, … }
    往往模型数据都是ajax从服务端请求来的。
  3. 控制器(ViewModel):将视图View和模型数据(Model)绑定在一起。
    绑定: 监控视图和模型,始终保持模型数据与页面自动同步
    控制器ViewModel中包含两大子系统:
    1. 响应系统: 监控模型中每个变量的变化
      只要有变量发生变化,立刻发出通知!
      本质: 将data中每个属性都提升为new Vue对象的访问器属性。只要修改new Vue对象的访问器属性,就可修改data中的变量。但是,同时会发出通知!
    2. 虚拟DOM树:
      什么是: Vue临时生成的仅保存可能变化的元素和属性的DOM树
      何时生成: new Vue()边扫描受监控的页面元素,边创建虚拟DOM树,仅保留可能发生变化的元素
      何时使用: 响应系统通知某个变量被改变时,告知虚拟DOM树。虚拟DOM树快速遍历自己,找到受影响的DOM元素,仅修改受影响的DOM元素
      总结: 虚拟DOM树:
      1. 内容少,遍历极快
      2. 仅修改受影响的DOM元素的属性或内容

4. 绑定语法:

{{变量名}} Interpolation 插值
告知Vue框架,这里需要哪个变量
{{}}中还可写一切正确的有返回值的js表达式:
比如: 运算, 三目, 函数调用,访问数组元素,访问对象属性,模板字符串
问题: 只能绑定内容,不能绑定属性和事件等…

5. 指令directive

什么是: Vue新增的增强HTML功能的特殊属性
为什么: HTML缺少动态原因所需的要素: 运算, 分支,循环
包括:

  1. 专门绑定属性值的指令: v-bind
    何时: 绑定属性值
    如何: <ANY v-bind:属性名="js表达式">
    v-bind: 让普通的属性的""中也可以执行js程序
    其实可省略: v-bind
    所以: 今后只要绑定属性都用 :属性名="js表达式"
  2. 事件绑定:v-on
    如何:
    HTML: <ANY v-on:事件名="处理函数名">
    <script>new Vue({
      el:"#app",
      data:{ 模型变量 },
      methods:{
   	处理函数 (){
         this.模型变量
       }
      }
    })
 其实: v-on: 可简写为@,
  所以,今后绑定事件都用@事件名="处理函数"
  1. v-if: 为HTML添加分支结构
    v-if 控制一个元素的显示隐藏
    <ANY v-if=“条件表达式”
    v-if v-else 可控制两个元素二选一显示
    <ANY v-if=“条件表达式”
    <ANY v-else
    v-if v-else-if v-else 可控制多个元素多选一显示
    <ANY v-if=“条件表达式”
    <ANY v-else-if=“条件表达式”
    <ANY v-else
  2. v-show: 控制一个元素显示隐藏
    用法同v-if: <ANY v-show=“条件表达式”
    本质: 用display:none隐藏元素
    v-if的本质: 用删除元素节点的方式,隐藏元素
  3. v-for: 根据数组反复生成多个相同结构的元素
    用法: <ANY v-for="elem of 数组"> //elem可当做模型变量使用,用作绑定 </ANY>
    of会依次读取数组中每个元素
    每读取一个元素就创建一个<ANY>
  4. 绑定html片段:
    问题: {{}}无法绑定HTML片段,它会努力保持HTML片段原样显示
    解决: v-text="变量" 不行,v-text等效于{{}}
    v-html="变量" 可以,会被浏览器解析为正文
    总结: 只要绑定的内容是HTML片段,都用v-html
  5. v-cloak: 在vue加载完之前,短暂隐藏{{}}语法,不让用户看到
    如何:
    1. 在界面中想隐藏的元素/父元素上添加v-cloak自定义属性
    2. 在页面的<style>中用属性选择器找到所有有v-cloak属性的元素,设置隐藏:
      <style>[v-cloak]{ display:none }</style>
      结果: 当vue对象加载完成,会自动查找所有v-cloak属性,自动移除。所有元素就重新显示出来
  6. v-pre: 保护内容中碰巧出现的{{}}不被VUE编译,保持原样显示
  7. v-once: 控制一个变量只在开始时绑定一次,之后即使模型变量变化,也不再更新.

6. 双向绑定:

单向绑定: 将内存中模型数据中的值绑定到界面上(Model->View)
问题: 无法绑定表单元素的值
表单元素值的修改,无法自动映射到内存中
解决: 今后只要绑定表单元素,都用双向绑定
什么是双向绑定: 即能将Model中的数据绑定到界面上(Model->View),又能自动将界面上的修改,映射到内存中(View->Model)
如何: <表单元素 v-model:value="模型变量">
简写: 1. <input type="text" <textarea> <select>
都可简写为: v-model="模型变量"
省略:value,默认绑定value属性
2. <input type="checkbox">
可简写为: v-model=“模型变量”
但默认绑定的是checked
3. <input type="radio">
可简写为: v-model=“模型变量”
但用模型变量和radio的value做比较
如果模型变量的值=radio的value时,就选中
如果模型变量的值!=radio的value时,就不选中

day02

1. 双向绑定:

哪个属性会被改变,v-model就自动绑定哪个属性

  1. 文本框和文本域:
    <input type="text" v-model[:value]="变量">
    <textarea v-model[:value]="变量">
  2. 单选按钮:
    <input type="radio" name="分组" value="1" v-model="sex">男
    <input type="radio" name="分组" value="0" v-model="sex">女
    v-model先用sex的值和value做比较
    哪个value==sex,当前radio就选中,否则就不选中
  3. 复选框:
    单独使用:
    <input type="checkbox" v-model="isAgree">同意
    v-mode:checked 且isAgree是bool类型
  4. select元素:
    <select v-model="orderStatus"> value=30
    <option value="10" >未付款</option>
    <option value="20" >已付款</option>
    <option value="30" >已发货</option>
    <option value="40" selected >已签收</option>

watch监控: 当某个模型变量被修改时,自动触发的函数

  wath:{
    受监控的变量名(){
      //会在受监控的变量被双向绑定修改时自动执行
    }
  }

2. 绑定class和style

绑定style:

  1. 其实style也是一个普通的字符串属性,也可以:
    <ANY :style="模型变量"
    模型变量: “css属性:值; css属性:值; …”
    问题: 字符串拼接很繁琐,不直观
  2. 将style看做一个对象绑定:
    <ANY :style="对象名"
    data:{ 对象:{ css属性:值, css属性:值 }
    }//css属性都要去横线变驼峰!

绑定class

  1. 其实class属性也只是一个字符串属性,也可以:
    <ANY :class="拼接字符串"
  2. 都用对象方式绑定:
   <ANY :class="对象名"
            //"success"
   data:{
     对象名:{
       hide: false,
       success: true,
       fail:false
     }
   }

3. 计算属性:

什么是: 自己不保存值,每次访问都要根据其他属性计算出来
何时: 要显示的值,需要根据其他属性动态计算才能获得时
如何:

  1. 定义计算属性:
   computed:{
     计算属性名(){
       根据其他属性,返回计算结果
       return ... ...
     }
   }
  1. 绑定时: 和普通属性完全一样,不要加()
    vs methods:
    methods: 调用时,必须加(),调用几次,就重复计算几次
    computed: 绑定时,不加(),即使多次绑定,也只计算一次。vue会缓存计算属性的计算结果
    总结: 如果更关心值/结果,优先选计算属性
    如果更关心操作/执行过程,优先选方法

4. 自定义指令:

如果13种指令不够用,可自定义指令:
如何:

  1. 定义指令:
   Vue.directive(
	"指令名",//不写v-前缀
    {
     inserted(elem){//当拥有该指令的元素被添加到DOM树后自动执行
       //elem: 接住当前标有该指令的DOM元素对象
       对elem执行各种想要的DOM操作
     }
    }
   )
  1. 使用指令:
    <ANY v-指令名>
    当该元素被加载到DOM树上后,自动执行指令中的inserted

5. 过滤器:

什么是: 对从模型中绑定来的原始值,进行再加工后,再显示
何时: 如果模型中的原始值不能直接使用
如何:

  1. 定义过滤器:
    Vue.filter("过滤器名", function(value,形参1,...){
      //value会接住要处理的原始值
      return 改造后的新值
    })
  1. 使用过滤器:
    在绑定时:
    {{原始模型变量|过滤器(实参1,...)|下一个过滤器 }}
    :属性="原始模型变量|过滤器(实参1,...)|下一个过滤器"

6. axios:

什么是: 基于Promise的专门发送http请求的函数库
何时: 今后在vue中发送ajax请求首选axios
为什么:

  1. 手写ajax四步/封装自定义函数
  2. jQuery: $.ajax() —— Vue中没有jQuery
  3. Vue官方曾经提供了专门发送ajax请求的组件:vue-resource
    ——官方不推荐使用
  4. Vue官方推荐axios作为Vue中标准的发送ajax请求的组件
    如何:
    1. 下载并引入:axios.min.js
      内存中,就多出一个axios对象,有两个方法: get() post()
    2. 发送get请求:
      axios.get("url",{
        params:{
         uname: "dingding",
         upwd:"123456"
        }
      }).then(function(res){
		//res是经过axios再封装的响应对象,不仅是result
		//result: res.data才是从前的result
      })
        发送post请求: 
        axios.post("url","uname=dingding&upwd=123456")

7. 组件:

什么是: 拥有专属的HTML,CSS,js和数据的独立页面区域
为什么: 重用!
何时: 只要一个页面功能,需要反复使用时
如何:

  1. 定义组件:
   Vue.component(
	"组件名"//不要用驼峰命名,而用"单词-单词"
	{
	  template:"#tplID", //找到要反复使用的HTML片段
      data:function(){//每次重复创建组件时,都自动调用data函数,为本次组件创建一个专属的模型对象
		return { 模型数据 }//类似于以前的data
      },
      methods:{ 方法/事件处理函数 },
      computed:{ 计算属性 },
      watch:{ 监听函数 }
   	}
   )

HTML片段都要保存在<template>元素中并其一个唯一的id
2. 使用组件:
其实vue中的一个组件,就是一个可重复使用的自定义标签而已。组件名其实就是一个标签名:
<组件名></组件名>
会被template的HTML片段代替!

day03

1. *****组件化开发

什么是组件化开发: 今后一个网页都是由组件组成的
拿到网页,先划分组件,再分组件开发,最后再拼接成一个网页
为什么:

  1. 团队协作开发
  2. 松耦合
    如何:
    1. 拿到网页,先划分组件
    2. 定义组件
    3. 将组件拼回主页面中

问题: 组件分类:

  1. 根组件: 一个页面中只有一个的组件:
    new Vue({
      el:"#app",
      data:{ ... }
    })
  1. 全局组件: 可出现在任意位置的组件
    Vue.component("组件名",{
	  template:"#tplxxx",
      data(){ return { ... }  }
    })
  1. 子组件: 只能出现在规定父组件内的组件
    如何: 2步
    1. 将Vue.component降级为普通的js对象
    //Vue.component("todo-add",{
    var todoAdd={
      template:"#tplTodoAdd",
      data(){ return { ... } }
    }
    
    1. 在父组件的{}中的components下添加子组件对象:
     Vue.component("todo",{
        template:"#tplTodo",
        data(){ return { ... } },
        components:{ todoAdd }
                //vue会自动将todoAdd -> <todo-add>
     })
    

*****组件间传参:
父->子:
问题: 父组件的成员,子组件无权直接使用
解决: 2步
1. 在子组件对象中添加props属性:

       var 子组件={
        template:"#tpl子组件",
        props:[ "自定义属性名" ]
        data(){ return {...} }
       }
   后果: 2个:
   1. 为子组件标签添加了一个自定义扩展属性,用于接收父组件的值。
      <子组件 自定义属性="">
   2. 子组件对象中多处一个同名的模型变量,可用于获取外部传入的属性值,在内部执行操作。
 2. 在父组件的<template>中
  <子组件 :自定义属性="父组件的数据"></子组件>
  将父组件data中的数据通过绑定方式,传递给子组件的自定义扩展属性。
  其实,父子组件用的还是同一个数据对象,任何一方修改,另一方都会受影响。

2. *****SPA

Single Page Application
什么是: 整个应用程序只有一个完整的HTML页面文件
单页面应用中所谓的“页面”,其实就是组件
由一个路由器根据URL地址中的锚点地址不同,选择不同的组件替换
vs 多页面应用:
单页面应用的优点:
请求次数: 多页面应用每更换一次页面就需要重新发送请求
单页面应用每更换一次页面,只需要从本地加载组件即可,不用重复发请求
资源共用: 多页面应用每更换一次页面,都需要重复请求相同的资源
单页面应用仅在首次加载时请求一次资源文件,之后更换页面,因为不是更换整个html文件,所以共用资源无需重复下载。
效率: 多页面应用,每次更换页面需要重建整棵DOM树,效率低
单页面应用,每次更换页面无需重建DOM树,仅是替换部分子树片段即可。效率高。
页面过渡效果: 多页面应用不可能实现页面过渡效果
单页面应用可以实现页面过渡效果
单页面应用的缺点:

  1. 首屏加载慢,要下载全部资源
    已经解决: 在路由中设置延迟加载
  2. 不便于搜索引擎优化

实现单页面应用: vue-router.js

  1. 先创建一个唯一的完整的index.html
    引入vue-router.js
    div#app中添加一个<router-view>标签,用于为将来要加载的"页面"组件占位
  2. 分别创建多个“页面”组件对象和模板
    “页面”组件对象必须以子组件形式创建
  3. 定义路由字典:
    路由字典:保存一组路径与组件对象对应关系的数组
    var routes=[
    {path:"/相对路径名", component: "页面"组件对象 }
    ]
  4. 定义路由器对象,将路由字典放入路由器中:
    才是真正负责导航/替换页面内容的对象
    var router=new VueRouter({ routes })
  5. 将路由器对象,加入当前页面的根组件new Vue
    new Vue({
    ...,
    router,
    ...
    })

嵌套路由:
何时: 多个页面中包含相同的区域(页头,页脚,导航)时
如何: 2步:

  1. 将多个页面共用的部分,保存在一个新创建的组件中
    新组件同时包含<router-view>
  2. 定义路由字典:
      //home: 是保存相同部分的组件
      {path:"/",component:home,children:[
		{path:"/",component:index},//默认路径 /
        {path:"/index",component:index},// /index
        {path:"/details",component:details} // /details
      ]},
      //login和之前页面没有相同部分
      {path:"/login",component:login}

加载时:
#/ /=="/" 先加载home页头
/=="/" 再加载index替换home中的<router-view>
#/details /=="/"先加载home页头
/details="/details" 再加载details替换home中的<router-view>
#/login /=="/"先加载home页头
没有/login
撤掉home页头
/login="/login" 只加载login

day04

1. 路由跳转:

HTML中: 所有a换成<router-link to="路径"></router-link>
运行时,自动翻译为<a href="#/路径"></a>
js中: this.$router.push("路径")
$router就是var router=new VueRouter()路由器对象
要执行跳转这个动作,只能借助$router
凡是以$开头的,都是Vue内置的对象

2. 路由传参:

2步:

  1. 在路由字典中配置支持参数的相对路径:
    {path:"/details/:lid",component:Details,props:true}
    /:lid: 将来请求details页面时必须携带一个lid参数
    比如:/details/5
    details页面中获取参数:
    this.$route.params.lid
    如果定义了props:truelid参数会自动传递给props中同名的属性: props:["lid"]
    this.lid=5
  2. 跳转时: <router-link to="/details/5"

4. 组件生命周期:

什么是: 一个组件创建的过程
包括: 4个阶段:

  1. create: 创建阶段:
    创建组件对象,以及模型对象data
    2个钩子函数:
    beforeCreate() 创建对象前触发
    created() 创建对象和data数据后触发
    data 可以axios发送ajax请求
    没有虚拟DOM 暂时不能操作DOM元素

  2. mount: 挂载阶段
    生成虚拟DOM树,绑定数据到真实的DOM树上
    beforeMount() 挂载阶段开始前自动触发
    mounted() 挂载后自动触发
    data 可以axios发送ajax请求
    有虚拟DOM,可执行DOM操作

  3. update: 更新阶段
    当组件的模型数据被更新时自动触发
    beforeUpdate()
    updated()

  4. destroy: 销毁阶段
    除非调用专门的destroy函数,才能触发destroy阶段
    beforeDestroy()
    destoryed()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值