ホームページ >ウェブフロントエンド >フロントエンドQ&A >コンポーネントは Vue の機能ですか?
#このチュートリアルの動作環境: Windows7 システム、vue3 バージョン、DELL G3 コンピューター。 Vue.js は、フロントエンド インターフェイス開発のための優れた JavaScript ライブラリであり、非常に人気がある理由は、多くの優れた機能を備えているためです。コンポーネントは vue の機能であり、Vue の最も強力な機能の 1 つです。 Vue では、コンポーネントは HTML 要素を拡張し、再利用可能なコードをカプセル化できます。高レベルでは、コンポーネントはカスタム要素であり、Vue のコンパイラはコンポーネントに特別な関数を追加します。場合によっては、コンポーネントを is 属性で拡張したネイティブ HTML 要素形式にすることもできます。 。
1) 軽量フレームワーク
Vue.js は、依存するテンプレート式と計算されたプロパティを自動的に追跡し、MVVM データ バインディングとコンポーザブルを提供します。コンポーネント システムは、シンプルで柔軟な機能を備えています。 API により、読者が理解しやすくなり、より早く開始できるようになります。2) 双方向データ バインディング
宣言的レンダリングは、双方向データ バインディングの主な具体例であり、Vue.js の中核でもあります。簡潔なテンプレートの使用 この構文は、データの宣言的なレンダリングを DOM に統合します。3) 命令
Vue.js は、主に組み込み命令を通じてページと対話します。命令の機能は、式の値が変化するときです。それに応じて特定の動作を DOM に適用します。4) コンポーネント化
コンポーネント (コンポーネント) は、Vue.js の最も強力な機能の 1 つです。コンポーネントは HTML 要素を拡張し、再利用可能なコードをカプセル化できます。大まかに言うと、コンポーネントは、Vue.js のコンパイラーが特別な機能を追加するカスタム要素です。場合によっては、コンポーネントは、 is 属性で拡張されたネイティブ HTML 要素の形式を取ることもできます。 Vue では、親子コンポーネントは props を介して通信し、親から子への一方向の送信になります。子コンポーネントは親コンポーネントと通信し、イベントをトリガーしてデータ変更を親コンポーネントに通知します。これは、基本的な父と子のコミュニケーション モデルを形成します。 開発中のコンポーネントが HTML や JavaScript などと非常に密接な関係にある場合、実際のニーズに応じてコンポーネントをカスタマイズできるため、開発がより便利になり、コードの記述量が大幅に削減されます。 このコンポーネントはホット リロードもサポートしています。変更を加えた場合、ページは更新されませんが、コンポーネント自体はすぐに再ロードされ、アプリケーション全体の現在の状態に影響はありません。 CSS はホットリロードもサポートしています。 コンポーネントの利点:5) クライアント ルーティング
Vue-router は Vue.js の公式ルーティング プラグインであり、Vue と深く統合されています。 .js であり、単一ページのアプリケーションを構築するために使用されます。 Vue シングルページ アプリケーションはルーティングとコンポーネントに基づいています。ルーティングは、アクセス パスの設定と、パスとコンポーネントのマップに使用されます。従来のページは、ページ切り替えとハイパーリンクによるジャンプを実装します。6) 状態管理
状態管理は実際には一方向のデータ フローであり、状態がビューのレンダリングを駆動し、ユーザーがビューを操作してアクションを生成します。これにより状態の変更が発生し、ビューが再レンダリングされ、別のコンポーネントが形成されます。<!-- 第一个根元素 --> <div>这里是:{{name}}</div> <!-- 第二个根元素 --> <div> <p>这里是:{{name}}</p> <br> <button>change-one-name</button> <!-- 点击后修改vue-app-one的name值--> </div>
// 第一个vue对象 var one = new Vue({ el:"#vue-app-one", data:{ "name":"ccy1" } }) // 第二个vue对象 var two = new Vue({ el:"#vue-app-two", data:{ "name":"ccy2" }, methods:{ // 修改vue-app-one的name为'ccy333' changeName:function(){ one.name = 'ccy333' } } })効果: クリック後、「ccy1」を「ccy333」に変更します
グローバル コンポーネント
グローバル コンポーネントを定義するには、コンポーネントに名前を付ける必要があります。呼び出すときは、コンポーネント名をラベル名として使用します。これはカスタム ラベルと同等であり、多くのサブ HTML タグを含めることができます。コンポーネントの定義:
- これらのサブ HTML ラベルはコンポーネントのテンプレート属性で定義されています。コンポーネントが呼び出されるたびに、テンプレート内のラベルが表示されます。テンプレート内の
- には、コンポーネント内の 1 つのルート要素
- data は関数
- 、データを返しますこれを使用して、data で定義されたデータを呼び出すことができます
- #例:
① 定义一个组件,命名为my-component
② 其中包含数据:name和方法:changeName
③ 渲染出的html效果有一个p标签,包含一个按钮,点击按钮时,修改name
④ 命名规范:camelCase (驼峰命名法) 与kebab-case (短横线分隔命名)
- 当写成标签时,遇到有大写字母的命名,需要改成小写并用横杆链接前后两个部分,如定义组件时命名为myComponent,写成标签时应写成my-component>;
- 组件定义时也可以用横杆法命名;
- 如果定义时用myComponent,标签用my-component>是OK的,系统自动识别
// 自定义的全局组件my-component // template中只有一个根元素p标签,里面包含一个button按钮 Vue.component('my-component',{ template:`<p> 我的名字是:{{name}} <button>btn</button> </p>`, data(){ return { name:'ccy' } }, methods:{ changeName:function(){ this.name = '安之' } } }) // vue对象1 new Vue({ el:"#vue-app-one", }) // vue对象2 new Vue({ el:"#vue-app-two", })
使用组件:
① 在vue对象对应的根元素(el指定标签)下使用
② 由于定义的是全局组件,所以可以在任意的vue对象下使用
③ 组件可复用,在一个vue对象下可以使用多次,且组件间互相独立
<div> <my-component></my-component> <my-component></my-component> </div> <div> <my-component></my-component> </div>
效果:
在vue对象中,data属性值是一个对象,比如这样的:
但是在全局组件中,同一份data可能被多个vue对象使用,每个对象不单独维护一份data时,如果某一个vue对象修改了data中的一个变量,其他vue对象获取data时就会被影响;
如果用上面的例子做案例,若组件中的data是对象(引用),其他地方均不改变,两个vue对象便共享同一个name变量;当我通过其中一个vue对象改变name数据时(即点击任一个btn按钮),另一个对象获得的name也发生了改变(其他按钮处的’ccy’也都被改成了’安之’)
因此,为保证数据的独立性,即每个实例可以维护一份被返回对象的独立的拷贝,data为每个实例都return一份新创建的数据,不同的vue对象获取的data均互不影响
在vscode中不允许组件中的data是对象,会报错:
[Vue warn]: The “data” option should be a function that returns a per-instance value in component definitions.
- 局部组件注册在某个vue对象中,
- 只有注册过该局部组件的vue对象才能使用这个局部组件
例子:
局部组件定义:
// template仅一个根元素:ul var msgComponent = { // 数据是自身提供的 (hobbies) template:`
注册局部组件:
// 仅由注册过该局部组件的vue对象才能使用,此处为div#vue-app-one // 注意命名规范,components中对象的key将会被作为标签名,多个单词拼接的命名需使用横杆法 // 可以写成msg-component,此处直接简化了命名为msg, new Vue({ el:"#vue-app-one", components:{ "msg": msgComponent } })
html文件中使用<msg></msg>
:
<div> <p>这里是vue-app-one</p> <mycomponent></mycomponent> <mycomponent></mycomponent> <p>我的爱好:</p> <msg></msg> <!--使用局部组件--> </div>
效果: 红框圈出的部分就是局部组件渲染出来的
创建子组件:
var titleComponent = { props:["title"], template:`<p>{{title}}</p>` // 所需要的数据title由父组件提供 }
在父组件的components属性中注册子组件:
new Vue({ el:"#vue-app-one", components:{ "msg": msgComponent, "titleComponent":titleComponent }, })
在父组件上使用子组件:
<!-- div#vue-app-one为父组件 --> <div> <p>这里是vue-app-one</p> <mycomponent></mycomponent> <mycomponent></mycomponent> <!--使用子组件title-component,并传值"我的爱好:"给子组件--> <title-component></title-component> <msg></msg> </div>
效果:红框标记处就是父向子传值并展示
定义子组件:
var titleComponent = { props:["title"], template:`<p>{{title}}</p>` }
在父组件的components属性中注册子组件:
new Vue({ el:"#vue-app-one", components:{ "msg": msgComponent, "titleComponent":titleComponent }, data(){ return { title:"my hobbies are ", } } })
使用子组件,通过绑定父组件data中的变量title来实现动态传值:
<!-- div#vue-app-one为父组件 --> <div> <p>这里是vue-app-one</p> <mycomponent></mycomponent> <mycomponent></mycomponent> <!-- 动态绑定title --> <title-component></title-component> <msg></msg> </div>
效果:红框处就是动态绑定获取数据的展示
传递数组等复杂数据时,也可以使用v-bind来动态传值,如:
需要向子级传递hobbies数组,在vue实例对象(父)中创建数据hobbies:
new Vue({ el:"#vue-app-one", components:{ "msg": msgComponent, "titleComponent":titleComponent }, data:{ title:"my hobbies are ", hobbies:['看剧','看动漫','吃好吃的'], //需要向子组件传递的数据 } })
定义子组件:
var msgComponent = { template:` <p>{{hobby}}</p> `, props:["hobby"], data(){ return { } } }
使用子组件:
<!-- div#vue-app-one为父组件 --> <div> <p>这里是vue-app-one</p> <mycomponent></mycomponent> <mycomponent></mycomponent> <title-component></title-component> <!-- 动态传值:hobbies --> <msg></msg> </div>
效果:
跳回“一点想法”处
子组件不能通过prop向父组件传递数据,需要使用事件向父组件抛出一个值,告知父组件我需要实现一个功能,由父组件处理这个事件
例子:点击按钮,改变名称chinesename
(由于data变量名不支持chinese-name形式,花括号里不支持chineseName形式,所以这里我都用了小写,此处记录一下,日后学到了新知再来填坑)
先在父组件的data中定义chinesename的初始值:
new Vue({ el:"#vue-app-one", data:{ chinesename:"anzhi" // chinesename初始值 } })
创建子组件,并注册事件change-name(就像click事件一样,需要让系统能够辨认这是一个事件并监听,当事件被触发时,执行某项约定好的操作):
Vue.component('blog-post', { props: ['chinesename'], template: ` <div> <h4>{{ chinesename }}</h4> <button> 修改名字 </button> </div> ` // blog-post组件包含一个h4,显示chinesename,和一个按钮 // 点击这个按钮,触发change-name事件,将"ruosu"作为参数传递给指定的处理函数onChangeName })
在父组件中使用子组件,定义change-name的处理函数为onChangeName:
<div> <p>这里是vue-app-one</p> <!-- v-bind:通过prop给子组件传递chinesename的初始值 --> <!-- v-on:子组件通过$emit给父组件传递新的chinesename的值 --> <div> <blog-post></blog-post> </div> </div>
在父组件处定义事件处理函数onChangeName:
new Vue({ el:"#vue-app-one", data:{ chinesename:"anzhi" }, methods:{ onChangeName:function(value){ // 将chinesename换成传递过来的数据 this.chinesename=value } } })
效果:
关于父子组件的区分,在此写一点总结,还是日后学了新知识再来填坑
官网中没有很明确指明两者的定义和区别,在网上搜了一圈,觉得比较多人认可并且好理解的是:
在前面这些父子传值的例子中,我们可以看到,对于局部组件,我们会在某个html根元素中注册并使用,所以此时el指定的根元素在html文件中是这个局部组件的父组件,局部组件在html使用时便是这个父组件的一份子,承担数据传输的责任
跳转到父向子动态传值案例
再用绕口令说一波,即:title-component组件定义处与使用处,两者身份是不一样的,在定义处,它是局部组件,也是子组件,需注册才能使用;在使用处,它是根元素的包含一部分,根元素为父组件,而“它”,承担着父组件与子组件数据沟通的重任
这个总结在全局组件情况下也适用,使用该全局组件的根元素是父组件,如上面的子向父传值的案例,p#vue-app-one是父组件,
图示:
如果是子组件又嵌套了子组件,被嵌套的组件是子子组件,以此类推
以上がコンポーネントは Vue の機能ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。