Vue2 学习记录--语法部分

学习资源--Vue2官网

Vue2停更后,发现官网原来的学习路径变成英文了,所以找到了中文简介进行学习:

简介 | Vue.js https://cn.vuejs.org/guide/introduction

一、模板语法

1.1 文本插值、html插值、属性和使用限制

在about组件中写测试代码。不废话,直接上代码。

<template>
  <div class="about">
    <h1>This is an about page</h1>
    {{ msg }}
    <div v-html="htmTxt"></div>
    <div v-bind:id="id" >百度</div>
    <div :id="id" >百度</div>
    <p>{{ count + 1 }}</p>
  </div>
</template>

<script>
export default {
  name: 'HomeView',
  data() {
    return {
      msg: '<h2>静态文本</h2>',
      htmTxt:'<h2>静态文本</h2>',
      id: '1234',
      attr: 'test-id',
      count: 0,
    }
  },  
  components: {     
  }
}
</script>

使用限制:

1、插值仅限于表达式。

2、关于缩写,当属性和属性名称相同时,比如 属性id,属性名称id,可以写成 :id, Vue2不支持。

1.2 简单的事件,用于测试语法

<template>
  <div class="about">
    <h1>This is an about page</h1>
    {{ msg }}
    <div v-html="htmTxt"></div>
    <div v-bind:id="id" >百度1</div>
    <div :id="id" >百度2</div>
    <div :testid = "testid">动态属性绑定</div>
    <p>{{ count + 1 }}</p>
    <p @click="myclick()">事件测试</p>
  </div>
</template>

<script>
export default 
{
  name: 'HomeView',
  data() {
    return {
      msg: '<h2>静态文本</h2>',
      htmTxt:'<h2>静态文本</h2>',
      id: '1234',
      testid: 'testid',
      count: 0,
    }
  },  
  methods: 
  {
     myclick() {
      this.count += 1;
      console.log('点击事件');
    var s = document.getElementById("1234").innerHTML;
    alert(s)
     }

  },
  components: {     
  }
}
</script>

1.3 指令:v-if、v-else、v-show

使用这几个指令控制dom显示,代码:

<template>
  <div class="about">
    <h1>This is an about page</h1>
    {{ msg }}
    <div v-html="htmTxt"></div>
    <div v-bind:id="id" >百度1</div>
    <div :id="id" >百度2</div>
    <div :testid = "testid">动态属性绑定</div>
    <p>{{ count + 1 }}</p>
    <p @click="myclick()">控制Dom显示</p>
    <div v-if="count % 2 == 0">count是偶数</div>
    <div v-else>count是奇数</div>
    <div v-show="count % 2 == 0">v-show:count是偶数时显示</div>
  </div>
</template>

<script>
export default 
{
  name: 'HomeView',
  data() {
    return {
      msg: '<h2>静态文本</h2>',
      htmTxt:'<h2>静态文本</h2>',
      id: '1234',
      testid: 'testid',
      count: 0,
    }
  },  
  methods: 
  {
     myclick() {
      
      console.log('点击事件');
      var s = document.getElementById("1234").innerHTML;
      alert(s)
      this.count += 1;
     }

  },
  components: {     
  }
}
</script>

心得:

1、v-if 和 v-show都实现了dom元素的渲染控制,他们的差别是:v-if 是真正控制了dom内容的输出,即dom中有就显示没有就不显示;而v-show是通过display:none来控制元素的显示的。

2、<div v-if>模块如果使用 <template v-if >来替换,可以消除本身模块在dom中的占位。

1.4 指令:v-for

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <ul>
      <li v-for="student in students" :key="student.idx">
        {{ student.idx }} - {{ student.name }} - {{ student.age }}岁
      </li>
    </ul>
  </div>
</template>

<script>
export default 
{
  name: 'HomeView',
  data() {
    return {
    
      students: [
        {idx:'1', name: '张三', age: 18 },
        {idx:'2', name: '李四', age: 19 },
        {idx:'3', name: '王五', age: 20 }
      ]
    }
  },  
 
  components: {     
  }
}
</script>

