Vue复习

Vue.js是什么

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

开始

将 Vue.js 添加到项目中主要有四种方式:

  1. 在页面上以 CDN 包的形式导入。
  2. 下载 JavaScript 文件并自行托管。
  3. 使用 npm安装它。
  4. 使用官方的 CLI 来构建一个项目,它为现代前端工作流程提供了功能齐备的构建设置 (例如,热重载、保存时的提示等等)

CDN

这样会直接使用最近版本

但是对于生产环境,最好使用明确的版本号和文件,防止盲目使用最新版本造成破坏

基础的vue实列
  

   
 

也可以使用Vue.extend进行实例化

var Profile = Vue.extend({});

var app = new Profile();

app.$mount("#hello");

选项 / 数据

    • data
    • props
    • propsData
    • computed
    • methods
    • watch
data类型Object | Function

Vue 实例的数据对象Vue 会递归地把 data 的 property 转换为 getter/setter,从而让 data 的 property 能够响应数据变化。

var obj = {ele:{},num:1}

把上方这个对象放入vue实例中的data属性中会自动被处理成下方这样

Vue复习_第1张图片

getter/setter实际依赖于Object.defineProperty 这个方法

  var obj = { ele: {}, num: 1 };

      var tempAttr = "666";

      Object.defineProperty(obj, "a", {

        get() {

          console.log("获取a属性");

          return tempAttr;

        },

        set(val) {

          console.log("设置a属性");

          tempAttr = val;

        },

      });

      console.log(obj.a);

      obj.a = 1;

如果是Vue组件中使用data属性则data的值必须是Function,因为组件可能会多次调用为了保证每个组件在调用时data中的数据相互独立,所以必须用function返回一个全新的数据

 Vue.component('countBox',{

        data:{

          num:1

        },

        template:`
{{num}}
`       })       new Vue({         template:`
`,       }).$mount("#app");

 如果在组件中使用object值,则会提示下方错误

下方代码说明vue实例对data的变量是引用赋值

 

如果设置的属性只做展示不需要响应可以使用

Object.seal(obj)

或者

Object.freeze(obj)

把数据冻结起来,vue就不会自动给递归设置setter/getter了

props 类型Array | Object

props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值。

Vue.component('props-demo-simple', {

  props: ['size', 'myMessage']

})



Vue.component('props-demo-simple', {

  props: {

    // 检测类型

    height: Number,

    // 检测类型 + 其他验证

    age: {

      type: Number,

      default: 0,

      required: true,

      validator: function (value) {

        return value >= 0

      }

    }

  }

})

使用时,直接使用标签使用

  

上面是全局注册

如果要局部注册的话

 new Vue({

      components:{

        mycomponent:{

          props:['title1'],

          template:`
{{title1}}
`         }       },       template: `
`,     }).$mount("#app");

propsData 类型{ [key: string]: any }

创建实例时传递 props。主要作用是方便测试。

    new Vue({

      props:['title'],

      propsData:{

        title:"内容"

      },

      template: `
{{title}}
`,     }).$mount("#app");

只用于 new 创建的实例中

 

  new Vue({

      components:{

        mycomponent:{

          props:['title1'],

          propsData:{

            title1:"111111111111111111"

          },

          template:`
{{title1}}
`         }       },       template: `
`, }).$mount("#app");

如果不过在经过new的vue实例中使用会有下方警告

computed类型{ [key: string]: Function | { get: Function, set: Function } }

计算属性将被混入到 Vue 实例中。所有 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例

注意如果你为一个计算属性使用了箭头函数,则 this 不会指向这个组件的实例,不过你仍然可以将其实例作为函数的第一个参数来访问。

new Vue({

      data() {

        return {

          num1: 4,

          num2: 5

        }

      },

      computed: {

        calcResult() {

          return this.num1 * this.num2

        }

      },

      template: `
{{calcResult}}
`,     }).$mount("#app");

页面上展示计算后的结果20

果使{ [key: string]:  { get: Function, set: Function } } 时对computed中的属性赋值时会执行set方法,获取值的时候会执行get方法

 new Vue({

      data() {

        return {

          num1: 4,

          num2: 5

        }

      },

      computed: {

        calcResult: {

          get() {

            return this.num1 * this.num2

          },

          set(val) {

            this.num1 = val

          }

        }

      },

      template: `
{{calcResult}}
`,     }).$mount("#app");

computed对返回的结果具有缓存作用,如果其中引用的data属性没有发生变化那么下次在读取的时候会直接取之前返回的值,下方设置定时器后观察返回的打印的结果可知

 new Vue({

      data() {

        return {

          num: 1

        }

      },

      computed: {

        calcResult() {

          console.log(this.num)

          return new Date()

        }

      },

      mounted() {

        setInterval(() => {

          console.log(this.calcResult)

        }, 500)

      },

      template: `
{{calcResult}}
`,     }).$mount("#app");

Vue复习_第2张图片

methods类型{ [key: string]: Function }

methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的 this 自动绑定为 Vue 实例。

watch类型{ [key: string]: string | Function | Object | Array }

主要用来监听data的数据变化,数据变化时会自动触发绑定的监听方法,下方是几种传值类型

  data() {

        return {

          num: 1

        }

      },

 [key: string]: string

watch: {

        num: "watchNum"

      },

      methods: {

        watchNum(val, oldVal) {

          console.log(val, oldVal)

        }

      },

 [key: string]: Function

watch:{

      num(val,newVal){

        console.log(val,newVal)

      }

     },

