Vue全解: 构造选项(基础)

创建一个 Vue 实例

  • Vue 是一个构造函数,对其使用 new 操作符,就得到了一个 Vue 的实例。
    const vm = new Vue(options) 
    // or
    new Vue(options)
复制代码
  • vm 对象封装了对视图的所有操作,包括数据读写事件绑定DOM 更新
    • vm 的构造函数是 Vue,按照 ES6 的说法,vm 所属的类是 Vue。
    • options 是 new Vue 的参数,一般称之为选项或者构造选项

vue 的响应式原理

  • 当我们把 options.data 传给 Vue 之后:
    • data 会自动被 Vue 监听(getter 、setter)
    • data 会被 Vue 的实例(vm)代理
    • 每次对 data 的读写都会被 Vue 监控
    • Vue 会在data 变化时更新 UI

options 构造选项

  • Vue 中文搜索 选项(英文搜 options),会列出 options 的五个大类,点击其中一个,即可得到所有相关文档。

文档链接

DOM

  • el(挂载点)
    • 用来指定数据的挂载位置,它的蚕食可以是 CSS 选择器,可以用 $mount 代替
        const Vue = window.Vue
        new Vue({
            el: '#app'
        })
        // 用 $mount 代替
        new Vue({
        
        }).$mount('#app')
    复制代码