1.5 指令 v-mode

绑定表单数据。

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <ul>
      <li v-for="student in students" :key="student.idx">
        {{ student.idx }} - {{ student.name }} - {{ student.age }}岁
      </li>
    </ul>
    <button @click="$router.push('/')">Go to Home</button>
    <input type="text" v-model.lazy="students[0].name" placeholder="修改第一个学生的名字"/> 
    <input type="number" v-model.number="students[0].age" placeholder="修改第一个学生的年龄"/>
    <div>
      <span>第一个学生的信息:</span>
      <span>{{ students[0].idx }} - {{ students[0].name }} - {{ students[0].age }}岁</span>
    </div>
    <button @click="students.push({idx: students.length + 1 + '', name: '新学生', age: 18})">添加新学生</button>
  </div>
</template>

<script>
export default 
{
  name: 'HomeView',
  data() {
    return {
    
      students: [
        {idx:'1', name: '张三', age: 18 },
        {idx:'2', name: '李四', age: 19 },
        {idx:'3', name: '王五', age: 20 }
      ]
    }
  },  
  methods: {

  },
  components: {     
  }
}
</script>

心得:

1、v-mode与绑定的数据是同步更新的。为了让数据在事件后更新,使用v-mode.lazy。

2、修饰符有三个:.lazy、number、trim。

1.6 方法(methods)、计算属性(computed)和侦听器(watch)

<template>
  <div class="about">
    <h1>This is an about page</h1>
      
    <h3>价格计算</h3>
    单价:<input type="number" v-model.number="price" placeholder="输入价格"/> 
数量:<input type="number" v-model.number="quantity" placeholder="输入数量"/>
<button @click="price = 1; quantity = 1;">reset</button>
    <div>
      <span>总价:</span>
      <span>函数计算:{{ getSum()}}</span> <span>计算属性{{ calcSum }}</span>
    </div>
  </div>
 </template>

<script>
export default 
{
  name: 'HomeView',
  data() {
    return {
      price: 1,
      quantity: 1,
    }
  },  
  methods: {
     getSum() {
      return this.price * this.quantity;
    }

  },
  computed: {
    calcSum() {
      return this.price * this.quantity;
    } 
    
  },
  watch: {
    price(newVal, oldVal) {
      console.log(`price changed from ${oldVal} to ${newVal}`);
    },
    
  },  
  components: {     
  }
}
</script>

心得:

1、插值表达式、函数计算和计算属性都可以。计算属性的优点:当数据没有发生变化时,不会重新计算。

1.7 v-bind 之 class与style绑定

<template>
  <div class="about">
    <h1>This is an about page</h1>
      
    <h3>价格计算</h3>
    单价:<input type="number" v-model.number="price" placeholder="输入价格"/> 
数量:<input type="number" v-model.number="quantity" placeholder="输入数量"/>
<button @click="price = 1; quantity = 1;">reset</button>
    <div>
      <span>总价:</span>
      <span>函数计算:{{ getSum()}}</span> <span>计算属性{{ calcSum }}</span>
    </div>

    <div><span>绑定样式</span><br/> 
      <div :class="{ active: price > 5 }">
        价格大于5元时显示红色,否则显示绿色
      </div>
    </div>
  </div>

 </template>

<script>
export default 
{
  name: 'HomeView',
  data() {
    return {
      active: 'active',
      price: 1,
      quantity: 1,
    }
  },  
  methods: {
     getSum() {
      return this.price * this.quantity;
    }

  },
  computed: {
    calcSum() {
      return this.price * this.quantity;
    } 
    
  },
  watch: {
    price(newVal, oldVal) {
      console.log(`price changed from ${oldVal} to ${newVal}`);
    },
    
  },  
  components: {     
  }
}
</script>

心得:

可以绑定对象、数组、数组对象。

二、组件

