IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 17.Composition API(三)高级语法补充 -> 正文阅读

[JavaScript知识库]17.Composition API(三)高级语法补充

1.生命周期钩子

setup可以用来代替methods、data、watch等这些选项,也可以替代生命周期钩子。

可以直接导入以on开头的函数注册生命周期钩子;

import {onUpdated,onBeforeUpdate} from "vue"

然后在setup中使用函数即可:

setup() {
			onUpdated(()=>{
				console.log("updated")
			})
		}

2.Provide和inject函数

provide给子组件提供数据,一般相邻的组件传递数据使用props,不相邻组件使用provide; inject子组件接受父组件传输过来的数据。

父组件:

<template>
	<div>
		<home></home>
		<button @click="increment">app+1</button>
	</div>
</template>

<script>
	// 导入provide函数
	import {provide,ref,readonly} from "vue";
	import Home from "./Home.vue";
	export default{
		components:{
			Home
		},
		setup() {
			const name =ref("phoebe");
			const counter = ref(100);
			// 将传输数据设置为readonly模式;子组件则不能修改数据
			provide("name",readonly(name));
			provide("counter",readonly(counter))
			// 响应式使counter+1
			const increment=()=>{
				counter.value++
			}
			return{
				increment
			}
		}
	}
</script>

子组件:

<template>
	<div>
		<h2>{{name}} {{counter}}</h2>
		<button @click="homeInrement">home +1</button>
	</div>
</template>

<script>
	import {inject} from "vue";
	export default{
		setup() {
			// inject 接受传入的数据
			const name = inject("name");
			const counter =inject("counter")
			// 一般情况不能在子组件中使父组件的数据更改,不符合数据的单向传输
			// 所以要在父组件中设置传输来的数据为只读模式
			const homeInrement = ()=>{counter.value++}
			return{
				name,
				counter,
				homeInrement
			}
		}
	}
</script>

在这里插入图片描述

3.代码练习

练习1:体会compositionAPI:
将功能模块的代码提取到hook中,方便后期管理和修改;

<template>
	<div>
		<h2>{{counter}}</h2>
		<h2>{{doubleCounter}}</h2>
		<button @click="increment">+1</button>
		<button @click="decrement">-1</button>
	</div>
</template>

<script>
	// import {ref,computed} from "vue";
	import useCounter from "./hooks/useCounter.js"
	export default{
		setup() {
			const {counter,doubleCounter,increment,decrement} = useCounter();
			//提取到hooks里面
			// const counter=ref(0);
			// // 计算属性得使用computed
			// const doubleCounter = computed(()=>counter.value*2)
			// const increment = ()=> {counter.value++}
			// const decrement = ()=> {counter.value--}
			return {
				counter,
				doubleCounter,
				increment,
				decrement
			}
		}
	}
</script>

useCounter.js文件(提取的代码):

import {ref,computed} from "vue";
 export default function(){
	 const counter=ref(0);
	 // 计算属性得使用computed
	 const doubleCounter = computed(()=>counter.value*2)
	 const increment = ()=> {counter.value++}
	 const decrement = ()=> {counter.value--}
	 return {
	 	counter,
	 	doubleCounter,
	 	increment,
	 	decrement
	 }
 }

练习2:通过hook修改页面的title

useTitle.js文件:

import { ref, watch } from "vue";

export default function(title= "默认"){
	const titleRef = ref(title);
	watch(titleRef, (newvalue) =>{
		document.title=newvalue;
	},{
		immediate:true
	})
	return{
		titleRef
	}
}

App.vue:

import useTitle from "./hooks/useTitle.js"
export default{
		setup() {
// 修改title
			const titleRef =useTitle("phoebe");
			// 定时修改title
			setTimeout(() => {
				titleRef.value = "lily"
			},1000);
		}
	}

练习3:在页面右下角显示页面滚动坐标
hooks中的usescrollposition.js文件:

import {ref} from "vue"
export default function(){
	// 滚动位置
	// 默认情况下的滚动位置
	const scrollX =ref(0)
	const scrollY =ref(0)
	// 监听scoll
	document.addEventListener("scroll",()=>{
		scrollX.value=Math.round(window.scrollX)
		scrollY.value=Math.round(window.scrollY)
	})
	return{
		scrollX,
		scrollY
	}
}

App文件:

<template>
	<div>
		<p class="content"></p>
		<!-- 展示X,Y滚动坐标 -->
		<div class="scroll">
			<div class="scoll-x">scollX:{{ scrollX}}</div>
			<div class="scoll-y">scollY:{{ scrollY}}</div>
		</div>
	</div>
</template>
//....
import usescrollposition from "./hooks/usescrollposition.js"
export default{
		setup() {
		//....
		const {scrollX,scrollY} =usescrollposition();
		return{ scrollX ,scrollY}
		}
	}
<style scpode>
.content{
	width: 3000px;
	height: 4000px;
}
.scroll{
	position: fixed;
	right: 30px;
	bottom: 30px;
}
</style>

在这里插入图片描述
4.监听鼠标位置的hook

import {ref} from "vue"
export default function(){
	// 滚动位置
	// 默认情况下的滚动位置
	const mouseX =ref(0)
	const mouseY =ref(0)
	// 监听scoll
	window.addEventListener("mousemove",(event)=>{
		mouseX.value=event.pageX
		mouseY.value=event.pageY
	})
	return{
		mouseX,
		mouseY
	}
}

