hooks思想


//1.将ref函数从vue当中导入
import { ref ,reactive } from "vue";
// initVal 初始值
const useCount = (initVal) => {
  //2.把一个值类型 进行ref的包装
  const pages = reactive([]);
  const count = ref(initVal);
  // 4.函数
  const submit = (val) => {
    if (typeof val === "number") {
      count.value += val;
    } else {
      console.error("val必须是一个数字");
    }
  };
  return [count, submit];
};


export default {
  setup() {
    const [count, submit] = useCount(0);
    // 3.把想在外面进行的渲染的数据,通过return导出
    return {
      count,
      submit,
    };
  },
}; 

methods

  • setup中执行方法

方式一

  • 以reactive定义响应式数据的方式来定义方法

<script>
import {ref, reactive,toRefs} from "vue";

export default {
  name: "test",
  setup(){

    const str = ref('inline')

    const fun = reactive({
      fun1(data){
        console.log(str.value)
        this.fun2(data)
      },
      fun2(data){
        console.log(data)
        console.log('我是fun2')
      }
    })

    return{
      ...toRefs(fun),
    }
  }
}
</script>

<button @click="fun1('abccd')">abcdd</button>

  • 通过点击事件将值传给fun1fun1接收到后在传给fun2

  • 这里this.fun2()方式去调用fun2,为什么这里用this可以正常执行不会报undefind

  • 因为这里的this非彼this,Vue2里的this实例, 这里的this是对象

避免了将功能逻辑都堆叠在setup的问题,可以将独立的功能写成单独的函数

  • setup外写了fun() login()两个功能函数,并在setup内分别调用

import {ref, reactive,toRefs} from "vue";

  export default {
    name: "test",
    setup(){

      const test1 = fun()      // 如果函数返回参数过多,可以赋值给变量并用扩展运算符暴露给组件的其余部分

      const { test } = login() // 也可单个接收

      return{
        ...toRefs(test1),
        test,
      }
    }
  }

    // 功能1
    function fun(){
    let str = ref('我是功能1')
    function fun1(data){
        console.log(str.value)
        fun2(data)
    }
    function fun2(data){
        console.log(data)
    }
    return{
        fun1,
        fun2,
    }
    }

    // 功能2
    function login() {

        const obj = reactive({
            msg:'我是功能2'
        })

        function test() {
            console.log(obj.msg)
        }

        return{ test  }
    }
</script>

包裹对象参数方法

  • 定义一个 reactive响应式对象,赋值给login变量,这个响应式对象内有我们登录需要的参数、验证和方法

  • 这里我们全部放在 login这个响应式对象内然后用toRefs及扩展运算符暴露出去

<script>
import {ref, reactive,toRefs} from "vue";

export default {
  name: "test",
  setup(){
    const login = reactive({
      param: {
        username: '123',
        password: '123456',
      },
      rules: {
        username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
        password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
      },
      login(){
        this.param.username = 'inline'
        this.param.password = '123456'
        console.log('成功登录!')
      }
    })

    return{
      ...toRefs(login),
    }
  }
}
</script>
 
<!-- ###使用一下 -->

<input type="text" v-model="param.username">
<input type="password" v-model="param.password">
<button @click="login">登录</button>

<!-- 正常执行, 将一个功能的所有方法和相关参数写在一个reactive对象内
 -->

setup 语法糖

<!-- 导入的组件无需注册,可直接使用  -->
<script setup>
  // 导入的组件也可以直接在模板中使用
  import Foo from './Foo.vue'
  import { ref } from 'vue'

  // 编写合成API代码,就像在正常设置中一样
  // 不需要手动返回所有内容
  const count = ref(0)
  const inc = () => {
    count.value++
  }
</script>

<template>
  <Foo :count="count" @click="inc" />
</template>


<!-- 发布Props和Emits -->
<script setup>

  const props = defineProps({
    foo: String
  })
  
  const emit = defineEmits(['update', 'delete'])
</script>

setup使用组件


<script setup>
import MyComponent from './MyComponent.vue'
</script>

<template>
  <MyComponent />
</template>

使用自定义指令​

全局注册的自定义指令将正常工作。本地的自定义指令在 <script setup> 中不需要显式注册,但他们必须遵循 vNameOfDirective 这样的命名规范:

<script setup>
const vMyDirective = {
  beforeMount: (el) => {
    // 在元素上做些操作
  }
}
</script>
<template>
  <h1 v-my-directive>This is a Heading</h1>
</template>

如果指令是从别处导入的,可以通过重命名来使其符合命名规范:

<script setup>
import { myDirective as vMyDirective } from './MyDirective.js'
</script>