网站开发用什么语言比较流行,网页图片无法保存,网站开发所用的技术,网站制作 pProps声明
一个组件需要显示声明它所接受的props#xff0c;这样vue才能知道外部传入的哪些是props#xff0c;哪些是透传attribute
在使script setup的单文件中#xff0c;props可以使用 defineProps()宏来声明#xff1a;
script setup
const props definePro…Props声明
一个组件需要显示声明它所接受的props这样vue才能知道外部传入的哪些是props哪些是透传attribute
在使script setup的单文件中props可以使用 defineProps()宏来声明
script setup
const props defineProps([foo])console.log(props.foo)
script在没有使用script setup的组件中prop可以使用props选项来声明
export default{props:[foo],setup(props){//接收props作为第一个参数console.log(props.foo)}
}注意传递给defineProps的参数和提供给props选项的值是相同的两种声明方式背后其实使用的都是prop选项。 除了使用字符串数组来声明prop外还可以使用对象的形式
//使用script setup
defineProps({title:String,likes:Number}
}//使用非script setup
export default{props:{title:String,likes:Nunber}}对于以对象形式声明中的每个属性key是prop的名称而值则是该prop预期类型的构造函数。比如如果要求一个prop的值是number类型则可以使用Number构造函数作为其声明的值。 对象形式的props声明不仅可以一定程度上作为组件的文档而且如果其他开发者在使用你的组件时传递错误的类型也会在浏览器控制台中抛出警告。我们将在本章节稍后进一步讨论有关 prop 校验的更多细节。 如果你正在搭配 TypeScript 使用
script setup langts
defineProps{title?:stringlikes?:number}()
/script传递prop的细节
Prop名字格式
如果一个prop的名字很长应使用camelCase形式因为它们是合法的Javascript 标识符可以直接在模板的表达式中使用也可以避免在作为属性key名时必须加上引号
defineProps({greetingMessage: String
})
span{{ greetingMessage }}/span虽然理论上你也可以在向子组件传递props时使用camelCase形式使用Dom 内模板是例外但实际上为了和HTML attribute 对齐我们通常会为其写为 kebab-case形式
MyComponent greeting-messagehello/对于组件名我们推荐使用 PascalCase 因为这提高了模板的可读性能帮助我们区分vue组件和原生Html元素。对于传递props来说使用camelCase并没有太多优势因此我们推荐更贴切html的书写风格。
静态vs动态 prop
至此你已经见过了很多像这样的静态值形式的props
BlogPost titleMy journey whit vue/相应地还有使用v-bind 或 缩写 来动态绑定的props
BlogPost :titlepost.title /
BlogPost :titlepost.title bypost.author.name/传递不同的值类型
在上述的两个例子中我们只传入了字符串值但实际上任何类型的值都可以作为props的值被传递。
Number
!-- 虽然 42 是个常量我们还是需要使用 v-bind --
!-- 因为这是一个 JavaScript 表达式而不是一个字符串 --
BlogPost :likes42 /!-- 根据一个变量的值动态传入 --
BlogPost :likespost.likes /Boolean
!-- 仅写上 prop 但不传值会隐式转换为 true --
BlogPost is-published /!-- 虽然 false 是静态的值我们还是需要使用 v-bind --
!-- 因为这是一个 JavaScript 表达式而不是一个字符串 --
BlogPost :is-publishedfalse /!-- 根据一个变量的值动态传入 --
BlogPost :is-publishedpost.isPublished /Array
!-- 虽然这个数组是个常量我们还是需要使用 v-bind --
!-- 因为这是一个 JavaScript 表达式而不是一个字符串 --
BlogPost :comment-ids[234, 266, 273] /!-- 根据一个变量的值动态传入 --
BlogPost :comment-idspost.commentIds /Object
!-- 虽然这个对象字面量是个常量我们还是需要使用 v-bind --
!-- 因为这是一个 JavaScript 表达式而不是一个字符串 --
BlogPost:author{name: Veronica,company: Veridian Dynamics}/!-- 根据一个变量的值动态传入 --
BlogPost :authorpost.author /
使用一个对象绑定多个prop
如果你想要将一个对象的所有属性都当作props传入你可以使用没有参数的v-bind即只使用 v-bind 而非属性
const post {id: 1,title: My Journey with Vue
}以及下面的模板
BlogPost v-bindpost /而这实际上等价于
BlogPost :idpost.id :titlepost.title /单向数据流
所有的props都遵循着单向绑定原则props因父组件的更新而变化自然地将新状态向下流往子组件而不会逆向传递。这避免了子组件意外修改父组件的状态的情况不然应用的数据流将会很容易变得混乱而难以理解。 另外每次父组件更新完后所有的子组件中的props都会被更新到最新值这意味着你不应该在子组件中去修改一个prop。否则会抛出警告
const props defineProps([foo])// ❌ 警告prop 是只读的
props.foo bar导致你想要更改一个prop的需求通常来之以下两种场景 1.prop被用于传入初始值而子组件想在之后将其作为一个局部数据属性。爱这种情况下最好是新定义一个局部数据属性从props上获取初始值即可
const props defineProps([initialCounter])
// 计数器只是将 props.initialCounter 作为初始值
// 像下面这样做就使 prop 和后续更新无关了
const counter ref(props.initialCounter)2.需要对传入的prop值做进一步的转换在这种情况下最好是基于该prop值定义一个计算属性
const props defineProps([size])// 该 prop 变更时计算属性也会自动更新
const normalizedSize computed(() props.size.trim().toLowerCase())更改对象 / 数组类型的 props 当对象或数组作为 props 被传入时虽然子组件无法更改 props 绑定但仍然可以更改对象或数组内部的值。这是因为 JavaScript 的对象和数组是按引用传递而对 Vue 来说禁止这样的改动虽然可能生效但有很大的性能损耗比较得不偿失。 这种更改的主要缺陷是它允许了子组件以某种不明显的方式影响父组件的状态可能会使数据流在将来变得更难以理解。在最佳实践中你应该尽可能避免这样的更改除非父子组件在设计上本来就需要紧密耦合。在大多数场景下子组件应该抛出一个事件来通知父组件做出改变。