<script src="https://unpkg.com/vue@next"></script>
dom 指向プログラミングからデータ指向プログラミングへ
表示リストを入力してください
const app=Vue.createApp({
data(){
return{
inputValue:'',
list:[]
}
},
methods:{
handleAddItem(){
this.list.push(this.inputValue);
this.inputValue='';
}
},
template:
`
<div>
<input v-model="inputValue" />
<button
v-on:click="handleAddItem"
v-bind:title="inputValue">
增加
</button>
<ul>
<todo-item v-for="(item,index) of list" v-bind:content="item" v-bind:index="index"/>
<ul>
</div>
`
});
app.component('todo-item',{
props:['content','index'],
template:'<li>{
{index}}--{
{content}}</li>'
});
app.mount('#root');
逆文字列
Vue.createApp({
data(){
return{
str:'hello world'
}
},
methods:{
handleReverse(){
this.str=this.str.split('').reverse().join('');
}
},
template:
`
<div>
{
{str}}
<button v-on:click="handleReverse">反转字符串</button>
</div>
`
}).mount('#root');
createApp は、Vue アプリケーションを作成し、それを app 変数に保存することを意味します
渡されるパラメータは、アプリケーションの最も外側のコンポーネントをどのように表示するかを示します。
MVVM デザイン パターン、M->モデル データ、V->View ビュー、VM->ViewModel ビュー データ接続
ライフサイクル機能 (8)
// 生命周期函数 在某一时刻自动执行的函数
const app = Vue.createApp({
data() {
return {
message: 'hello world'
}
},
beforeCreate(){
// 在实例生成之前自动执行的函数
console.log('beforeCreate');
},
created(){
// 在实例生成之后自动执行的函数
console.log('created');
},
beforeMount(){
// 在组件内容被渲染到页面之前自动执行的函数
console.log(document.getElementById('root').innerHTML,'beforeMounted');
},
mounted(){
// 在组件内容被渲染到页面之后自动执行的函数
console.log(document.getElementById('root').innerHTML,'mounted');
},
beforeUpdate(){
// 在data中数据发生变化时,自动执行的函数
console.log(document.getElementById('root').innerHTML,'beforeUpdate');
},
updated(){
// 在data中数据发生变化时,且重新渲染页面后,自动执行的函数
console.log(document.getElementById('root').innerHTML,'updated');
},
beforeUnmount(){
// 当Vue应用(实例)失效时,自动执行的函数
console.log(document.getElementById('root').innerHTML,'beforeUnmount');
},
unmounted(){
// 当Vue应用(实例)失效时,且DOM完全销毁之后,自动执行的函数
console.log(document.getElementById('root').innerHTML,'unmounted');
},
template: `<div>{
{message}}</div>`
});
const vm=app.mount('#root');
補間式{ {}}
const app = Vue.createApp({
data() {
return {
message: '<strong>hello world</strong>'
}
},
template: `<div>{
{message}}</div>`
});
const vm=app.mount('#root');
結果には html タグを含む変数が表示されます。太字の変数を表示したい場合は、テンプレートにv-html コマンドを追加する必要があります。
const app = Vue.createApp({
data() {
return {
message: '<strong>hello world</strong>'
}
},
template: `<div v-html="message"></div>`
});
const vm=app.mount('#root');
title属性を追加するにはv-bindコマンドを追加する必要がありますが、このときページ上のhello worldの上にマウスを置くとhello worldのタイトルが表示されます。
v-bind: タイトルの省略形: タイトル
const app = Vue.createApp({
data() {
return {
message: 'hello world'
}
},
template: `<div v-bind:title="message">hello world</div>`
});
const vm=app.mount('#root');
v-bind を入力ボックスと組み合わせて使用することもできます。
const app = Vue.createApp({
data() {
return {
disable:false
}
},
template: `<input v-bind:disabled="disable"/>`
});
const vm=app.mount('#root');
注: テンプレートでは v-once ディレクティブを使用して、変数が初回の値のみをレンダリングし、その後変数の値を変更しても変更に従わないようにすることができます。
イベント バインディング v-on:click() 省略形 @click
動的プロパティを結合します: [変数]
const app = Vue.createApp({
data() {
return {
message:'hello world',
name:'title',
event:'click'
}
},
methods:{
handleClick(){
alert('click');
}
},
template: `<div :[name]="message" @[event]="handleClick">{
{message}}</div>`
});
const vm=app.mount('#root');
デフォルトの動作を防止 @click.prevent="handleClick"
const app = Vue.createApp({
data() {
return {
message:'hello world'
}
},
methods:{
handleClick(){
alert('click');
//e.preventDefault();
}
},
template:
`
<form action="http://www.baidu.com" @click.prevent="handleClick">
<button type="submit">提交</button>
</form>
`
});
const vm=app.mount('#root');
計算された計算されたプロパティ
const app = Vue.createApp({
data() {
return {
message:'hello world'
}
},
computed:{
// 当计算属性依赖的内容发生变化时,方法才会重新执行计算
total(){
return Date.now();
}
},
methods:{
// 只要页面重新渲染,方法就会执行
formatString(string){
return string.toUpperCase();
},
getTotal(){
return Date.now();
}
},
template:
`
<div>{
{formatString(message)}} {
{total}}</div>
<div>{
{formatString(message)}} {
{getTotal()}}</div>
`
});
const vm=app.mount('#root');
リスナー監視 (通常、非同期操作に使用) (対応するプロパティの監視)
const app = Vue.createApp({
data() {
return {
message:'hello world',
count:2,
price:5,
newTotal:10
}
},
// 监听器
watch:{
// 当价格发生变化才会执行的函数
price(current,prev){
this.newTotal= current*this.count;
}
},
computed:{
// 当计算属性依赖的内容发生变化时,方法才会重新执行计算 建议使用因为有缓存、简洁
total(){
return this.price*this.count;
}
},
methods:{
// 只要页面重新渲染,方法就会执行
formatString(string){
return string.toUpperCase();
},
getTotal(){
return this.price*this.count;
}
},
template:
`
<div>{
{formatString(message)}} {
{total}}</div>
<div>{
{formatString(message)}} {
{getTotal()}}</div>
<div>{
{formatString(message)}} {
{newTotal}}</div>
`
});
const vm=app.mount('#root');
文字列のスタイルを変更する
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lesson 5</title>
<script src="https://unpkg.com/vue@next"></script>
<style>
.red{
color: red;
}
.green{
color: green;
}
.blue{
color: blue;
}
.brown{
color: brown;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 改变样式
// 1字符串/2对象/3数组
const app = Vue.createApp({
data(){
return{
classString:'green',
classObject:{
'red':true,
'green':true,
'blue':true
},
classArray:['red','blue','green',{brown:true}]
}
},
template:
`
<div :class="classString">Hello World</div>
<div :class="classArray">Hello World</div>
<div :class="classObject">Hello World</div>
`
});
const vm=app.mount('#root');
</script>
</html>
親要素には複数の子要素が含まれています。 注: $attrs.class は
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lesson 5</title>
<script src="https://unpkg.com/vue@next"></script>
<style>
.red{
color: red;
}
.green{
color: green;
}
.blue{
color: blue;
}
.brown{
color: brown;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 改变样式
// 1字符串/2对象/3数组
const app = Vue.createApp({
data(){
return{
classString:'red',
classObject:{
'red':true,
'green':true,
'blue':true
},
classArray:['red','blue','green',{brown:false}]
}
},
template:
`
<div :class="classString">
Hello World
<demo class="green" />
</div>
`
});
app.component('demo',{
template:
`
<div :class="$attrs.class">one</div>
<div>two</div>
`
});
const vm=app.mount('#root');
</script>
</html>
インラインスタイルの使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>lesson 5</title>
<script src="https://unpkg.com/vue@next"></script>
<style>
.red{
color: red;
}
.green{
color: green;
}
.blue{
color: blue;
}
.brown{
color: brown;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
// 改变样式
// 1字符串/2对象/3数组
const app = Vue.createApp({
data(){
return{
classString:'red',
classObject:{
'red':true,
'green':true,
'blue':true
},
classArray:['red','blue','green',{brown:false}],
styleString:'color:yellow;background:orange',
// 行内样式我们使用对象存储可读性更高
styleObject:{
color:'orange',
background:'purple'
}
}
},
template:
`
<div :style="styleObject">
Hello World
</div>
`
});
app.component('demo',{
template:
`
<div :class="$attrs.class">one</div>
<div>two</div>
`
});
const vm=app.mount('#root');
</script>
</html>
v-ifとv-showの違い
const app = Vue.createApp({
data(){
return{
show:false
}
},
template:
`
<div v-if="show">Hello World</div>
<div v-show="show">Bye World</div>
`
});
const vm=app.mount('#root');
要素を頻繁に変更する必要がある場合は、要素が破壊されないため、v-show の使用をお勧めします。
const app = Vue.createApp({
data(){
return{
conditionOne:false,
conditionTwo:true
}
},
template:
`
<div v-if="conditionOne">if</div>
<div v-else-if="conditionTwo">else if</div>
<div v-else>else</div>
`
});
const vm=app.mount('#root');
v-使用目的
配列とオブジェクトの使用注: v-for の優先度は v-if よりも高いため、判断したい場合はタグをネストする必要がありますが、この時点で余分な div タグがあることがわかりました。ちょっとしたトリックを使って外側の div タグを置き換えます。テンプレート タグのプレースホルダーに相当します。
const app = Vue.createApp({
data(){
return{
listArray:['dell','lee','teacher'],
listObject:{
firstName:'dell',
lastName:'lee',
job:'teacher'
}
}
},
methods:{
handleAddBtnClick(){
// 1使用数组的变更函数
//this.listArray.push('hello');结尾增加
//this.listArray.pop();结尾删除
//this.listArray.shift();开头删除
//this.listArray.unshift('hello');//开头增加
// this.listArray.reverse();
// 2直接替换数组
// this.listArray=['bye','world'];
// this.listArray=['bye','world'].filter(item=>item==='bye');
// 3更新数组内容
// this.listArray[1]='bye';
this.listObject.age=100;
this.listObject.sex='male';
}
},
template:
`
<div>
<template v-for="(value,key,index) in listObject" :key="index">
<div v-if="key!=='lastName'">
{
{value}}--{
{key}}--{
{index}}
</div>
</template>
<div v-for="item in 10">{
{item}}</div>
<button @click="handleAddBtnClick">新增</button>
</div>
`
});
const vm=app.mount('#root');
イベント
複数の関数を呼び出す場合、以前のように参照名を直接記述することはできませんが、有効にするには () カンマを追加して区切る必要があります。
const app = Vue.createApp({
data(){
return{
counter: 0
}
},
methods:{
handleBtnClick(num,event){
console.log(event.target);
this.counter+=num;
}
},
template:
`
<div>
{
{counter}}
<button @click="handleBtnClick(2,$event)">新增</button>
</div>
`
});
const vm=app.mount('#root');
const app = Vue.createApp({
data(){
return{
counter: 0
}
},
methods:{
handleBtnClick(){
alert('1');
},
handleBtnClick1(){
alert('2');
},
},
template:
`
<div>
{
{counter}}
<button @click="handleBtnClick(),handleBtnClick1()">新增</button>
</div>
`
});
const vm=app.mount('#root');
バブリングの停止 (外部への伝播) @click.stop
const app = Vue.createApp({
data(){
return{
counter: 0
}
},
methods:{
handleBtnClick(){
this.counter+=1;
},
handleDivClick(){
alert('div click');
}
},
template:
`
<div>
{
{counter}}
<div @click="handleDivClick">
<button @click.stop="handleBtnClick">新增</button>
</div>
</div>
`
});
const vm=app.mount('#root');
自分のラベルをクリックして @click.self を表示します
const app = Vue.createApp({
data(){
return{
counter: 0
}
},
methods:{
handleBtnClick(){
this.counter+=1;
},
handleDivClick(){
alert('div click');
}
},
template:
`
<div>
<div @click.self="handleDivClick">
{
{counter}}
<button @click="handleBtnClick">新增</button>
</div>
</div>
`
});
const vm=app.mount('#root');
イベント修飾子: ラベル @click.prevent はデフォルトの動作が発生しないことに注意してください。@click.capture キャプチャ フェーズ (外側から内側) はデフォルトでバブリング フェーズ (内側から外側) になり、@click.once はクリックのみ可能です。一度
キーとマウスの修飾子
按键:enter、tab、delete、esc、上、下、左、右
マウス: 左、右、中央
const app = Vue.createApp({
data(){
return{
counter: 0
}
},
methods:{
handleKeyDown(){
console.log('keydown');
}
},
template:
`
<div>
<input @keydown.delete="handleKeyDown"/>
</div>
`
});
const vm=app.mount('#root');
const app = Vue.createApp({
data(){
return{
counter: 0
}
},
methods:{
handleClick(){
console.log('click');
}
},
template:
`
<div>
<div @click="handleClick">123</div>
</div>
`
});
const vm=app.mount('#root');
双方向バインディング
チェックボックス チェックボックスとシングル ボタン ラジオ
// input,textarea,checkbox,radio
const app = Vue.createApp({
data(){
return{
message:[]
}
},
template:
`
<div>
{
{message}}
jack <input type="checkbox" value="jack" v-model="message"/>
jessica <input type="checkbox" value="jessica" v-model="message"/>
karry <input type="checkbox" value="karry" v-model="message"/>
</div>
`
});
const vm=app.mount('#root');
// input,textarea,checkbox,radio
const app = Vue.createApp({
data(){
return{
message:''
}
},
template:
`
<div>
{
{message}}
jack <input type="radio" value="jack" v-model="message"/>
jessica <input type="radio" value="jessica" v-model="message"/>
karry <input type="radio" value="karry" v-model="message"/>
</div>
`
});
const vm=app.mount('#root');
リストボックス
const app = Vue.createApp({
data(){
return{
message:[],
options:[{
text:'A',value:{value:'A'}
},{
text:'B',value:{value:'B'}
},{
text:'C',value:{value:'C'}
}]
}
},
template:
`
<div>
{
{message}}
<select v-model="message" multiple>
<option v-for="item in options" :value="item.value">{
{item.text}}</option>
</select>
</div>
`
});
const vm=app.mount('#root');
const app = Vue.createApp({
data(){
return{
message:'world',
}
},
template:
`
<div>
{
{message}}
<input type="checkbox" v-model="message" true-value="hello" false-value="world"/>
</div>
`
});
const vm=app.mount('#root');
world は選択されていない値を表します
注: v-model.lazy などの入力ボックスからマウスを移動し、外側をクリックして両方向にバインドします。 v-model-trim は文字列の先頭と末尾のスペースを削除します。