[key: string]: Object

 watch: {

        num: {

          immediate: true,

          deep: true,

          handler(val, oldVal) {

            console.log(val, oldVal)

          }

        }

      },

[key: string]: Array

watch: {

        num: [{

          immediate: true,

          deep: true,

          handler(val, oldVal) {

            console.log(val, oldVal)

          }

        },{

          handler:"watchNum"

        },

        "watchNum1"

      ]

      },

      methods: {

        watchNum(val, oldVal) {

          console.log("function")

        },

        watchNum1(val, oldVal) {

          console.log("function1")

        }

      },

生命周期函数

生命周期是vue实例从初始化-》挂载-》更新数据和视图-》激活以及隐藏-》销毁的过程

每个过程发生时,都会触发对应的钩子函数。

生命周期函数包含下面这几种

beforeCreate

在实例初始化之后,进行数据侦听和事件/侦听器的配置之前同步调用,此时this可以获取到vue实例,但是无法调用和获取vue中的data和methods中的属性和方法

created

数据侦听和事件/侦听器的配置之后,vue实例挂载到dom之前调用,此时可以通过this访问vue实例中的一些属性,但是无法通过ref获取dom元素

beforeMount

  beforeMount() {

        console.log("beforeMount")

      },

      mounted() {

        console.log("mounted")

      },

      render(h) {

        console.log("render")

        return h("div", {}, "我是个div")

      }

在可以看出来这个生命周期函数是在vue实例上属性成功之后,render函数调用之前触发的

mounted

在render函数执行后,vue实例中的dom成功挂载到指定元素上时触发,此时可以用通过ref获取真实的dom元素,但不能保证所有子组件也挂载成功,可以用$nextTick确保可以正常获取和操作子元素

       this.$nextTick(() => {})
beforeUpdate

当有被监听的数据发生变化时并且在dom元素更新之前触发

updated

当有被监听的数据发生变化时并且在dom元素更新之后触发,此时可以获取最新状态的dom元素

 beforeUpdate() {

        console.log('beforeUpdate')

        console.log(this.$refs.myDiv.innerText)

      },

      updated() {

        console.log('updated')

        console.log(this.$refs.myDiv.innerText)

      },

      render(h) {

        console.log("render")

        return h("div", {

          ref: "myDiv",

          on: {

            click: () => {

              this.num++

            }

          }

        }, `${this.num}`)

      }

Vue复习_第3张图片

activated

被 keep-alive 缓存的组件激活时调用

deactivated

被 keep-alive 缓存的组件失活时调用。

keep-alive:在组件进行切换时,把失活的组件缓存起来

 

      

 

beforeDestroy

实例销毁之前调用。在这一步,实例仍然完全可用。可以通过this使用vue里的属性,也可以获取dom元素

destroyed

实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。

这里我们为全局挂载一个组件,根据打印的结果可以知道此时可以读取vue实例中的属性,但无法获取真实的dom元素

  Vue.component("customDiv", {

      data() {

        return {

          name: "我是待销毁的div"

        }

      },

      beforeDestroy(){

        console.log(this.name)

        console.log(this.$refs)

      },

      destroyed() {

        console.log(this.name)

        console.log(this.$refs)

      },

      template: `
{{name}}
`, }); ....   render(h) {         return h("div", {           ref: "myDiv",           on: {             click: () => {               this.num++             }           }         }, [           `${this.num}`,           this.num < 2 ?  h("customDiv") : ""         ])       } ....

Vue复习_第4张图片

Vue生命周期流程图

自定义指令

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新

componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

unbind:只调用一次,指令与元素解绑时调用。

接下来我们来看一下钩子函数的参数 (即 elbindingvnode 和 oldVnode)。

指令钩子函数会被传入以下参数:

  • el:指令所绑定的元素,可以用来直接操作 DOM。
  • binding:一个对象,包含以下 property:
    • name:指令名,不包括 v- 前缀。
    • value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2
    • oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
    • expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
    • arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
    • modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
  • vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。
  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

下方自定义一个指令

   Vue.directive('pin', {

      inserted(el, binding, vnode,oldVnode){

        console.log(el, binding)

      },

    })

    new Vue({

      data() {

        return {

          num: 1

        }

      },

      template: `
{{num}}
`,     }).$mount("#app");

Vue复习_第5张图片

此时打印结果中没有oldValue

  Vue.directive('pin', {

      update(el, binding, vnode,oldVnode){

        console.log(el, binding)

      },

    })

    new Vue({

      data() {

        return {

          num: 1

        }

      },

      computed:{

        args(){

          return 'custom' + this.num

        }

      },

      template: `
{{num}}
`,     }).$mount("#app");

Vue复习_第6张图片

如果绑定的内容更新的话就会有old数据

封装一个输入自动聚焦的指令
  Vue.directive('focus', {

      inserted(el, binding, vnode,oldVnode){

       el.focus && el.focus()

      },

    })

    new Vue({

      template: `
                 
`,     }).$mount("#app");
封装一个权限的指令
  const state = Vue.observable({

      permissions: ['add', 'edit', 'delete']

    })

    function checkPermission(permission) {

      let count = permission.length

      return state.permissions.filter(ele => permission.includes(ele)).length == count

    }

    Vue.directive('permission', {

      inserted(el, binding, vnode, oldVnode) {

        var permission = binding.value

        var hasPermission = checkPermission(permission)

        if (!hasPermission) {

          el.parentNode.removeChild(el)

        }

      },

    })

    new Vue({

      template: `
                                     
`,     }).$mount("#app");

你可能感兴趣的:(1024程序员节)