Vue组件之全局组件与局部组件

举报
tea_year 发表于 2021/12/29 23:05:04 2021/12/29
【摘要】 组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。个人认为就是一个可以重复利用的结构层代码片段。 全局组件注册方式:Vue.co...

  
  1. 组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能。在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展。个人认为就是一个可以重复利用的结构层代码片段。
  2. 全局组件注册方式:Vue.component(组件名,{方法})
  3. eg:
  4. <body>
  5. <div id="app">
  6. <my-component></my-component>
  7. </div>
  8. <div id="app1">
  9. <my-component></my-component>
  10. </div>
  11. <script>
  12. Vue.component("my-component",{
  13. template:"<h1>我是全局组件</h1>"
  14. });
  15. new Vue({
  16. el:"#app"
  17. });
  18. new Vue({
  19. el:"#app1"
  20. })
  21. </script>
  22. </body>
  23. 渲染结果:
  24. <div id="app">
  25. <h1>我是全局组件</h1>
  26. </div>
  27. <div id="app1">
  28. <h1>我是全局组件</h1>
  29. </div>
  30. 这里需要注意:
  31. 1.全局组件必须写在Vue实例创建之前,才在该根元素下面生效;
  32. eg:
  33. <body>
  34. <div id="app">
  35. <my-component></my-component>
  36. </div>
  37. <div id="app1">
  38. <my-component></my-component>
  39. </div>
  40. <script>
  41. new Vue({
  42. el: "#app"
  43. });
  44. Vue.component("my-component", {
  45. template: "<h1>我是全局组件</h1>"
  46. });
  47. new Vue({
  48. el: "#app1"
  49. })
  50. </script>
  51. </body>
  52. 这样只会渲染app1根元素下面的,并不会渲染app根元素下面的,并且会报错。
  53. 2.模板里面第一级只能有一个标签,不能并行;
  54. <body>
  55. <div id="app">
  56. <my-component></my-component>
  57. </div>
  58. <script>
  59. new Vue({
  60. el: "#app"
  61. });
  62. Vue.component("my-component", {
  63. template: "<h1>我是全局组件</h1>" +
  64. "<p>我是全局组件内标签</p>"
  65. });
  66. new Vue({
  67. el: "#app1"
  68. })
  69. </script>
  70. </body>
  71. 这样子会报错,并且只会渲染第一个标签h1;我们应该这样子写:
  72. <body>
  73. <div id="app">
  74. <my-component></my-component>
  75. </div>
  76. <script>
  77. new Vue({
  78. el: "#app"
  79. });
  80. Vue.component("my-component", {
  81. template: "<h1>我是全局组件<p>" +
  82. "我是全局组件内标签</p></h1>"
  83. });
  84. new Vue({
  85. el: "#app1"
  86. })
  87. </script>
  88. </body>
  89. 局部组件注册方式,直接在Vue实例里面注册
  90. eg:
  91. <body>
  92. <div id="app1">
  93. <child-component></child-component>
  94. </div>
  95. <script>
  96. new Vue({
  97. el: "#app1",
  98. components:{
  99. "child-component":{
  100. template:"<h1>我是局部组件</h1>"
  101. }
  102. }
  103. });
  104. </script>
  105. 局部组件需要注意:
  106. 1.属性名为components,s千万别忘了;
  107. 2.套路比较深,所以建议模板定义在一个全局变量里,代码看起来容易一点,如下:(模板标签比较多的时候,这样子写更加简洁规整)
  108. <body>
  109. <div id="app1">
  110. <child-component></child-component>
  111. </div>
  112. <script>
  113. var child={
  114. template:"<h1>我是局部组件</h1>"
  115. };
  116. new Vue({
  117. el: "#app1",
  118. components:{
  119. "child-component":child
  120. }
  121. });
  122. </script>
  123. </body>
  124. 关于组件中的其他属性,可以和实例中的一样,但是data属性必须是一个函数:
  125. eg:
  126. <body>
  127. <div id="app1">
  128. <child-component></child-component>
  129. </div>
  130. <script>
  131. var child={
  132. template:"<button @click='add2'>我是局部组件:{{m2}}</button>",
  133. data:function(){
  134. return {m2:1}
  135. },
  136. methods:{
  137. add2:function(){
  138. this.m2++
  139. }
  140. }
  141. };
  142. new Vue({
  143. el: "#app1",
  144. components:{
  145. "child-component":child
  146. }
  147. })
  148. </script>
  149. </body>
  150. 显示结果:
  151. clipboard.png
  152. 全局组件和局部组件一样,data也必须是一个函数:
  153. <body>
  154. <div id="app1">
  155. <my-component></my-component>
  156. </div>
  157. <script>
  158. Vue.component("my-component",{
  159. template:"<button @click='add1'>全局组件:{{m1}}</button>",
  160. data:function(){
  161. return {
  162. m1:10
  163. }
  164. },
  165. methods:{
  166. add1:function(){
  167. this.m1++
  168. }
  169. }
  170. });
  171. new Vue({
  172. el:"#app1"
  173. })
  174. </script>
  175. </body>
  176. 显示结果:
  177. clipboard.png
  178. 当使用 DOM 作为模板时 (例如,将 el 选项挂载到一个已存在的元素上),你会受到 HTML 的一些限制,因为 Vue 只有在浏览器解析和标准化 HTML 后才能获取模板内容。尤其像这些元素 <ul><ol><table><select> 限制了能被它包裹的元素,而一些像<option> 这样的元素只能出现在某些其它元素内部。
  179. 自定义组件 <my-row> 被认为是无效的内容,因此在渲染的时候会导致错误。变通的方案是使用特殊的 is 属性:
  180. eg:
  181. <body>
  182. <div id="app1">
  183. <ul>
  184. <li is="my-component"></li>
  185. </ul>
  186. </div>
  187. <script>
  188. Vue.component("my-component",{
  189. template:"<h1>{{message}}</h1>",
  190. data:function(){
  191. return {
  192. message:"hello world"
  193. }
  194. }
  195. });
  196. new Vue({
  197. el:"#app1"
  198. })
  199. </script>
  200. </body>
  201. 渲染结果为:
  202. clipboard.png
  203. 对于全局与局部的作用域问题,我们可以这样理解,只要变量是在组件内部用的,这些变量必须是组件内部的,而在外部html结构中引用的变量,都引用的是该挂载下的实例里面的变量
  204. eg:
  205. <body>
  206. <div id="app1">
  207. <my-component></my-component>
  208. </div>
  209. <script>
  210. Vue.component("my-component",{
  211. template:"<button @click='add3'>" +
  212. "{{message}}</button>",
  213. data:function(){
  214. return {
  215. message:"hello world"
  216. }
  217. },
  218. methods:{
  219. add3:function(){
  220. alert("我是局部")
  221. }
  222. }
  223. });
  224. new Vue({
  225. el:"#app1",
  226. methods:{
  227. add3:function(){
  228. alert("我是全局")
  229. }
  230. }
  231. })
  232. </script>
  233. </body>
  234. 弹出框显示:我是局部
  235. Vue中所谓的全局指的是该挂载下的区域;
  236. 下面这种做法是错误的,按我的想法觉得应该会弹出:我是全局,但是却报错,也就是说组件处于全局下不可以添加默认事件,要用全局的事件函数,必须父子通信
  237. <body>
  238. <div id="app1">
  239. <my-component @click="add3"></my-component>
  240. </div>
  241. <script>
  242. Vue.component("my-component",{
  243. template:"<button @click='add3'>" +
  244. "{{message}}</button>",
  245. data:function(){
  246. return {
  247. message:"hello world"
  248. }
  249. }
  250. });
  251. new Vue({
  252. el:"#app1",
  253. methods:{
  254. add3:function(){
  255. alert("我是全局")
  256. }
  257. }
  258. })
  259. </script>
  260. </body>
  261. 额外话题:
  262. 1.函数return后面必须跟返回的内容,不能换行写
  263. eg:
  264. clipboard.png
  265. 下面这种写法不会返值回来:
  266. clipboard.png
  267. 2.Vue和小程序等一样,采用es6的函数写法,this指向是不一样的
  268. <body>
  269. <div id="app1">
  270. <button @click="f">ES5</button>
  271. <button @click="f1">ES6</button>
  272. </div>
  273. <script>
  274. new Vue({
  275. el:"#app1",
  276. methods:{
  277. f:function(){
  278. console.log(this)
  279. },
  280. f1:()=>{
  281. console.log(this)
  282. }
  283. }
  284. })
  285. </script>
  286. </body>
  287. 结果:
  288. 第一个this指的是Vue实例
  289. 第二个this指的是Window
  290. clipboard.png
  291. 由于它和小程序不一样,我发现在data里面this指的是window,在methods里面this才是Vue实例
  292. 所以建议大家用es5写吧
  293. new Vue({
  294. el:"#app1",
  295. data:{that:this},
  296. })
  297. clipboard.png

 

文章来源: aaaedu.blog.csdn.net,作者:tea_year,版权归原作者所有,如需转载,请联系作者。

原文链接:aaaedu.blog.csdn.net/article/details/86573232

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。