2.1 组件基础

1、组件由html模板、js脚本和css三部分组成。

2、html模板内只能使用一个div。

3、组件目的是为了重用。一个页面可以在多个地方引用同一个组件。

4、组件是独立的,各组件内的数据互不相关。

5、所以data必须是函数

6、页面和组件之间传递数据:props。父传子。

7、组件可以通过事件向页面传递数据。子传父。

8、插槽。

2.2 第一个组件Hello.vue

Show me your code.

第一个组件hello.vue

<template>
<div  class="hello">
<h1>Vue2 component</h1>	
</div>
</template>

<script>
export default {
name: 'HelloView',
data() {
return {}
}, 
methods: {
}, 
components: {
}
}
</script>

<style scoped>
</style>

在about中引入hello.vue:

step1 import Hello from '@/components/Hello.vue';

step2 components: { Hello,  }

step3 在所需处使用组件:<Hello/>   

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <Hello/>
    <Hello/>
    <Hello/>     
  </div>
</template>

<script>
import Hello from '@/components/Hello.vue'; 
export default 
{
  name: 'AboutView',
  data() {
    return {
    
    }
  },  
  methods: {

  },
  components: {    
    Hello,
  }
}
</script>

2.3 父页面通过props向组件传递数据

父页面代码:

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <Hello name="张三" code="007" :id='1'/>
    <Hello name="李四" code="008" id='2'/>
    <Hello/>     
  </div>
 </template>
<script>
import Hello from '@/components/Hello.vue'; 
export default 
{
  name: 'AboutView',
  data() {
    return {
    
    }
  },  
  methods: {

  },
  components: {    
    Hello,
  }
}
</script>

子组件代码:

<template>
<div  class="hello">
<h1>Vue2 component</h1>	
<p>id: {{ id }}</p>
<p>{{ code }}</p>
<p>name: {{ name }}</p>
</div>
</template>

<script>
export default {
name: 'HelloView',
data() {
    return {
        
     }
}, 
methods: {
}, 
components: {
},
props: {
    id: {
        type: Number,
        default: 0
    },
    code: {
        type: String,
        default: ''
    },
    name: {
        type: String,
        default: ''
    }      
}
}
</script>

<style scoped>
</style>

注意:

1、data函数内不要再声明相同的变量了。

2、注意,id=“2”传递的是字符串,props验证会有错误:vue.runtime.esm.js:4482 [Vue warn]: Invalid prop: type check failed for prop "id". Expected Number with value 2, got String with value "2".

2.4 组件通过事件向父页面传递数据

组件代码:

<template>
<div  class="hello">
<h1>Vue2 component</h1>	
<p>id: {{ id }}</p>
<p>{{ code }}</p>
<p>name: {{ name }}</p>
<button @click="myPostMsg">向父页面发送数据</button> 
</div>
</template>

<script>
export default {
name: 'HelloView',
data() {
    return {
        
     }
}, 
methods: {
    myPostMsg() {
      this.$emit('helloMsg', this.name); 
    }
}, 
components: {
},
props: {
    id: {
        type: Number,
        default: 0
    },
    code: {
        type: String,
        default: ''
    },
    name: {
        type: String,
        default: ''
    }      
}
}
</script>

<style scoped>
</style>

父页面代码:

<template>
  <div class="about">
    <h1>This is an about page</h1>
    <Hello name="张三" code="007" :id='1' @helloMsg="doHelloMsg"/>
    <Hello name="李四" code="008" :id='2' @helloMsg="doHelloMsg"/>
    <Hello @helloMsg="doHelloMsg"/>    
    <p>{{ msg }}</p>
  </div>
 </template>
<script>
import Hello from '@/components/Hello.vue'; 
export default 
{
  name: 'AboutView',
  data() {
    return {
       msg: 'who?'
    }
  },  
  methods: {
    doHelloMsg(data) {
      console.log('AboutView 接收到数据:' + data);
      this.msg = '收到子组件传过来的数据:' + data;
    }
    
  },
  components: {    
    Hello,
  }
}
</script>

