一、组合式API
- 什么是组合式API? 
  - vue3中支持vue2的选项式、支持新的编程模式–函数式编程(没有this指针)
- 做了一个兼容,可以在一个组件中使用函数式编程和OOP编程(选项式)
 
setup()函数
- 可以使用setup属性来实现函数式编程
- 内部直接编写任意代码,可以直接调用,不存在块作用域(方法必须写在methods中)
- setup中不可以使用外边data数据,定义响应式数据–关联对象–必须使用ref函数来定义(如果是使用ref定义的变量,那么直接使用)
 //如果是使用ref定义的变量,那么直接使用,并且获取值需要使用.value属性获取
                    console.log('函数式编程', name.value);
- 定义响应式数据–关联对象–必须使用ref函数来定义
  //定义响应式数据--关联对象--必须使用ref函数来定义
                const name =Vue.ref('画虎')
- ref赋值,不能够直接给数据赋值,只能给数据的.value赋值
setName() {
                        //ref赋值,不能够直接给数据赋值,只能给数据的.value赋值
                        name.value = 'dada'
                    }
- 获取节点 
  -  1、定义一个空的ref对象 
-  2、这个对象的名字必须和dom节点上的ref属性名字一致 
  
-  3、必须导出这个ref对象 
  
 
-  
- 因为ref是关联对象,所以vue3给出了另外一个定义响应式数据的函数–reactive
- ref定义的是一个数据ref对象,reactive定义的是一个对象
- 所以reactive相当于之前的data属性
<body>
    <div id="root" class="container">
        <div class="panel panel-primary">
            <div class="panel-heading">
                  <h3 class="panel-title">Panel title</h3>
            </div>
            <div class="panel-body">
                <div class="form-group">
                    <label for="">用户名字</label>
                    <input ref="node" type="text" class="form-control" v-model="name" placeholder="Input field">
                </div>
                <div class="form-group">
                    <label for="">登录次数</label>
                    <input ref="node" type="text" class="form-control" v-model="obj.count" placeholder="Input field">
                </div>
                <div class="form-group">
                    <label for="">只读的值</label>
                    <input ref="node" type="text" class="form-control" v-model="readValue" placeholder="Input field">
                </div>
                <button type="submit" @click="showName" class="btn btn-primary">获取值</button>
                <button type="submit" @click="setName" class="btn btn-primary">赋值</button>
                <button type="submit" @click="getNode" class="btn btn-primary">获取节点</button>
            </div>
            
            <panel :count="obj.count"><panel/>
            
      </div>
        
    </div>
    <script>
        const Panel = {
            template: `
                <div class="panel panel-warning">
                    <div class="panel-heading">
                            <h3 class="panel-title">Panel title</h3>
                    </div>
                    <div class="panel-body">
                           获取父组件传递的数据{{mycount}}
                    </div>
                </div>
            `,
           // 如果涉及组件props传参,还是要用props属性接收数据和定义数据
           props: {
                count: Number
            },
            setup(props) {
                /* 如果在setup钩子函数中要使用props的数据,必须先使用props定义和接收数据,然后通过setup参数获取数据 */
                console.log(props)
                //如果要修改数据
                const mycount = Vue.ref(props.count * 10)
                return {
                    mycount
                }
            }
        }
        Vue.createApp({
            // 组件注册,还是使用components属性
            components: {
                'panel':Panel
            },
            // 可以使用setup属性来实现函数式编程
            // 内部直接编写任意代码,可以直接调用,不存在块作用域(方法必须写在methods中)
            setup() {
                 如果定义的方法,dom节点需要使用,必须进行导出--return
                function showName() {
                    //setup中不可以使用外边的data数据
                    //如果是使用ref定义的变量,那么直接使用,并且获取值需要使用.value属性获取
                    console.log('函数式编程', name.value)
                    console.log('获取reactive的值', obj.count)
                    console.log('获取redonly的值', readValue);
                }
                //定义响应式数据--关联对象--必须使用ref函数来定义
                const name =Vue.ref('画虎')
                //获取节点:
                // 1、定义一个空的ref对象
                // 2、这个对象的名字必须和dom节点上的ref属性名字一致
                // 3、必须导出这个ref对象
                const node = Vue.ref()
                function getNode() {
                    console.log(node.value)
                    //
                }
                /**
                 * + 因为ref是关联对象,所以vue3给出了另外一个定义响应式数据的函数--reactive
                    + ref定义的是一个数据ref对象,reactive定义的是一个对象
                    + 所以reactive相当于之前的data属性
                */
                const obj = Vue.reactive({
                    count:1
                })  
                
                /** 定义只读数据 */
                const readValue = Vue.readonly(10000)
                return {
                    name,
                    node,
                    obj,
                    readValue,
                    showName,
                    setName() {
                        //ref赋值,不能够直接给数据赋值,只能给数据的。value赋值
                        name.value = 'dada'
                    },
                    getNode
                }
            }
        })
        .mount('#root')
        
    </script>
</body>
</html>
函数式编程组件传值
- 组件注册,还是使用components属性
 // 组件注册,还是使用components属性
            components: {
                'panel':Panel
            },
- 如果涉及组件props传参,还是要用props属性接收数据和定义数据
 // 如果涉及组件props传参,还是要用props属性接收数据和定义数据
           props: {
                count: Number
            },
- 如果再setup钩子函数中要使用props的数据,必须使用props选项来定义数据,然后在setup钩子函数中使用形参来接收数据
setup(props) {
                /* 如果在setup钩子函数中要使用props的数据,必须先使用props定义和接收数据,然后通过setup参数获取数据 */
                console.log(props)
                //如果要修改数据
                const mycount = Vue.ref(props.count * 10)
                return {
                    mycount
                }
            }
生命周期钩子函数
- setup钩子函数要早于beforeCreate生命周期,并且它实现了方法和数据定义所以setup可以理解为创建生命周期
- 因此setup钩子函数中如果要实现生命周期,那么没有创建生命周期,只有挂载、更新、卸载
- 所以vue3的生命周期钩子函数有6个:onBeforeMount、onMounted、onBeforeUpdate、onUpdated、onBeforeUnmount、onUnmounted
- 四个阶段,每一个阶段分为之前之后,vue3中提供了两种写法,选项式和钩子函数式,在setup中没有创建生命周期,因为setup限于创建生命周期而执行,所以可以把setup当创建生命周期使用
  



















