Vue h函数的使用详解
一、认识
文档:https://v3.cn.vuejs.org/guide/render-function.html#dom-%E6%A0%91
h() 到底会返回什么呢?其实不是一个实际的 DOM 元素。它更准确的名字可能是 createNodeDescription,因为它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,包括及其子节点的描述信息。我们把这样的节点描述为“虚拟节点 (virtual node)”,也常简写它为 VNode 。“虚拟 DOM”是我们对由 Vue 组件树建立起来的整个 VNode 树的称呼。
二、使用
文档:https://v3.cn.vuejs.org/guide/render-function.html#h-%E5%8F%82%E6%95%B0
1、h() 参数
h() 函数是一个用于创建 VNode 的实用程序。也许可以更准确地将其命名为 createVNode(),但由于频繁使用和简洁,它被称为 h() 。它接受三个参数:
// @returns {VNode}
h(
// {String | Object | Function} tag
// 一个 HTML 标签名、一个组件、一个异步组件、或
// 一个函数式组件。
//
// 必需的。
'div',
// {Object} props
// 与 attribute、prop 和事件相对应的对象。
// 这会在模板中用到。
//
// 可选的(在开发时。建议传,实在没有传的时候,传入 null)
{},
// {String | Array | Object} children
// 子 VNodes, 使用 `h()` 构建,
// 或使用字符串获取 "文本 VNode" 或者
// 有插槽的对象。
//
// 可选的。
[
'Some text comes first.',
h('h1', 'A headline'),
h(MyComponent, {
someProp: 'foobar'
})
]
)
2、简单的使用
3、实现一个计数器案例
<script>
import "./style.css"
import { h, ref } from "vue";
export default {
// data 的写法
// data() {
// return {
// counter: 0
// }
// },
setup() {
const counter = ref(0)
return { counter }
},
render() {
return h("div", null, [
h("h1", null, `当前计数:${this.counter}`),
h("button", { onClick: () => this.counter++, class: "button" }, "加 1"),
h("button", { onClick: () => this.counter--, class: "button" }, "减 1")
])
}
}
</script>
修改成纯setup的写法:
<script>
import "./style.css"
import { h, ref } from "vue";
export default {
// data 的写法
// data() {
// return {
// counter: 0
// }
// },
setup() {
const counter = ref(0)
return () => {
return h("div", null, [
h("h1", null, `当前计数:${counter.value}`),
h("button", { onClick: () => counter.value++, class: "button" }, "加 1"),
h("button", { onClick: () => counter.value--, class: "button" }, "减 1")
])
}
}
}
</script>
4、函数组件和插槽的使用
1)父组件
<script>
import { h, ref } from "vue";
import Test from "./components/Test.vue"
export default {
setup() {
return {}
},
render() {
return h(Test, null, {
// default 对应的是一个函数,default是默认插槽
default: props => h("span", null, "父传入到组件中的内容:" + props.name)
})
}
}
</script>
2)子组件
<script>
import { h } from "vue";
export default {
render() {
return h("div", null, [
h("div", null, "我是子组件"),
this.$slots.default ? this.$slots.default({ name: "哈哈哈" }) : h("div", null, "我是子组件的默认值")
])
}
}
</script>
注:在项目中,如果你像上面一样写代码,就太苦逼了,所以这个时候就要用 JSX。
三、jsx的使用
1、jsx的认识
jsx我们通常会通过Babel来进行转换(React编写的jsx就是通过babel转换的);
对于Vue来说,我们只需要在Babel中配置对应的插件即可;
文档:https://v3.cn.vuejs.org/guide/render-function.html#jsx
2、下载Babel插件支持vue(现在貌似脚手架直接支持)
npm install @vue/babel-plugin-jsx -D
3、配置babel
1)在根目录下创建 .babel.config.js
2)在.babel.config.js 里面加入,如下代码
module.exports = {
presets: [
"@/vue/cli-plugin-babel/preset"
],
plugins: [
"@vue/babel-plugin-jsx"
]
}
4、简单的使用
<script>
import { ref } from 'vue'
export default {
setup() {
let counter = ref(0)
return { counter }
},
render() {
return (
<div>
<div>JSX的使用</div>
<h2>当前数字:{this.counter}</h2>
</div>
)
}
}
</script>
5、计数器案例
<script>
import { ref } from '@vue/reactivity'
export default {
setup() {
let counter = ref(0)
function add() {
counter.value++
}
function decrement() {
counter.value--
}
return { counter, add, decrement }
},
render() {
return (
<div>
<div>JSX的使用</div>
<h2>当前数字:{this.counter}</h2>
<button onClick={this.add}>加 1</button>
<button onClick={this.decrement} >减 1</button>
</div >
)
}
}
</script>
6、组件和插槽的使用
1)父组件
<script>
import { ref } from '@vue/reactivity'
import Test from "./components/Test.vue"
export default {
setup() {
let counter = ref(0)
function add() {
counter.value++
}
function decrement() {
counter.value--
}
return { counter, add, decrement }
},
render() {
return (
<div>
<div>JSX的使用</div>
{}
<h2>当前数字:{this.counter}</h2>
<button onClick={this.add}>加 1</button>
<button onClick={this.decrement} >减 1</button>
<hr />
<Test>
{}
{{ default: props => <p>我是父传入子的</p> }}
</Test>
</div >
)
}
}
</script>
2)子组件
<script>
export default {
render() {
return (
<div>
<p>我是组件</p>
{}
{this.$slots.default()}
</div>
)
}
}
</script>
注:如果你要h函数来写组件,请仔细查看文档,以上讲解,只是入门级。
到此这篇关于Vue h函数的使用详解的文章就介绍到这了,更多相关Vue h函数内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341