Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: 关于
v-model
的报错,比如,不能直接修改props
那么可以 使用 在computed
或者data
中 使用emit
将事件和值发送回去,然后由父组件的v-model
去修改。
Props
是一种非常强大的技术,可以帮助在我们的组件内部强制执行一定程度的一致性。
然而,
过度依赖
props 来增强你的组件功能, 往往会产生增加的复杂性
和难以维护
的不灵活的组件。
所以当你的
props
, 以及template
中 有大量逻辑
, 大量v-if v-else
这个时候 应该考虑slot
我们知道
slot
对于提供数据
和确定孩子(child
) 内部显示内容
非常有用.
如果你把它 想象成 一个经典的 起重机游戏, 你抓东西放在这个 slot 里, 这就是 我们做的
从 parent 收集数据, 然后将它 放入插槽 slot 中
正如您在 app.vue 组件中看到的,与其让基本按钮(base button)决定是否应该基于 props 渲染 icon 或 spinner,我们可以简单地
传递它需要渲染的元素
,就像任何普通的 HTML 元素一样。
插槽杀手级功能
作用域插槽也就是 v-slot
child
孩子 需要提供数据怎么办, 在 父组件中 使用 子组件的data
核心: 作用域插槽允许组件将其(自己的)
数据
公开给插槽的模板块
=> 或者说是slot 的 template 标签中
不过 需要注意的一点是:我们通过 scoped slot 公开的数据, 只是 模板槽的 作用域, 不能 用于父slot 中的 其他内容
, 在 父组件使用slotProps
来访问数据,具体内容 可以看下面的 slot使用注意事项。
所以 当我们需要使用 一些 灵活性, 以及 代码复用的时候 可以 考虑
slot
关于 slot
在 定义组件的地方写 <slot>
标签,在 使用组件的地方 (如果使用的 v-slot
指令,该指令仅仅能在 template 标签 和 组件上面使用。) 直接写需要传递的 元素 或 组件。
v-slot
传递的东西是 直接 传递到 组件定义那个地方的 <slot> </slot> 标签上的
slot
<!--
current-user 是父组件 ,它在定义的时候 在内部 使用了 <SLOT> 标签,并且将数据 user 使用 v-bind 也就是 :user="user", 绑定在 slot 标签上。
所以在父组件 current-user 中 可以通过 v-slot="{ user }" 结构来使用 子组件的数据,当然这个也不如使用 vuex 进行状态管理来的方便。hhh
-->
<current-user v-slot="{ user }">
{{ user.firstName }}
<!-- 完整写法是 slotProps.user.firstName -->
</current-user>
函数组件的应用场景是 你需要优化一个有很多节点的组件
例如你有一个 庞大的列表, 而且 列表中 每项都是 状态组件, 但是每个组件中 可能还有更多的组件, 这些 组件可能 纯粹 作为展示使用的,
例如只是一个 button, 或者只是一个 静态头像, 这些 组件不太需要 状态(
data
)
如果你的 组件只是 简单接收 数据 进行展示, 接受 props 然后 根据 这些 props 进行 渲染,
那么使用 函数式组件 是很适合的
如果这些 组件 在很多地方复用了 , 把他们 转换成 函数组件可以提高 应用性能
在 这里使用 高阶组件的 好处是
某某
组件内部 没有被 污染(可以非常简单的在其他地方复用)
因为是 将其 作为 一个 参数 传递给 一个 函数 进行 处理, 函数 将 处理过的 组件对象 返回(使用render函数可以很简单的完成这个任务
) 理论上 高阶组件 具备 更强的 复用性, 特别是 你想把组件用在 很多其他地方
template模板
最后都被 编译为了 => 渲染函数
所以 写 渲染函数的时候 就 当做自己在 写
template
好了
在 Vue 上下文中, 当我们 第一次 渲染一个
Vue
应用
我们会将template
放到 渲染函数 进行编译
这会 发生在你使用完整的编译方式(full build)
, 也就是你 直接使用DOM
模板, 就像你直接在 DOM 中 编写模板一样, 或者 直接 给Vue
传递一个 模板字符串
, 也就是说 这个是带了编译器的, 用于将template
编译为render function 的方式来表示
但是 如果你使用
vue-cli
来构建项目, 用到webpack
和vue-loader
vue-loader
实际上在 构建的时候预编译模板
,
所以 当 浏览器 访问的代码 是不包含 原始模板的
相反 , 它 提供了编译的 渲染函数代码
, 这个是 纯JavaScript
, 使用的是 编译后的render function 表示方法
这类似于
angular
上下文中的ALT
(angular context) 编译
这样做会 节约很多 编译时间
而且我们可以在 没有 编译器的时候 运行
在 Vue 中 提供了 两种
build
方式 ,
在 编译成
Render
函数 之后,Render
函数, 实际上 是返回 一个虚拟DOM
Vue
基于 虚拟 DOM 生成 真实 DOM
另外一个鲜为人知的特性是
h
函数也可以 渲染一个组件(component
)
直接 将组件传递给 渲染函数
import MyComponent from "..."
h(MyComponent, {
props:{...}
// 传递 属性给 组件, 通过 数据对象 (data object)
// 这意味着 你不再需要在 组件里面 注册组件配置项(componet options)
//
})
Vue 将 Template 作为默认 api , 但也允许你 使用 render function 进行开发, 如果你需要 比较高的 灵活性的 时候
对于 可能嵌套了 两个不同的组件, 深度嵌套的组件树, 但是 他们 仍然要 访问相同的数据
因此 问题 变得 不清楚, 那个组件 应该 拥有 数据?
最终 你会发现 都不应该 拥有这个数据, 数据应该提取出来 独立管理,
如果 数据是应用中多个组件共享的, 所以 这就提出了 使用 库 或者 一个模式的 必要性
所以 这个时候就 要使用 状态管理库了
mixins 本质上是 可重复使用的 代码片段
可以在 不同的组件 中 使用的 ,可重用代码片段
, 当然更好的方式 是 编写插件调用 Vue.use
我们只需要 将 mixin 对象 放入到 组件对象 即可, 这样最直接
当然 更好的是 使用 插件的方式, 来 让 组件复用 代码 片段
因为 如果你 多次 使用 vue.use 调用 同一个 插件, 它会防止 反复应用
但是 vue.mixins 不会这样做
而且这样你会看到 引用 代码片段的时候 , 方式 更加统一, 都是use
const myPlugin = {
install(Vue){
Vue.mixin({
created({
if(this.$options.rules){
// we can doing something
// 这里 是我们需要 实现的代码
}})
})
}
// 这里将对外公开 install 函数
}
Vue.use(myPlugin)
预期:随表单控件类型不同而不同。
限制: 仅支持 以下类型的元素或者组件 使用 v-model
<input>
<select>
<textarea>
components
我的理解是
这个数据双向绑定
, 主要还是用于表单
之中, 以及表单验证
当中
而且 实际上
v-model
是 ,v-bind
+v-on
的一个语法糖
<input type="text" v-model="message" />
<!-- 等同于 以下 代码 -->
<input
type="text"
v-bind:value="message"
v-on:input="message=$event.target.value"
/>
<h2>{{message}}</h2>
这个可以运行的示例
<script src="../lib/vue@v2_6_14.js"></script>
<div id="app">
<!-- <input type="text" v-model="message" > -->
<!-- 等同于 以下 代码
v-model 的好处就是 input 的是value 以及其他的 可能是 别的属性, v-model会帮助你自动判断,
并且代码 短一些嘛 哈哈 。
-->
<input
type="text"
v-bind:value="message"
v-on:input="message=$event.target.value"
/>
<h2>{{message}}</h2>
</div>
<script>
const vm = new Vue({
el: "#app",
data() {
return {
message: "hello world",
};
},
});
</script>
一个组件上的 v-model
默认会利用名为 value
的 prop
和名为 input
的事件,但是像
单选框、复选框等类型的输入控件可能会将 value attribute属性
用于不同的目的。model
选项可以用来避免这样的冲突:
组件
v-model
的测试
<script src="../lib/vue@v2_6_14.js"></script>
<div id="app">
<base-checkbox v-model="lovingVue"></base-checkbox>
</div>
<script>
Vue.component("base-checkbox", {
model: {
prop: "checked",
event: "change",
},
props: {
checked: Boolean,
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`,
});
const vm = new Vue({
el: "#app",
data() {
return {
lovingVue: true,
};
},
});
</script>
一般 我们 最早学习的就是
v-bind : v-on @ 来
使用动态绑定
和事件监听
来 增强html
然而随着 组件 越来越 大 和 越来越复杂,
我们可以发现这种方法 变得有局限性 , 甚至会造成 混乱
您可以 动态的 为
v-bind v-on
定义多个 值, 使用对象语法
,
简单
v-bind
例子,v-on
也是 类似的, 具体的看详细笔记
<script src="../lib/vue@v2_6_14.js"></script>
<div id="app">
<!-- <img
:src="imageAttrs.src"
:alt="imageAttrs.alt"
> -->
<!--
改写为这样 可以更好的管理 绑定属性
其实这个 就是 作为 参数 传递给 v-bind 的
实际上 src 和 alt 都是 参数
v-bind={src:imageAttrs.src, alt:imageAttrs.alt}
最终 变形为 下面这个
<img v-bind="imageAttrs">
-->
<img v-bind="imageAttrs" />
</div>
<script>
const vm = new Vue({
el: "#app",
data() {
return {
imageAttrs: {
src: "./logo.svg",
alt: "vuejs.org",
},
};
},
});
</script>
Vue 代码学习
软件架构说明
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。