四种写法 1.

<template>
    <div>
        <h1>组件1</h1>
        <button @click='count++'>+1</button>
        <button @click='count--'>-1</button>
        <br />
        <button @click='add()'>+1</button>
        <button @click='sub()'>-1</button>
        <h2 :style='styles.box' v-text='count'></h2>
        <p :style='styles.box' class='box'>测试文字</p>
    </div>
</template>

<script setup>
    import { ref, useCssModule } from 'vue'
    let count = ref(0)
    const styles = useCssModule()
    // 这里必须加value 因为被ref修饰之后就是一个引用数据类型(所有的响应式变量都是引用数据类型)
    const add = () => {
        console.log(count, typeof count)
        count.value++
    }
    const sub = () => count.value--

</script>

<style scoped>
    .box {
        color: #fff;
        background: red;
    }
</style>
<template>
    <hr />
    <h1>组件2</h1>
    <button @click='change'>+2</button>
    <button @click='change(-1)'>-1</button>
    <h1 v-text='count'></h1>
</template>

<script> 
// 在script内部的代码是JS代码,在setup中 访问或修改响应式变量时用. value来访问。
// 简单记忆:如果一个声明变量能用this访问, 就不加.value;反之。。。
// 在template视图模板中,访问或修改响应式变量时不要加.value,指令会自动访问变量的.value。
import { ref } from 'vue'
export default {   
    // 新增的选项,有两个参数 (上下文,props) -- 自动执行 相当于当前组件的入口函数
    setup(props, ctx){
        let count = ref(0)
        const change = (step)=> count.value += step
        return {
            count,
            change
        }
    },
    // 使用这种方式写 可以使用2.0 的写法
    methods:{
        change(step){
            console.log(this)
        }
    }
}
</script>


<style scoped>

</style>
<template>
    <!-- <div>
        <h1>组件3</h1>
        <h3 v-text='count'></h3>
        <button @click='add()'>+1</button>
        <button @click='sub()'>-1</button>
    </div> -->
</template>

<script>
    import { ref, defineComponent,h } from 'vue'
    

    // export default defineComponent({
    //     setup(props, ctx){
    //         let count = ref(0)

    //         const add = () => {
    //             count.value++
    //         }
    //         const sub = () => count.value--

    //         return ()=> h(
    //             'div',
    //             {},
    //             [
    //                 h('hr',{},''),
    //                 h('h1',{},'组件3'),
    //                 h('h3',{},count.value),
    //                 h('button',{onclick:add},'+1'),
    //                 h('button',{onclick:sub},'-1'),
    //             ]
    //         )
    //     }
    // })
    export default defineComponent(()=>{
        let count = ref(0)

        const add = () => {
            count.value++
        }
        const sub = () => count.value--

        // return 一个渲染函数
        return ()=> h(
            'div',
            {},
            [
                h('hr',{},''),
                h('h1',{},'组件3'),
                h('h3',{},count.value),
                h('button',{onclick:add},'+1'),
                h('button',{onclick:sub},'-1'),
            ]
        )
    })

</script>

<style scoped>
    .box {
        color: #fff;
        background: red;
    }
</style>
// jsx 语法中需要返回render函数
import { defineComponent, ref, triggerRef } from 'vue'


// export default {
//     setup(props, ctx){
//         console.log(props);
//         let count = ref(0)
//         let sub = ()=>count.value--
//         let add = ()=>count.value++
//         return ()=>(
//             <div>
//                 <hr></hr>
//                 <h1>组件4</h1>
//                 <h2>{count.value}</h2>
//                 <button onClick={add}>+1</button>
//                 <button onClick={sub}>-1</button>
//             </div>
//         )   
//     }
// }



// export default (props, ctx)=>{
//     console.log(props, ctx)
//     let count = ref(0)
//     let sub = ()=>count.value--
//     let add = ()=>count.value++
//     return (
//         <div>
//             <hr></hr>
//             <h1>组件4</h1>
//             <h2>{count.value}</h2>
//             <button onClick={add}>+1</button>
//             <button onClick={sub}>-1</button>
//          </div>
//     )
// }


export default defineComponent((props, ctx)=>{
    let count = ref(0)
    let sub = ()=>count.value--
    let add = ()=>count.value++
    
    // 函数写法  返回函数
    return ()=>(
        <div>
            <hr></hr>
            <h1>组件4</h1>
            <h2>{count.value}</h2>
            <button onClick={add}>+1</button>
            <button onClick={sub}>-1</button>
         </div>
    )
})

vue 最佳实践:

常规写法:

// 组合:替换cmputed ,methods 等

<template>
    <div>
        <h1>TODO LIST</h1>
        <input type='text' v-model='task' />
        <button @click='add'>
            添加
        </button>
        <div>
            <li v-for='item in list'>
                {{item.id}}---{{item.task}}
                <button @click='remove(item)'>
                    删除
                </button>
            </li>
        </div>

    </div>
</template>

// 关注点分离
<script>
import { computed, ref } from 'vue'
function useTodo(arg){
    let list = ref([])
    let task = ref(arg)
    const add = ()=>{
        list.value.push({
            id:Math.random()*100,
            task:task.value
        })
        task.value = ''
    }

    const remove = (item)=>{
        list.value = list.value.filter(ele=>item.id!=ele.id)
    }

    const length = computed(()=>{
        return list.value.length
    })

    return {
        list,
        task,
        remove,
        add,
        length
    }
}
</script>

<script setup>
    const { list, task, length, add, remove } = useTodo('')
    // ...
</script>

<style>

</style>

jsx写法:

import { defineComponent, ref, computed } from 'vue'



export default defineComponent((props, ctx)=>{
    // 也可以像todo.vue一样使用use函数封装
    let list = ref([])
    let task = ref('')
    let length = computed(()=>list.value.length)
    
    const add = ()=>{
        list.value.push({
            id:Math.random()*100,
            task:task.value
        })
        task.value = ''
    }
    

    const remove = (item)=>{
        list.value = list.value.filter(ele=>item.id!=ele.id)
    }


    
    return ()=>(
        <div>
            <h1>TODO LIST</h1>
            <input type='text' value={task.value} onChange={(e)=>task.value = e.target.value}/>
            <button onClick={()=>add()}>
                添加
            </button>
            <div>
                {
                    list.value.map(ele=>{
                        return(
                            <li>
                                {ele.id} --- {ele.task}
                                <button onClick={()=>remove(ele)}>
                                    删除
                                </button>
                            </li>
                        )
                    })
                }
                
            </div>
            <hr />
            <h3>任务数量:{length.value}</h3>
        </div>
    )    
})