首页IT科技vue中的computed和watch的区别(vue2.x的h函数(createElement)与vue3中的h函数)

vue中的computed和watch的区别(vue2.x的h函数(createElement)与vue3中的h函数)

时间2025-05-05 17:44:23分类IT科技浏览4913
导读:1. vue2.x的 h 函数(createElement 使用方法及介绍:(参考官网提取) h函数第一个是标签名字 或者是组件名字,第二个参数是配置项,第三个参数是 innerText ,不会帮你转换节点,如果需要转换成节点(v-html)请去第二个参数中的 domP...

1. vue2.x的 h 函数(createElement)

使用方法及介绍:(参考官网提取) h函数第一个是标签名字 或者是组件名字              ,第二个参数是配置项                    ,第三个参数是 innerText       ,不会帮你转换节点          ,如果需要转换成节点(v-html)请去第二个参数中的 domProps 配置 innerHTML 当第二个参数是字符串的时候则会直接当 innerText 渲染(相当于配置项参数为空对象)【h(‘span’, ‘姓名’)】 第三个参数如果为字符串的时候可以理解为默认值!(innerText的默认值)如果同时设置了这两个则配置中的权重更高 第三个参数也是该元素的子集合            、插槽设置的地方              。 温馨提示:vue2.x的h函数跟vue3.x的有点不一样                     ,第二个参数配置项格式变了         ,第三个参数为函数返回      ,具体情况看本文第二要点 以下为常见的常规配置 import SelectEdit from ./SelectEdit export default { data() { return { name: } }, render(h) { // 如果使用原生的则 // return h(div, { // 这个是挂载组件 return h(SelectEdit, { // 此处是给 SelectEdit 组件传值的(props传值) props: { value: 1, type: on }, // class可以数组的形式也可以对象的形式 // class: [speci-class], class: { speci-class: true }, // 样式有-的注意小驼峰 或者使用 string 模式 style: { color: red, fontSize: 14px, // 或者这样 font-size: 14px }, // 普通的 HTML attribute attrs: { placeholder: 这是给原生html赋值placeholder属性 }, // DOM property domProps: { innerHTML: DOM property, // 这个参数等同于h函数的第三个参数 innerText: xxxxxxx }, // 这里是挂载方法的但不再支持如 `v-on:keyup.enter` 这样的修饰器 on: { // 方法名可以自定义(组件内 $emit(xxxchange, {name: zs})) xxxchange: val => { this.name = val.name; }, click: val => { this.name = val.name; }, }, // 仅用于组件                     ,用于监听原生事件            ,而不是组件内部使用 // `vm.$emit` 触发的事件                    。 nativeOn: { click: this.nativeClickHandler }, // 自定义指令      。注意   ,你无法对 `binding` 中的 `oldValue` directives: [ { name: my-custom-directive, value: 2, expression: 1 + 1, arg: foo, modifiers: { bar: true } } ], // 作用域插槽的格式为 scopedSlots: { default: props => createElement(span, props.text) }, // 如果组件是其它组件的子组件                     ,需为插槽指定名称 slot: name-of-slot, // 其它特殊顶层 property key: myKey, ref: myRef, // 如果你在渲染函数中给多个元素都应用了相同的 ref 名               , // 那么 `$refs.myRef` 会变成一个数组          。 refInFor: true }, 这里是显示文本) } } 举例子了:如果你想要实现以下效果(v-model) <div class="row zs active info" name="zs"> <span style="background-color: red;font-size: 16px;" @click="handleName">姓名:</span> <i >{{ name }}</i> <input v-model="name" /> </div>

目测没问题

data() { return { name: } }, render(h) { return h(div, { class: [row zs, active, info], attrs: { name: zs } }, [ h(span, { style: { backgroundColor: red, font-size: 16px }, on: { click: handleName } }, 姓名:), h(i, 张三), h(input, { domProps: { value: this.name }, on: { input: function (event) { this.$emit(input, event.target.value) } } }) ] ) }

2. vue3 h函数配置项

与2.x相比,第一个参数格式没有更变                  ,第二个参数格式更变了                   ,第三个参数变为建议使用函数返回了 第三个参数如果为字符串的时候可以理解为默认值!(innerText的默认值)如果同时设置了这两个则配置中的权重更高 第三个参数也是该元素的子集合                    、插槽设置的地方                     。 第三个参数不使用函数会有一个vue警告(所以说直接函数吧) 具体使用如下: import { h } from vue; import { ElButton } from element-plus h( ElButton, { type: primary, innerText: 修改11, onClick: () => { console.log(11); } }, () => 修改 )

2.1 v-model实现(以下开始为官网实现)

props: [modelValue], emits: [update:modelValue], render() { return h(SomeComponent, { modelValue: this.modelValue, onUpdate:modelValue: value => this.$emit(update:modelValue, value) }) }

自己搞忘记后重新弄的踩坑记录:

双向绑定实现:2.x中是value   ,但是到了3.x中不是value了而是modelValue onUpdate:modelValue 相当于就是 v-model              ,只不过这个变成了函数                    ,在这个函数里面需要你自己给绑定元素赋值         。不赋值则会出现双向绑定失效的问题!

2.2 v-on

给定有效的事件名称      ,例如(onClick, onChange)或自定义的名称

render() { return h(div, { onClick: $event => console.log(clicked, $event.target) }) }

2.3 事件修饰符

对于 .passive        、.capture 和 .once 事件修饰符          ,可以使用驼峰写法将他们拼接在事件名后面:

render() { return h(input, { onClickCapture: this.doThisInCapturingMode, onKeyupOnce: this.doThisOnce, onMouseoverOnceCapture: this.doThisOnceInCapturingMode }) }

对于所有其它的修饰符                     ,私有前缀都不是必须的         ,因为你可以在事件处理函数中使用事件方法:

这里是一个使用所有修饰符的例子: render() { return h(input, { onKeyUp: event => { // 如果触发事件的元素不是事件绑定的元素 // 则返回 if (event.target !== event.currentTarget) return // 如果向上键不是回车键      ,则终止 // 没有同时按下按键 (13) 和 shift 键 if (!event.shiftKey || event.keyCode !== 13) return // 停止事件传播 event.stopPropagation() // 阻止该元素默认的 keyup 事件 event.preventDefault() // ... } }) }

2.4 插槽

你可以通过 this.$slots 访问静态插槽的内容                     ,每个插槽都是一个 VNode 数组:

render() { // `<div><slot></slot></div>` return h(div, {}, this.$slots.default()) } props: [message], render() { // `<div><slot :text="message"></slot></div>` return h(div, {}, this.$slots.default({ text: this.message })) }

渲染函数将插槽传递给子组件

render() { // `<div><child v-slot="props"><span>{{ props.text }}</span></child></div>` return h(div, [ h( resolveComponent(child), {}, // 将 `slots` 以 { name: props => VNode | Array<VNode> } 的形式传递给子对象      。 { default: (props) => h(span, props.text) } ) ]) }

插槽以函数的形式传递            ,允许子组件控制每个插槽内容的创建                     。任何响应式数据都应该在插槽函数内访问   ,以确保它被注册为子组件的依赖关系                     ,而不是父组件            。相反               ,对 resolveComponent 的调用应该在插槽函数之外进行,否则它们会相对于错误的组件进行解析   。

// `<MyButton><MyIcon :name="icon" />{{ text }}</MyButton>` render() { // 应该是在插槽函数外面调用 resolveComponent                     。 const Button = resolveComponent(MyButton) const Icon = resolveComponent(MyIcon) return h( Button, null, { // 使用箭头函数保存 `this` 的值 default: (props) => { // 响应式 property 应该在插槽函数内部读取                  , // 这样它们就会成为 children 渲染的依赖               。 return [ h(Icon, { name: this.icon }), this.text ] } } ) }

如果一个组件从它的父组件中接收到插槽                   ,它们可以直接传递给子组件。

render() { return h(Panel, null, this.$slots) }

也可以根据情况单独传递或包裹住                  。

render() { return h( Panel, null, { // 如果我们想传递一个槽函数   ,我们可以通过 header: this.$slots.header, // 如果我们需要以某种方式对插槽进行操作              , // 那么我们需要用一个新的函数来包裹它 default: (props) => { const children = this.$slots.default ? this.$slots.default(props) : [] return children.concat(h(div, Extra child)) } } ) }

2.5 component 和 is

在底层实现里                    ,模板使用 resolveDynamicComponent 来实现 is attribute                   。如果我们在 render 函数中需要 is 提供的所有灵活性      ,我们可以使用同样的函数:

const { h, resolveDynamicComponent } = Vue // ... // `<component :is="name"></component>` render() { const Component = resolveDynamicComponent(this.name) return h(Component) }

就像 is, resolveDynamicComponent 支持传递一个组件名称         、一个 HTML 元素名称或一个组件选项对象   。

通常这种程度的灵活性是不需要的              。通常 resolveDynamicComponent 可以被换做一个更直接的替代方案                    。

例如          ,如果我们只需要支持组件名称                     ,那么可以使用 resolveComponent 来代替      。

如果 VNode 始终是一个 HTML 元素         ,那么我们可以直接把它的名字传递给 h:

// `<component :is="bold ? strong : em"></component>` render() { return h(this.bold ? strong : em) }

同样      ,如果传递给 is 的值是一个组件选项对象                     ,那么不需要解析什么            ,可以直接作为 h 的第一个参数传递          。

与 < template > 标签一样   ,< component > 标签仅在模板中作为语法占位符需要                     ,当迁移到 render 函数时               ,应被丢弃                     。

2.6 自定义指令

可以使用 withDirectives 将自定义指令应用于 VNode:

const { h, resolveDirective, withDirectives } = Vue // ... // <div v-pin:top.animate="200"></div> render () { const pin = resolveDirective(pin) return withDirectives(h(div), [ [pin, 200, top, { animate: true }] ]) }

resolveDirective 是模板内部用来解析指令名称的同一个函数         。只有当你还没有直接访问指令的定义对象时,才需要这样做

2.7 内置组件

诸如 < keep-alive >                   、< transition >            、< transition-group > 和 < teleport > 等内置组件默认并没有被全局注册      。这使得打包工具可以 tree-shake                  ,因此这些组件只会在被用到的时候被引入构建                     。不过这也意味着我们无法通过 resolveComponent 或 resolveDynamicComponent 访问它们            。

在模板中这些组件会被特殊处理                   ,即在它们被用到的时候自动导入   。当我们编写自己的 render 函数时   ,需要自行导入它们:

const { h, KeepAlive, Teleport, Transition, TransitionGroup } = Vue // ... render () { return h(Transition, { mode: out-in }, /* ... */) }

2.8 渲染函数的返回值

在我们目前看过的所有示例中              ,render 函数返回的是单个根 VNode                     。但其实也有别的选项               。

返回一个字符串时会创建一个文本 VNode                    ,而不被包裹任何元素:

render() { return Hello world! }

我们也可以返回一个子元素数组      ,而不把它们包裹在一个根结点里。这会创建一个片段 (fragment):

// 相当于模板 `Hello<br>world!` render() { return [ Hello, h(br), world! ] }

可能是因为数据依然在加载中的关系          ,组件不需要渲染                     ,这时它可以返回 null                  。这样我们在 DOM 中会渲染一个注释节点

2.9 JSX

如果你写了很多渲染函数         ,可能会觉得下面这样的代码写起来很痛苦:

h( anchored-heading, { level: 1 }, { default: () => [h(span, Hello), world!] } )

特别是对应的模板如此简单的情况下:

<anchored-heading :level="1"> <span>Hello</span> world! </anchored-heading>

这就是为什么会有一个 Babel 插件      ,用于在 Vue 中使用 JSX 语法                     ,它可以让我们回到更接近于模板的语法上                   。

import AnchoredHeading from ./AnchoredHeading.vue const app = createApp({ render() { return ( <AnchoredHeading level={1}> <span>Hello</span> world! </AnchoredHeading> ) } }) app.mount(#demo)

有关 JSX 如何映射到 JavaScript 的更多信息            ,请参阅使用文档    。

参考链接

vue2.x官网渲染函数 vue3.x官网dom-树 vue3.x官网渲染函数 本文仅做于笔记

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
django csrf timeout(Django Raw and Raw SQL)