在App.vue引入即可:import usemouseposition from "./hooks/usemouseposition.js"
使用:const{ mouseX,mouseY} = usemouseposition()
要有返回值:return {mouseX, mouseY}

5.使用hook进行本地保存

import { ref,watch } from "vue"
export default function(key,value){
	const data = ref(value)
	if(value){
		//如果有value就是要保存数据
		window.localStorage.setItem(key,JSON.stringify(value))
	}
	else{
		// 如果没有value就是要获取数据
		data.value = JSON.parse(window.localStorage.getItem(key))
	}
	//数据发生变化,修改值后再保存
	watch(data,(newvalue)=>{
		window.localStorage.setItem(key,JSON.stringify(newvalue))
	})
	return data;
}
import uselocalstorage from "./hooks/uselocastorage.js"
//...
export default{
		setup() {
		//....
		//保存数据到本地服务器 {name:"phoebe",age:18}
			const data = uselocalstorage("info")
			// 修改数据
			const changedata = ()=> data.value="hahah "
			
			return {data,
				changedata}
		}
	}

在这里插入图片描述
这里导入有很多,可以将这些代码提取出来,在hooks文件夹中新建index.js文件:

import useCounter from "./useCounter.js"
import useTitle from "./useTitle.js"
import usescrollposition from "./usescrollposition.js"
import usemouseposition from "./usemouseposition.js"
import uselocalstorage from "./uselocastorage.js"

export {
	useCounter,
	useTitle,
	uselocalstorage,
	usemouseposition,
	usescrollposition
}

在App.vue中这样使用即可:

import {
		useCounter,
		useTitle,
		uselocalstorage,
		usemouseposition,
		usescrollposition
	} from "./hooks/index.js"

4.setup的顶级写法

<script setup>

每个 *.vue 文件最多可以包含一个 <script setup>。(不包括一般的 <script>)

这个脚本块将被预处理为组件的 setup() 函数,这意味着它将为每一个组件实例都执行。<script setup> 中的顶层绑定都将自动暴露给模板。
更多细节,可以到vue官网上查看。

5. 认识h函数

vue推荐使用模板创建html,但一些特殊场景,需要JavaScript的完全编程的能力,可以使用渲染函数,比模板更接近编译器。
h() 是 hyperscript 的简称——意思是“能生成 HTML (超文本标记语言) 的 JavaScript”。

Vue 提供了一个 h() 函数用于创建 vnodes

h()函数怎么使用?

h()函数接收三个参数
第一个参数:是标签的名称、组件、异步组件或者函数式组件
第二个参数:标签的属性,
第三参数:标签中的内容
如果使用render函数的话,就不需要写template标签了

<script>
	import { h } from "vue"
	export default{
		render() {
			return h("h2",{class:"title"},"hello render")
		}
	}
</script>

在这里插入图片描述
h函数实现计数器

<script>
	import {
		h
	} from "vue"
	export default {
		data(){
			return{
				counter : 0
			}
		},
		render() {
			return  h("div",{class:"app"},[ 
					// h("h2",null,'当前计数: this.counter),
					h('h2',null,`当前计数:${this.counter}`),
					h("button",{onClick:()=> this.counter++},"+1"),
					h("button",{onClick:()=> this.counter--},"-1")
				])
		}
	}
</script>

也可以使用setup替代data使用

import {h,ref} from "vue"
export default {
  setup(){
    const counter=ref(0)
    return {counter}
   }
   //....
 }

也可以在setup中写render函数

 setup(){
    const counter=ref(0)
    return ()=>{
      return h('div',{
          class:'app'
      },[
        h('h2',null,`当前计数:${counter.value}`),
        h('button',{
          onClick:()=>counter.value++
        },'+1'),
        h('button',{
           onClick:()=>counter.value--
        },'-1')  
      ])
    }
  }

在h函数中传入组件
App.vue

<script>
	import {
		h
	} from "vue";
	import HelloWorld from "./HelloWorld.vue";
	export default {
		render() {
			return h(HelloWorld,null,"")
		}
	}
</script>

HelloWorld.vue

<script>
	import { h } from "vue"
	export default{
		render() {
			return h("h2",null,"Hello World")
		}
	}
</script>

也可以传入插槽

app.vue

<script>
import { h } from "vue";
import helloword from "./1/helloword.vue";
export default {
  render() {
    return h(helloword, null, {
      default:props=>h('span',null,'传到helloword的内容')
    });
  },
};
</script>

helloword.vue

<script>
import {h} from 'vue'
export default {
   render(){
       return h("div",null,[
           h('h2',null,'helloword'),
           this.$slots.default ? this.$slots.default() :  h('span',null,'插槽默认值'),
       ])
   }
}
</script>

jsx的使用
现在的vue脚手架内置这些插件,所以可以直接编写jsx代码。

<script>
	import { h } from "vue";
	export default{
		data(){
		      return {
		        counter:0
		      }
		    },
		render() {
			const increment=()=>this.counter++
			const decrement=()=>this.counter--
			return (
			   <div>
			        <h2>当前计数:{this.counter}</h2>
			        <button onClick={increment}>+</button>
			        <button onClick={decrement}>-</button>
			   </div>
			)
		}
	}
</script>

在这里插入图片描述

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-21 00:19:29  更:2022-09-21 00:20:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 10:36:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码