理解:

1、从c++解耦的角度思考问题。子组件是父页面的组成部分;父页面应该是parent指针存在于子组件中。

2、子组件中定义了一个传数据的回调函数,参数一般是const char*,父页面中定义同样参数的函数,并将函数指针传递给子组件中。子组件在使用发送数据函数就相当于父页面执行已定义的参数是const char* 的函数。

3、根据上面两条规则,我们来看代码实现。

      回调函数名称为 helloMsg, 参数为 字符串。

     子组件中使用点击事件来实现 helloMsg的函数的执行(不必须是点击事件,任何函数都可以,只要“this.$emit('helloMsg', this.name);” 能执行到)。 emit函数执行已注册函数的运行(一般情况下,父页面已经完成函数指针的注册,如果注册函数null则不执行)。

    父页面中通过 <...... @helloMsg="doHelloMsg"/> 绑定回调函数为 doHelloMsg。所以子组件执行已注册函数时相当于执行 父页面的doHelloMsg函数。

总结:

三步走:

1、子组件中某个函数中实现 this.$emit('helloMsg', 需要传递的数据);”  helloMsg是双方的桥梁。

2、父页面在组件使用时,指定绑定的函数。比如 @helloMsg="doHelloMsg"/> 绑定了回调函数为doHelloMsg。

3、父页面中实现doHelloMsg(字符串参数)函数。

2.5 插槽

2.5.1 插槽内容

父页面

......
<Hint>来自父页面的插槽内容</Hint>  
......

插槽组件

<template>
<div  class="hint">
<h1>Hint module</h1>	
<slot>组件的默认提示内容</slot>
</div>
</template>

<script>
export default {
    name: 'HintSlot',
    data() {
    return {}
    }, 
    methods: {
    }, 
    components: {
    }
}
</script>

<style scoped>
</style>
2.5.2 编译作用域
<Hint>来自父页面的插槽内容:{{ msg }}</Hint>  

{{ msg }} 虽然显示在slot组件中,但是编译作用域在父页面

2.5.3 后备内容

<Hint></Hint> 时显示 "组件的默认提示内容"。

<Hint>{{ msg }}</Hint>,且 msg=‘ ’ 时 并不显示 "组件的默认提示内容",而是不显示内容。

2.5.4 具名插槽

父页面

......
<Hint>
      <template v-slot:header>
      <h3>这是头部内容</h3>
      </template>
      <template v-slot:main>
      <p>这是主体内容</p>
      </template>
      <template v-slot:footer>
      <h3>这是底部内容</h3>
      </template>
</Hint>      
......

插槽组件

<template>
<div  class="hint">
    <h1>Hint module</h1>	
    <slot name="header">Header</slot>
    <hr/>
    <slot name="main">main content</slot>
    <hr/>
    <slot name="footer">footer</slot>
</div>
</template>
2.5.5 作用域插槽

父页面

......
<template v-slot:default="slotProps" >
        <h2>from slot id: {{ slotProps.id }}</h2>
</template>
......

插槽组件

<template>
<div  class="hint">
    <h1>Hint module</h1>	
    <slot name="header">Header</slot>
    <hr/>
    <slot name="main" :id="id">main content</slot>
    <hr/>
    <slot name="footer">footer</slot>
    <hr/>
    <slot :id="id">id</slot>
</div>
</template>

<script>
export default {
    name: 'HintSlot',
    data() {
    return {
        id:"007"
    }
    }, 
    methods: {
    }, 
    components: {
    }
}
</script>

<style scoped>
</style>

理解:

插槽中的数据,传递给父页面处理后返回。

2.5.6 动态插槽名

这个不常用。

2.6 动态组件&异步组件

1、动态引用组件

......
//import Hello from '@/components/Hello.vue'; 
const Hello = () =>import('@/components/Hello.vue');
......

2、$root

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值