Vue2

作者: 追风还是少年 | 来源:发表于2023-11-07 23:19 被阅读0次

    let、var、const

    (1) var
    在 ES6 出现之前,var 声明占主导地位。但是,使用 var 声明的变量存在一些问题。

    • var 声明的作用域是全局的或函数/局部的
      当 var 变量在函数外部声明时,作用域是全局的。这意味着在函数体外用 var 声明的任何变量都可以在整个窗口中使用。
      var 在函数中声明时,它的作用域是在函数体内。这意味着它只能在该函数中被访问。
    • var 变量可以重新声明和更新
      这意味着我们可以在相同的作用域内执行此操作,并且不会出错。
    var greeter = "hey hi";
    var greeter = "say Hello instead";
    
    var greeter = "hey hi";
    greeter = "say Hello instead";
    
    • var 的提升
    console.log (greeter);
    var greeter = "say hello"
    

    解释为

    var greeter;
    console.log(greeter); // greeter is undefined
    greeter = "say hello"
    
    • val的问题
    var greeter = "hey hi";
    var times = 4;
    
    if (times > 3) {
        var greeter = "say Hello instead"; 
    }
    
    console.log(greeter) // "say Hello instead"
    

    (2) let

    • let 是块作用域
       let greeting = "say Hi";
       let times = 4;
    
       if (times > 3) {
            let hello = "say Hello instead";
            console.log(hello);// "say Hello instead"
        }
       console.log(hello) // hello is not defined
    
    • let 可以更新但不能重新声明
    let greeting = "say Hi";
    greeting = "say Hello instead"; // error: Identifier 'greeting' has already been declared
    

    但是,如果同一个变量定义在不同的作用域,就不会报错

    let greeting = "say Hi";
    if (true) {
        let greeting = "say Hello instead";
        console.log(greeting); // "say Hello instead"
    }
    console.log(greeting); // "say Hi"
    

    就像 var 一样,let 声明被提升到顶部。与初始化为 undefined 的 var 不同,let 关键字未初始化。所以如果你在声明之前尝试使用 let 变量,你会得到一个 Reference Error。

    (3) const
    与 let 声明一样,const 声明只能在它们声明的块内访问。
    每个 const 声明都必须在声明时进行初始化。
    const 不能更新或重新声明。

    const greeting = "say Hi";
    greeting = "say Hello instead";// error: Assignment to constant variable. 
    
    const greeting = "say Hi";
    const greeting = "say Hello instead";// error: Identifier 'greeting' has already been declared
    
    const greeting = {
            message: "say Hi",
            times: 4
        }
    greeting = {
        words: "Hello",
        number: "five"
    } // error:  Assignment to constant variable.
    
    greeting.message = "say Hello instead"; //这样是允许的
    

    === 与 =

    • ===
      严格相等(三个等号)
      比较两个操作数时,如果类型不同,就一定不相等
      (1)如果两个都是字符串,每个位置的字符都一样,那么相等,否则不相等
      (2)如果两个值都是true,或是false,那么相等
      (3)如果两个值都引用同一个对象或是函数,那么相等,否则不相等
      (4)如果两个值都是null,或是undefined,那么相等
    • ==
      宽松相等(两个等号)
      比较两个操作数时
      如果两个类型不同,双等号(==)将执行类型转换,有可能会返回相等
      (1)如果一个是null,一个是undefined,那么相等
      (2)如果一个是字符串,一个是数值,把字符串转换成数值之后再进行比较

    Vue Chrome浏览器调试插件Devtools

    // 开发环境,包含完整的警告和调试模式
    <script type="text/javascript" src="./js/vue.js"></script>
    // 生成环境
    <script type="text/javascript" src="./js/vue.min.js"></script>
    

    容器与vue绑定

    <input id = "root" v-bind:value="name"></input>
    <input id = "root2" v-model:value="age"></input>
    <script>
    vm = new Vue({
      el: '#root2',
      data: {
        name: '简书',
        age: 18
      }
    })
    
    vm2 = new Vue({
      el: '#root2',
      data: {
        name: '简书',
        age: 18
      }
    })
    <script>
    
    //容器与vue是一 一绑定,即多个vue对象不能绑定同一个容器
    //(1) root输入框容器与vue单向绑定,即vue的data数据更新会同步更新到容器,而容器的输入值修改不会同步更新到vue的data数据
    //(2) root2输入框容器与vue双向绑定,即vue的data数据更新会同步更新到容器,容器的输入值修改也会同步更新到vue的data数据
    

    <div id = 'root'>{{name}}<div>
    var data =  {
        name: '简书',
        age: 18,
      }
    vm = new Vue({
      data: data,
      method: {
        showinfo: funtion(){
          console.log(this) //this为 vue对象
        },
        //showinfo(){ //简写方式
        //}
        //showinfo: ()=>{ //箭头函数
        // console.log(this) //this不为vue对象,为windows
        //}
      },
      created: function () {
         // `this` 指向 vm 实例
        console.log('a is: ' + this.a)
     }
    })
    // 实例化vue对象时没有绑定容器,而是实例化之后进行绑定
    vm.$mount('#root')
    vm._data === data
    vm.name == data.name
    

    插值法与指令语法

    • 插值法
      {{name}},用于html标签体,即<div>{{name}}</div>
    • 指令语法
      v-bind 指令,用于标签属性,v-bind:可以简写为:, 如 v-bind:value,可以简写为:value
      v-model 指令,用于表单类型元素,如 v-model:value,可以简写为v-model
      v-if 指令, <p v-if='seen'>现在你看到我了</p>,当seen=true时,才展示
      v-else-if指令、v-else
      v-for 指令, <li v-for='book in books'>{{book}}</li>
      v-on 指令,可以简写为@,如 v-on:click,可以简写为@click
      v-show指令,控制是否显示,映射样式的display 如:style='display:none'
      v-text指令,<div v-text='name'>这里输入内容失效</div>与<div>{{name}}</div>等价,如果name='<h1>test</h1>' v-text不解析html标签,内容原样显示

    v-html指令,作用v-text差不多,与v-text区别,v-html指令会解析内容里面的标签

    <template v-if><h1>aa</h1></h2>bb</h2></template> 模版与v-if配合

    vm = new Vue({
      el: '#root',
      data: {
        name: '简书',
        age: 18,
        seen: true
        books: ['book1','book2']
      }
    })
    

    修饰符:

    // .prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault(),即只执行事件处理函数,不提交到服务器端
    <form v-on:submit.prevent="onSubmit">...</form>
    

    绑定class样式

    :class属性值由vue解析出来的样式会与class属性定义的样式合并

    <div id = 'root'>
      <div class = 'basic' :class='style' @click='changStyle'>test</div>
     //<div class = 'basic' :class="['normal','happy']" >test2</div>
     <div class = 'basic' :class='arr' @click='changStyle2'>test2</div>
    <div class = 'basic' :class='classObj' >test3</div>
    <div class = 'basic' :style='styleObj' >test4</div>
    <div>
    <script>
    vm = new Vue({
      el: '#root',
      data: {
        name: '简书',
        age: 18,
        style: 'normal',
        arr: ['style1','style2'],
        classObj: {
          'normal': true,
          'happy': false
        },
        styleObj:{
          fontSize: '40px'
        }
      },
      methods:{
        changStyle(){
          this.style = 'happy'
        },
        changStyle2(){
          this.arr.shift()
        }
      }
    })
    </script>
    

    computed计算属性

    计算属性会缓存,get函数什么时候调用?1、初次读取计算属性时,2、当依赖的属性发生变化时候,get函数会重新调用
    计算属性使用{{fullName}}

    computed:{
      fullName: {
        get(){
        }
        set(){
        }
      }
    }
    
    当计算属性只有get函数时,简写为下面形式:
    computed:{
      fullName(){
      }
    }
    

    style scope

    组件的style加 scope防止组件定义的class样式与其它组件的class名称相同导致冲突

    <style scope>
    </style>
    

    app组件的style一般不会定义为scope,这里定义的class样式为所有组件共享的样式

    语言默认为css,如果要使用less,需要配置lang='less',使用前需要npm -i less-loader@7(不加版本,默认是最新的,最新的less是需要配合webpack的5版本)

    <style lang='less'>
    </style>
    

    :key 唯一标识(虚拟DOM,Vue使用,在真实DOM中不存在)

    自定义指令

    <div id= root>
        <h2>{{name}}</h2>
        <h2>当前n的值<span v-text="n"></span></h2>
        <h2>放到十倍后的值<span v-big="n"></span></h2>
    </div>
    <script>
    vm = new Vue({
      el: '#root',
      data: {
        name: '简书',
        age: 18,
        n: 1
        },
       directives:{
          // big函数何时会被调用 1、指令与元素成功绑定时 2、指令所在模版被重新解析(有变量变化就会引起模版解析)
          big(element, binding){
            element.innerText = binding.value*10
          },
          fbind: {
           // 指令与元素成功绑定
            bind(element, binding){
              element.innerText = binding.value
            },
            // 指令所在元素被插入页面
            inserted(element, binding){
              element.foucus()
            },
            // 指令所在模版被重新解析
            updated(element, binding){
              element.innerText = binding.value
            }
          }
       }
    })
    </script>
    

    表单

    // 修饰符阻止默认行为,不提交调整了
    <form @submit.prevent='showInfo'>
    <input type='text' v-model.trim='username'/>
    <input type='password' v-model='password'/>
    // number修饰符
    <input type='number' v-model.number='age'/>
    
    <input type='radio' name='sex' v-model='sex' value='male'/>
    <input type='radio' name='sex' v-model='sex' value='female'/>
    
    // 如果没有配置value属性,收集的是checked属性
    <input type='checkbox' v-model='hobby' value='study'/>
    <input type='checkbox'  v-model='hobby' value='game'/>
    
    <select v-model='city'>
      <option value=''>请选择</option>
      <option value='beijing'>北京</option>
      <option value='shanghai'>上海</option>
    </select>
    //延迟收集,失去焦点收集
    <input type='text' v-model.lazy='other'/>
    </form>
    <script>
    const vm = new Vue({
      el: '#root',
      data: {
        username: '',
        password: '',
        sex: 'male',
        hobby: [] //类型必须为数组,如果定义为'',会影响数据收集,收集的为true或false
        city: 'beijing',
        other: ''
      },
      methods:{
        showinfo(){
          alert('ok')
        }
      }
    })
    </script>
    

    组件

    实现应用中局部功能的代码和资源的集合
    非单文件组件:一个文件包含多个组件
    单文件组件:一个文件只包含一个组件(vue文件)

    1、创建组件 2、注册组件

    <div id= 'root'>
    // 使用组件
    <school></school>
    <hr>
    <student></student>
    </div>
    <script>
    const school = Vue.extend({
      // 组件不能写el,因为组件可以公用
      // el: '#root',
      template: '<div><h1>{{schoolName}}</h1><h1>{{address}}</h1></div>'
      // data只能用这种写法
      data(){
        return {
          schoolName: 'a',
          address: 'xxx'
        }
      }
    })
    
    const student= Vue.extend({
      //开发者工具呈现名字
      name: 'school',
      // 组件不能写el,因为组件可以公用
      // el: '#root',
      template: '<div><h1>{{studentName}}</h1><h1>{{age}}</h1></div>'
      // data只能用这种写法
      data(){
        return {
          studentName: 'b',
          age: 18
        }
      }
    })
    
    const vm= new Vue({
       el: '#root',
      // 局部注册
       components:{
         school: school,
         student: student
       }
    })
    
    //全局注册
    Vue.component('hello',hello)
    </script>
    
    VueComponent构造函数
    ### 数据代理
    ```javascript
    var data = { name: '简书' }
    // var data = { name: '简书' , age: 20} 直接在这里定义的sex属性默认是可以修改的
    const vm = new Vue({
      el: '#root',
      data: data
    })
    
    Object.defineProperty(data, 'age',{
      configurable: true,  // 属性是否可删除,默认为false
      writable: true, //属性值是否可以修改,默认为false
      enumerable: true, //属性key是否可枚举,默认false,类似for key in data console.log(key) 、Object.keys()不会输出sex属性
      value: 18,
      get: funtion(){ // getter
        return vm.age
      },
      set: funtion(val){ //setter
        vm.age= val
      }
    })
    

    MVVM

    image.png

    M 代表Model,即模型,plain javascript objects
    V 代表View, 即模版视图,DOM
    VM代表 View Model,Vue

    Model用纯JavaScript对象表示,View负责显示,两者做到了最大限度的分离。
    ViewModel把Model和View关联起来。ViewModel负责通过Data bindings把Model的数据同步到View显示出来,还负责通过DOM Listeners(监听view的修改)把View的修改同步回Model

    安装vue-cli

    //全局安装
    npm install -g @vue/cli
    npm config set registry https://registry.npm.taobao.org

    vue create my-project

    // 运行
    npm run serve

    babel,es6转es5

    export

    ctrl + s,更新代码

    vue核心 + 模版

    esm:es module
    common.js

    render

    new Vue({
    router,
    render: h => h(App),
    }).$mount('#app')

    vue ref

    给html元素或子组件注册引用信息

    <template>
      <h1 v-text='msg' ref='title'></h1>
    </template>
    
    <script>
    this.$refs.title
    </script>
    
    ### props
    
    <School name='张三' sex='男' age='18>
    
    
    student= {
      //开发者工具呈现名字
      name: 'school',
      //props: ['name','sex','age'] //简单接收
      /*
      props:{
        name: String,
        sex: String,
        age: Number
      },
    */
     props{
        name{
          type: String,
          required: true
        },
        sex{
          type: String,
          required: true
        },
        age{
          type: Number,
          required: true,
          default: 19
        },
      }
    }
    

    mixin 混入

    多个组件共用配置提取为一个混入对象,使用混入
    mixin.js

    export const henru1 = {
      data:{},
      methods:{},
      mounted(){
      }
    }
    

    全局混合:在app组件 import 混入 Vue.mixin(henru1) Vue.mixin(henru2)
    局部混入: 在vc的mixins:[henru1,henru2]

    插件plugin

    export default{
      install(Vue,options){
        Vue.filter(..)
        Vue.directive(..)
        Vue.mixin(..)
        Vue.prototype.$myMethod = function(){...}
        Vue.prototype.$myProperty = xxx
      }
    }
    // 传入多个参数
    Vue.use(plugins,1,2)
    

    插槽 slot

    默认插槽

    <category>
      <image src=''></image>
    </category>
    
    category组件:
    <template>
      <h1>测试</h1>
      <slot>默认</slot>
    </template>
    

    具名插槽:

    <category><image slot="center" src=''></image><a slot="footer"/></category>
    或
    <category>
      <template slot="center">//或<template v-slot:center> 只有template元素才能用这种写法
        <image src=''></image>
      </template>
    
      <a href='' slot="footer"/>
    </category>
    
    category组件:
    <template>
    <h1>测试</h1>
    <slot name="center">默认</slot>
    <slot name="footer">默认</slot>
    </template>
    

    作用域插槽:

    数据在组件,需要把数据传给使用插槽的地方
    <category>
    <template scope = '{games}'> //或者使用slot-scope 必须使用template包裹,{games}是结构赋值,如果<template scope = 'xx'>,那使用games就必须通过xx.games
    </template >
    </category>
    
    category组件:
    <template>
    <slot :games="games" msg="hello">默认</slot> //可以传多个数据给组件的使用者
    </template>
    

    $emit

    组件自定义事件

    使用组件地方
    <Student v-on:test="getName" ref="student"/>
    
    new Vue(){
      methods:{
        getName(){
        }
        mounted(){
          this.$refs.student.$on('test',this.getName);
        }
      }
    }
    
    Student组件定义:
    <h1>student组件</h1>
    <button @click="sendName"></button>
    export default {
      methods:{
        sendName(){
          this.$emit('test','xx');
        }
      }
    }
    

    也可以通过refs实现 this.off('test'); //解绑事件 this.$off(['test'])

    ...param,接收多个参数

    sync修饰符

    在父组件上告诉子组件传递过去的msg跟父组件上的n保持同步,相当于允许它修改
    <child :msg.sync='n'></child> //msg属性

    <button @click="$emit('update:msg',msg-1)">子组件点击{{msg}}</button>

    vuex

    多组件数据共享:全局事件总线实现

    vm store配置项

    action:{}、mutation: {}、state: {}

    route

    export default new VueRouter({
      router:[
        {
          path: '/about',
          component: about
        },
        {
          path: '/home',
          component: home
        }
      ]
    })
    
    <route-link to='/about' active-class='active'>
    
    <route-view></route-view>
    

    路由守卫

    {
    path: '/home',
    component: Home,
    meta: {title:'', isAuth:true}
    }

    • 全局路由守卫(针对所有路由)
      // 初始化的时候调用、每次路由被切换之前被调用
      // to代表要切换到哪个路由,from代表从哪个路由来
      router.beforeEach(to,from,next){
      //next()
      })
      // 初始化的时候调用、每次路由被切换之后被调用
      router.afterEach(to,from){
      }

    • 独享路由守卫(只有一个)
      {
      path: '/home',
      component: Home,
      // 进入之前
      beforeEnter: (to, from, next) =>{
      }
      }

    • 组件内路由守卫
      export default {
      name: 'Student',
      data(){
      return {}
      },
      // 通过路由规则,进入该组件时被调用
      beforeRouteEnter(to, from, next){
      },
      // 通过路由规则,离开该组件时被调用
      beforeRouteLeave(to, from, next){
      }
      }

    路由的两个生命周期钩子

    //组件激活
    activated(){
    }
    //组件失活
    deactivated(){
    }
    

    数据劫持

    ES6与ES5

    <script type='module'/>

    export:
    (1)分别暴露
    export function(){}
    (2)统一暴露
    export {}
    (3)默认暴露
    export default

    import:
    通用导入
    import * as m1 from ''; ////分别暴露、统一暴露、默认暴露

    解构赋值形式
    import {} from ''; //分别暴露和统一暴露
    import {default as x} from ''; //默认暴露

    简便形式:
    import x from ''; //默认暴露

    <script src='' type='module'/>

    webpack

    相关文章

      网友评论

          本文标题:Vue2

          本文链接:https://www.haomeiwen.com/subject/knvfwdtx.html