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>
通过点击事件将值传给
fun1
,fun1
接收到后在传给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>