数据

  • data(内部数据)
    • data 支持对象和函数,请优先使用函数
    • 可以简单理解为防止组件复用造成的内部数据共享
        const Vue = window.Vue
        new Vue({
            data: {
                n: 0
            }
            // or
            data(){
                return {
                    n: 0
                }
            }
        }).$mount('#app')
    复制代码
  • methods(方法)
    • methods包含了所有事件处理函数或者是普通函数
        const Vue = window.Vue
        new Vue({
            data(){
                return { 
                   n: 0,
                   array: [11, 22, 33, 44]
                }
            },
            template: `
                <div id="demo">
                    {{n}}
                    <button @click="add"> + 1 </button>
                 {{filter()}}   
                </div>
            `,
            methods: {
                add(){
                    this.n++
                },
                // 页面中主动调用函数,每次渲染都会自动执行
                filter(){
                    return this.array.filter(i => i % 2 === 0)
                }
            }
        }).$mount('#app')
    复制代码
  • props(外部属性)
    • 不同于 data 的内部数据,允许从外部传入数据,传入的数据会自动绑定到 this
    • 声明:
        // demo.vue
        <template>
            {{message}}
            <button @click="fn">+1</button>
        </template>
        
        <script>
            export default{
                props: ['message','fn']
            }
        </script>
        <style scoped></style>
    复制代码
    • 使用:从外部传入一组 key = value
        // main.js
        const Vue = window.Vue
        import Demo from './demo.vue'
        new Vue({
            components:{Demo},
            template:`
                <div>
                    <Demo message="外部数据">
                <div>
            `,
        }).$mount('#app')
        
    复制代码
    • 传入变量或者函数:
        // main.js
        const Vue = window.Vue
        import Demo from './demo.vue'
        new Vue({
            data(){
                return {
                    n: 0
                }
            }
            components:{Demo},
            template:`
                <div>
                    {{n}}
                    <Demo :message="n" :fn="add" />
                <div>
            `,
           methods: {
               add(){
                   this.n++
               }
           }
        }).$mount('#app')
        
    复制代码
  • computed(计算属性)
    • computed 包含所有用于返回计算处理后的、可复用的属性的方法,有点绕,看下面例子
      1. 展示用户的昵称或者电话或者邮箱,要求优先展示昵称
        new Vue({
            data(){
                return {
                    user: {
                        nickname: 'aaa',
                        email: 'bbb@b.com',
                        phone: 'ccc'
                    }
            },
            template: `
                <div>
                    {{ user.nickname || user.email || user.phone }}
                </div>
            `
        }).$mount('#app')
    复制代码
    • 以上需求如果被复用多次,一旦需求改变(如优先展示邮箱),代码将难以维护
    • 用 computed 处理
        new Vue({
            data(){
                return {
                    nickname: 'aaa',
                    email: 'bbb@b.com',
                    phone: 'ccc'
                }
            },
            computed: {
                // 只读的
                displayName() {
                    const user = this.user
                    return user.nickname || user.email || user.phone
                }
                // or 可读写的
                displayName: {
                    get: function() {
                        const user = this.user
                        return user.nickname || user.email || user.phone
                    },
                    ser: function(value) {
                       // this.user.nickname = value
                    }
                }
            },
            template: `
                <div>
                    {{displayName}}
                </div>
            `
        )}
    复制代码
    • 无论需求怎么变,只要修改 computed 属性里的方法就可以了
  • watch(监听 / 侦听)
    • 当数据变化时,执行一个函数
    • 使用 watch 实现撤销
        new Vue({
            data(){
                return {
                    n: 0,
                    history:[],
                    isUndoMode: false
                }
            },
            watch: {
                if(!inUndoMode) {
                    n(newValue, oldvalue){
                        this.history.push({from: oldValue, to: newValue})
                    }
                }
            },
            template: `
                <div>
                    {{n}}
                    <br>
                    <button @click="add">+1</button>
                    <button @click="minus">-1</button>
                    <br>
                    <button @click="undo">撤销</button>
                    <br>
                    {{history}}
                </div>
            `,
            methods:{
                add(){
                    this.n++
                },
                minus(){
                    this.n--
                },
                undo(){
                    const last = this.history.pop()
                    if (last) {
                        this.n = last.from
                    }
                    this.isUndoMode = true
                    this.$nextTick(() => { // watch 是异步的
                        this.inUndoMode = false
                    }, 0)
                }
            }
        }).$mount('#app')
    复制代码
    • watch 的 deep 属性 (深度监听)
      • watch 在监听数据变化时,如果监听的是简单数据类型,如果值变化,则视为变化,如果监听复杂数据类型,如果对象的地址变化,则视为变化,如果对象里属性的值变化,而对象的地址没变,则视为无变化。
      • 修改 deep 属性的值为 true 可以改变这一点
          ...
          watch: {
              obj: {
                  handle(){...},
                  deep: true
              }
          }
          ...
      复制代码
  • watchcomputed 的区别
    • computed 计算属性
    1. 支持缓存,只有依赖数据发生改变,才会重新进行计算
    2. 不支持异步,当 computed 内有异步操作时无效,无法监听数据的变化
    3. computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于 data 中声明过或者父组件传递的 props 中的数据通过计算得到的值
    4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用 computed
    5. 如果 computed 属性属性值是函数,那么默认会走 get 方法;函数的返回值就是属性的属性值;在 computed 中的,属性都有一个 get 和一个 set 方法,当数据变化时,调用 set 方法。
    • watch 监听
    1. 不支持缓存,数据变,直接会触发相应的操作
    2. 支持异步
    3. 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值
    4. 当一个属性发生变化时,需要执行对应的操作;一对多
    5. 监听数据必须是 data 中声明过或者父组件传递过来的 props 中的数据,当数据变化时,触发其他操作,函数有两个参数
      • immediate:组件加载立即触发回调函数执行
      • deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep 无法监听到数组的变动和对象的新增,参考 vue 数组变异,只有以响应式的方式触发才会被监听到

资源

  • components(组件)
    • Vue 组件有三种定义方式
    1. 单独创建一个 vue 文件 demo.vue
        <template>
            <div id="demo">
                {{n}}
                <button @click="add">+1</button>
            </div>
        </template>
        
        <script>
            export default{
                data(){ return { n:0 } },
                methods:{
                    add(){ this.n++ }
                }
            }
        </script>
        
        <style scoped>
            ...
        </style>
    复制代码
    • 引入组件,使用组件
        const Vue = window.Vue
        // 注意路径
        import demo from './demo.vue'
        new Vue({
            // 使用
            components: { demo },
            template: `
                <div>
                    <demo />
                <div>
            `
            ...
        }).$mount('#app')
    复制代码
    1. 或者使用 component 函数,直接定义组件。函数的第一个参数接收组件的名字,第二个参数和 options 完全一样
        const Vue = window.Vue
        Vue.component('demo',{
            template: `
                <div> content <div>
            `
        })
        new Vue({
            // 使用
            template: `
                <div>
                    <demo />
                <div>
            `
            ...
        }).$mount('#app')
    复制代码
    1. 第三种
        const Vue = window.Vue
        new Vue({
            // 定义
            components: {
                newDemo: {
                    template: `
                        <div> content <div>
                    `
                }
            }
            // 使用
            template: `
                <div>
                    <newDemo />
                <div>
            `
            ...
        }).$mount('#app')
    复制代码

生命周期钩子

  • 钩子可以简单理解为程序执行的某个重要节点,可以使用这些方法来做一些事情。
    • beforeCreatecreated(不会出现在页面中)
        const Vue = window.Vue
        new Vue({
            ...
            created(){
                console.log('内容创建了')
            }
        })
    复制代码
    • beforeMountmounted(会出现在页面中)
        const Vue = window.Vue
        new Vue({
            ...
            mounted(){
                console.log('页面展示了')
            }
        })
    复制代码
    • beforeUpdateupdated(数据更新触发)
        const Vue = window.Vue
        new Vue({
            ...
            updated(){
                console.log('数据更新了')
            }
        })
    复制代码
    • beforeDestroydestroyed(数据从页面中消失)
        const Vue = window.Vue
        new Vue({
            ...
            destroyed(){
                console.log('数据消亡了')
            }
        })
    复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享