ヴュー
1 はじめに:
Vue は、ユーザー インターフェイスを構築するための進歩的なフレームワークです。他の大きなフレームワークとは異なり、Vue は下から上にレイヤーごとに適用されるように設計されています。Vue のコア ライブラリはビュー レイヤーのみに焦点を当てており、使いやすいだけでなく、サードパーティのライブラリや既存のプロジェクトとの統合も簡単です。一方、最新のツールチェーンやさまざまなサポート ライブラリと組み合わせると、Vue は複雑なシングルページ アプリケーションを実行することもできます。これは、単一ページの application-index.html と、ジャンプを実現するためのページ ジャンプ用の vue プラグイン ルーティングに使用されます。
【vue】https://cn.vuejs.org/
[Gitee カバーキャラクター: You Yuxi が Vue.js について語る] https://gitee.com/gitee-stars/14
[Vue 著者 You Yuxi インタビュー] https://www.jianshu.com/p/3092b382ee80
[Object.defineProperty() の詳細な説明により、vue ソース コードの理解が深まります] https://www.cnblogs.com/ldq678/p/13854113.html https://zhuanlan.zhihu.com/p/22695144
1-Vue基本渲染-插值
### js代码
window.onload = function () {
// 创建vue实例,vue实例要与模板(DOM)绑定
let vm= new Vue({
el: "#app",
data: {
// 数据模型
msg:'hello world'
},
// 函数
methods: {
changeData(){
if(this.msg==='hello world'){
// 更改数据模型中的数据
// 获取数据模型中的数据
// 在vue实例内访问vue实例身上的属性和方法
this.msg='你好我是修改后的值'
}else{
this.msg='hello world';
}
}
},
})
}
### html代码
<!-- 以前把msg作为元素文本的,获取dom节点,绑定事件,dom.innerText=msg-->
<div id="app">
<!-- 在模板内访问vue实例中数据模型中的数据 插值 -->
<!-- 基本渲染 插值 -->
{
{
msg}}
<p>{
{
msg}}</p>
<!-- 点击按钮 改变数据模型中的数据msg变量 -->
<button @click='changeData'>点我修改数据模型msg数据</button>
</div>
数据模型更改,引发了vm驱动
2.MVVM
モデルデータモデル
ビュービュー
VM ViewModel はビューとデータ モデル間のリンクです。データ モデルが変更されると、vm はビューにそれを変更するように通知し、ビューが変更されると、vm はデータ モデルに対応する変更を行うように通知します。
ビュー モデルは、データ モデル内のデータをビューにレンダリングするのに役立ちます。これはリンクに相当します。
[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします (img-wd2QUqbw-1691293440376) (D:\code area\ES6 および vue class document\images) \image-20210527142359964.png )]
最適化されたレンダリング: 現在のデータ モデルが変更されると、対応するビューのみが変更され、対応するビュー レイヤーのみがレンダリングされます。
mvvm の概要:
m はモデル サーバー上のビジネス ロジック操作を指します。v はビュー ビュー (ページ) を指します。vm は ViewModel モデルとビューの間のコア ハブ (vue.js など) を指します。
DOM Listeners
上図のとはData Bindings
、双方向バインドを実現するための鍵となる 2 つのツールであると考えることができます。ビュー側から見ると、ViewModel のツールは
DOM Listeners
ページ上の DOM 要素の変更を監視し、変更がある場合はモデル内のデータを変更するのに役立ちます。モデル側から見ると、モデル内のデータを更新するときに、
Data Bindings
このツールはページ内の DOM 要素の更新に役立ちます。
### 2.数据模型
let vm=new Vue({
el:'#app',
data:{
msg:'科大优质男',
time:new Date()
},
methods:{
sayName(){
console.log(this.name)
},
}
})
// 每隔一秒重新查询一次时间
setInterval(()=>{
vm.time=new Date()
},1000)
// 查看vue实例对象
console.log(vm)
****** **** 3. ライフサイクル(フック機能)
vueインスタンスの作成から仮想 dom の生成、データ バインディング、データのレンダリングと破棄の監視までのプロセス全体
生命周期的第一步首先是创建vue实例,并且进行初始化。
### vue实例初始化阶段
beforeCreate
在初始化的时候调用了beforeCreate,完成了vue实例的生命周期相关属性的初始化以及事件的初始化。这个时候还不能访问数据模型中的data和methods中的方法。
created
在初始化完毕之后,完成vue的数据注入以及数据监听操作,该构造的执行意味着vue实例创建完毕,可以进行data数据模型和和methods方法的访问
### vue实例挂载阶段
beforeMount
在created之后,vue会判断实例中是否含有el属性,如果没有vm.$mount(el),接着会判断是否含有template属性,如果有将其解析为一个render function,如果没有将el指定的外部html进行解析。这里只完成了模板的解析但是数据并没有绑定到模板中。
mounted
创建vm.$el替换el,实际上完成的是数据绑定操作,在其间执行了render函数,将模板进行了解析,将数据进行了动态绑定
### vue实例更新阶段
beforeUpdate
更新虚拟dom节点
updated
完成了页面的重新渲染
### vue实例销毁阶段
beforeDestroy
销毁之前调用,此时可以访问vue实例
destroyed
完成了监听器,子组件,事件监听等移除,销毁vue实例对象。
### js代码
<script>
let vm=new Vue({
el:"#app",
data:{
msg:'hello world'
},
beforeCreate(){
console.log('vue实例初始化之前')
},
created() {
console.log('vue实例初始化好了,可以访问到数据模型中的数据以及methods方法')
},
beforeMount() {
console.log('实例挂载之前')
},
mounted(){
console.log('实例挂载完毕,可以获取dom节点,一般不操作dom')
},
beforeUpdate() {
console.log('实例发生改变之前触发该生命周期')
},
updated() {
console.log('实例发生改变后页面视图发生变化,触发该生命周期')
},
beforeDestroy() {
// console.log('实例销毁之前,仍然可以访问到数据模型中的数据和方法')
},
destroyed() {
// console.log('实例销毁完毕,销毁了监听器和事件监听以及子组件');
},
methods:{
sayHello(){
console.log(this.msg)
},
}
});
console.log(vm)
setTimeout(()=>{
vm.$destroy()
},3000)
</script>
### html代码
<div id="app">
{
{
msg}}
</div>
4. テンプレートの構文
導入:
Vue は、開発者が基礎となる Vue インスタンスのデータに DOM を宣言的にバインドできる HTML ベースのテンプレート構文を使用します。すべての Vue テンプレートは有効な HTML であるため、仕様に準拠したブラウザおよび HTML パーサーで解析できます。基礎となる実装では、Vue はテンプレートを仮想 DOM レンダリング関数にコンパイルします。応答性の高いシステムと組み合わせると、Vue は少なくとも再レンダリングが必要なコンポーネントの数をインテリジェントに計算し、DOM 操作の数を最小限に抑えることができます。仮想 DOM に精通しており、JavaScript の生のパワーを好む場合は、オプションの JSX 構文 (React は jsx 構文を使用します) を使用して、レンダリング関数を作成し、テンプレートを使用せずに直接レンダリングすることもできます。
1. 補間: 1. 基本的なレンダリング { {}}
Vue インスタンスが作成されると これらのプロパティの値が変更されると、ビューは「応答」します。つまり、一致が新しい値で更新されます。
渲染最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值。
2. オリジナルの HTML (v-html、タグ内のテキスト コンテンツを解析)
3. 属性 v-bind (バインディングが変数であることを示す略語を使用できます)
4. イベント v-on:click (@ 省略形を使用できます)
5.javascript式(jsロジック演算が可能)
```Mustache 标签```将会被替代为对应数据对象上 ```msg property```的值。无论何时,绑定的数据对象上 ```msg property ```发生了改变,插值处的内容都会更新。当这些数据改变时,视图会进行重渲染。
1.文本渲染
### js代码
let vm=new Vue({
el:'#app',
data:{
msg:'hello world',
animal:['大笨象','小猴子','狐狸']
},
methods:{
}
});
### html代码
<div id="app">
<div>{
{
animal}}</div>
<div>{
{
msg}}</div>
</div>
也可以使用v-once指令,执行一次性地插值,当数据发生改变,插值处的内容不会更新
### js代码
let vm=new Vue({
el:'#app',
data:{
msg:'hello world'
}
})
setTimeout(()=>{
vm.msg='hello vue'
},2000)
### html代码
<div id="app" >
<!-- {
{
msg }} 不会再更改,一直是hello world -->
<div v-once>{
{
msg}}</div>
</div>
2.如果我们向后台请求的数据是一段HTML代码,如果我们直接通过{
{
}}来输出,会将HTML代码也一起输出。双大括号会将数据解析为普通文本,而非 HTML 代码。但是我们可能希望的是按照HTML格式进行解析,并且显示对应的内容。如果我们希望解析出HTML展示
可以使用**v-html**指令:该指令后面往往会跟上一个string类型,会将string的html解析出来并且进行渲染。
<div id="app">
<div v-html='url'></div>
</div>
new Vue({
el:'#app',
data(){
return {
list:"All the changan flowers in one day",
url:'<a href="https://www.baidu.com">百度一下</a>'
}
}
})
3.属性渲染
双大括号语法不能作用在元素属性上,遇到这种情况应该使用**v-bind**指令 :
### js代码
new Vue({
el:"#app",
data(){
return {
msg:'我是数据模型中的msg',
title:'我是鼠标悬浮就会展示的title'
}
}
})
### html代码
<div id="app">
<!-- <div v-bind:title='title'>{
{
msg}}</div> -->
<!-- 简写为:属性名="变量名" -->
<div :title='title'>{
{
msg}}</div>
</div>
4.事件渲染
可以使用v-on给当前元素绑定事件,也可以使用简写形式@click
###js代码
new Vue({
el:'#app',
data:{
},
methods:{
test(){
alert(1)
}
}
})
### html代码
<div id="app">
<button v-on:click='test'>点我点我</button>
<button @click='test'>点我点我</button>
</div>
5.javaScript表达式
###js代码
new Vue({
el:'#app',
data(){
return {
animal:['大笨象','小猴子','狐狸'],
count:1001,
firstname:'ren',
lastname:'terry'
}
}
})
###html代码
<div id="app">
<ul>
<li v-for='(item,index) in animal'>
{
{
index+1}}-{
{
item}}-{
{
index}}
</li>
</ul>
<div>{
{
Number(animal)}}</div>
<div>{
{
Boolean(animal)}}</div>
<div>{
{
count*100}}</div>
<div>{
{
firstname}}--{
{
lastname}}</div>
</div>
条件付きレンダリング
1. v-if (単独で使用可能)、式が true の場合、v-if 属性を使用して要素をレンダリングし、それ以外の場合は v-else を使用してレンダリングします。
2. v-show (CSS スタイルで表示属性を切り替える)、CSS スタイルを頻繁に切り替える、v-show を使用する**
v-if と v-for を一緒に使用することはお勧めできません。v-if が v-for とともに使用される場合、v-for は v-if よりも優先されます。
*****
v-show 与 v-if 的区别 : v-show 不支持 v-else v-show 不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。 v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。 v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做;直到条件第一次变为真时,才会开始渲染条件块。 v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
v-if は要素/ラベルの追加または削除に対応します。
条件が
満たされる場合は要素を追加します。条件が満たされない場合は要素を削除します。v -show は
要素の CSS スタイルの表示属性に対応します。display
:ブロックは
要素の非表示表示に対応する条件を満たしていません: なし
CSS スタイルを頻繁に切り替えるために v-show が使用されています
### javascript代码
new Vue({
el:"#app",
data:{
type:'email',
animal:['老虎','大象','狮子'],
isShow:false
}
})
### html代码
<button @click="type='email'">点我获取email</button>
<button @click="type='telephone'">点我获取telephone</button>
<div v-if="type=='email'">
<form>
<input type="text" placeholder="请输入email">
</form>
</div>
<div v-else-if="type==='telephone'">
<form >
<input type="text" placeholder="请输入telephone">
</form>
</div>
<div v-else>错误</div>
<ul v-show="">
<li v-for="item in animal" :key="item">{
{
item}}</li>
</ul>
</div>
リストレンダリング v-for
リストデータをレンダリングするために使用されます。v-for ディレクティブには、items 内の item という形式の特殊な構文が必要です。items はソース データ配列、item は反復される配列要素のエイリアスです。
*** 鍵
Vue は要素を可能な限り効率的にレンダリングし、多くの場合、要素を最初からレンダリングするのではなく、既存の要素を再利用します。これを行うと、Vue が非常に高速になります。ただし、vue を再利用したくない場合もありますが、このとき、Vue は「これら 2 つの要素は完全に独立しているため、再利用しないでください」を表現する方法を提供します。一意の値を持つキーを追加するだけです
### html代码
<ul>
<li v-for='(item,index) in animal' :key='item'>
{
{
index+1}}-{
{
item}}-{
{
index}}
</li>
</ul>
### js代码
new Vue({
el:'#app',
data(){
return {
animal:['大笨象','小猴子','狐狸'],
}
}
})
スタイルバインディング
要素のクラス リストとインライン スタイルの操作は、データ バインディングの一般的な要件です。これらはすべて属性であるため、v-bind を使用してそれらを処理できます。式を通じて文字列の結果を計算するだけです。ただし、文字列の連結は面倒でエラーが発生しやすくなります。したがって、Vue では、クラスとスタイルに v-bind を使用する場合に特別な機能強化が行われました。式の結果の型は、文字列のほかにオブジェクトまたは配列にすることもできます。
### html代码
<div :style="styleObj">Hello</div>
<div :style="{color:currentColor}">World</div>
<div :style="[styleObj2,styleObj]"> hello world</div>
### css代码
new Vue({
el: '#app',
data: {
currentColor: 'blue',
styleObj: {
color: 'red',
"font-size": '30px',
},
styleObj2: {
background: 'pink',
color: 'blue'
}
},
})
クラスバインディング
要素のクラス リストとインライン スタイルの操作は、データ バインディングの一般的な要件です。これらはすべて属性であるため、v-bind を使用してそれらを処理できます。式を通じて文字列の結果を計算するだけです。ただし、文字列の連結は面倒でエラーが発生しやすくなります。したがって、Vue では、クラスとスタイルに v-bind を使用する場合に特別な機能強化が行われました。式の結果の型は、文字列のほかにオブジェクトまたは配列にすることもできます。
### css样式
.red {
color: red;
}
.size {
font-size: 30px;
}
### html代码
<div id="app">
<div class="red" :class="{size:true}">Hello</div>
<div :class="{red:false,size:true}">World</div>
<div :class="[{red:true},{size:false}]">hello World</div>
</div>
### js代码
new Vue({
el: '#app',
data: {
},
})
********* [インタビューの質問: 大規模プロジェクトではデータがオブジェクトではなく関数である理由]
组件是一个可复用的实例,当你引用一个组件的时候,组件里的data是一个普通的对象,所有用到这个组件的都引用的同一个data,就会造成数据污染。
不使用return包裹的数据会在项目的全局可见,会造成变量污染;
使用return包裹后数据中变量只在当前组件中生效,不会影响其他组件。
当一个组件被定义, data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
//1、在简单的vue实例中看到的Vue实例中data属性,如下所示:
<script>
let vm=new Vue({
el:'',
data:{
},//数据可以直接挂在vue实例上
methods:{
}
})
</script>
//2、在使用组件化的项目中,如下所示:
//每一个.vue文件中都对应一个vue组件实例,该vue组件实例的构造函数参数由当前页面的export default提供
<script>
export default{
data(){
return {
}
},
methods:{
}
</script>
「」
v-for を使用する場合は、対応する要素またはコンポーネントに :key 属性を追加することが公式に推奨されています。
なぜこのキー属性が必要なのでしょうか (理解してください)。
これは実際には、Vue の仮想 DOM の Diff アルゴリズムに関連しています。
レイヤー内に同じノード、つまりリストノードが多数ある場合、新しいノードを挿入したい
- B と C の間に F を追加でき、Diff アルゴリズムがデフォルトでこのように実行されることを望みます。
- つまり、C を F に、D を C に、E を D に更新し、最後に E を挿入するのは、非常に非効率ではないでしょうか。
したがって、キーを使用して各ノードを一意に識別する必要があります
-
Diff アルゴリズムはこのノードを正しく識別できます
-
新しいノードを挿入するための正しいロケーション領域を見つけます。