博客列表 >Vue2 基础语法

Vue2 基础语法

Lon
Lon原创
2021年11月03日 20:03:21968浏览

Vue2 基础语法

了解更多详情请访问 https://cn.vuejs.org/v2/guide/index.html

视频教程 https://www.bilibili.com/video/BV1Zy4y1K7SH

一、Vue 安装

官方手册给出了多种安装方式,这里列出两种

CDN

  1. <!-- 开发环境版本,包含了有帮助的命令行警告 -->
  2. <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  3. <!-- 生产环境版本,优化了尺寸和速度 -->
  4. <script src="https://cdn.jsdelivr.net/npm/vue"></script>

NPM

  1. npm install vue

二、初识Vue

学习阶段,推荐使用第一种,不过,我们直接使用下载版本就好,防止断网;

1.想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象;

2.root容器里的代码依然符合html规范,只不过混入了一些特殊的Vue语法;

3.root容器里的代码被称为【Vue模板】;

4.Vue实例和容器是一一对应的;

5.真实开发中只有一个Vue实例,并且会配合着组件一起使用;

6.{{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性;

7.一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新;

  1. <div id="app">
  2. {{message}}
  3. </div>
  4. <script src="../js/vue.js"></script>
  5. <script>
  6. //阻止 vue 在启动时生成生产提示。
  7. Vue.config.productionTip = false;
  8. const app = new Vue({
  9. el : '#app',
  10. data : {
  11. message : 'Hello, Vue!'
  12. }
  13. });
  14. </script>

三、模板语法

Vue模板语法有2大类:
1.插值语法:
功能:用于解析标签体内容。
写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。
2.指令语法:
功能:用于解析标签(包括:标签属性、标签体内容、绑定事件…..)。
举例:v-bind:href="xxx"或 简写为 :href="xxx",xxx同样要写js表达式,
且可以直接读取到data中的所有属性。
备注:Vue中有很多的指令,且形式都是:v-????,此处只是拿v-bind举个例子。

  1. <div id="root">
  2. <h1>插值语法</h1>
  3. <h3>你好 {{name}}</h3>
  4. <hr/>
  5. <h1>指令语法</h1>
  6. <a v-bind:href="school.url" x="hello">点我去{{school.name}}学习1</a>
  7. <a :href="school.url">点我去{{school.name}}学习2</a>
  8. </div>
  9. <script>
  10. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  11. new Vue({
  12. el:'#root',
  13. data:{
  14. name:'jack',
  15. school:{
  16. name:'百度',
  17. url:'http://www.baidu.com',
  18. }
  19. }
  20. })
  21. </script>

四、数据绑定

Vue中有2种数据绑定的方式:
1.单向绑定(v-bind):数据只能从data流向页面。
2.双向绑定(v-model):数据不仅能从data流向页面,还可以从页面流向data。
备注:
1.双向绑定一般都应用在表单类元素上(如:inputselect等)
2.v-model:value 可以简写为 v-model,因为v-model默认收集的就是value值。

  1. <div id="root">
  2. <!-- 普通写法 -->
  3. <!-- 单向数据绑定:<input type="text" v-bind:value="name"><br/>
  4. 双向数据绑定:<input type="text" v-model:value="name"><br/> -->
  5. <!-- 简写 -->
  6. 单项数据绑定:<input type="text" :value="name"><br/>
  7. 双向数据绑定:<input type="text" v-model="name"><br/>
  8. <!-- 如下代码是错误的,因为v-model只能应用再表单类元素(输入类元素)上 -->
  9. <!-- <h2 v-model:x="name">你好啊</h2> -->
  10. </div>
  11. <script>
  12. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  13. new Vue({
  14. el:'#root',
  15. data:{
  16. name:'张三'
  17. }
  18. })
  19. </script>

五、el和datad的两种写法

datael的2种写法:
1.el有2种写法
(1).new Vue时候配置el属性。
(2).先创建Vue实例,随后再通过vm.$mount('#root')指定el的值。
2.data有2种写法
(1).对象式
(2).函数式
如何选择:目前哪种写法都可以,以后学习到组件时,data必须使用函数式,否则会报错。
3.一个重要的原则:
Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了。

  1. <div id="root">
  2. <h1>你好,{{name}}</h1>
  3. </div>
  4. <script>
  5. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  6. //el的两种写法
  7. // const vm = new Vue({
  8. // el:'#root',//第一种写法
  9. // data:{
  10. // name:'zhangsan'
  11. // }
  12. // })
  13. // console.log(vm)
  14. // vm.$mount("#root")//第二种写法
  15. new Vue({
  16. el:'#root',
  17. //data的第一种写法,对象式
  18. // data:{
  19. // name:'zhangsan'
  20. // }
  21. //data的第二种写法,函数式
  22. data(){
  23. console.log('@@@',this)//此处的this是Vue实例对象
  24. return{
  25. name:'zhangsan'
  26. }
  27. }
  28. })
  29. </script>

六、事件处理器

1、事件的基本使用

1.使用v-on:xxx@xxx 绑定事件,其中xxx是事件名;
2.事件的回调需要配置在methods对象中,最终会在vm上;
3.methods中配置的函数,不要用箭头函数!否则this就不是vm了;
4.methods中配置的函数,都是被Vue所管理的函数,this的指向是vm 或 组件实例对象;
5.@click="demo"@click="demo($event)" 效果一致,但后者可以传参;

  1. <div id="root">
  2. <h2>欢迎来到{{name}}学习</h2>
  3. <!-- <button v-on:click="showInfo">点我提示信息</button> -->
  4. <button @click="showInfo1">点我提示信息1(不传参)</button>
  5. <button @click="showInfo2($event,66)">点我提示信息2(传参)</button>
  6. </div>
  7. <script>
  8. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  9. const vm = new Vue({
  10. el:'#root',
  11. data:{
  12. name:'中国',
  13. },
  14. methods:{
  15. showInfo1(event){
  16. console.log(event.target.innerText)
  17. console.log(this)//此处的this是vm
  18. alert('你好!')
  19. },
  20. showInfo2(event,number){
  21. console.log(event , number)
  22. console.log(event.target.innerText)
  23. console.log(this)
  24. alert('你好')
  25. }
  26. }
  27. })
  28. </script>

2、事件修饰符

1.prevent:阻止默认事件(常用);
2.stop:阻止事件冒泡(常用);
3.once:事件只触发一次(常用);
4.capture:使用事件的捕获模式;
5.self:只有event.target是当前操作的元素时才触发事件;
6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

  1. <div id="root">
  2. <h2>欢迎来到{{name}}学习</h2>
  3. <!-- 阻止默认事件(常用) -->
  4. <a href="http://www.baidu.com" @click.prevent="showInfo">点我提示信息</a>
  5. <!-- 阻止事件冒泡(常用) -->
  6. <div class="demo1" @click="showInfo">
  7. <button @click.stop="showInfo">点我提示信息</button>
  8. <!-- 修饰符可以连续写 -->
  9. <!-- <a href="http://www.baidu.com" @click.prevent.stop="showInfo"></a> -->
  10. </div>
  11. <!-- 事件只触发一次(常用) -->
  12. <button @click.once="showInfo">点我提示信息</button>
  13. <!-- 使用事件的捕获模式 -->
  14. <div class="box1" @click.capture="showMag(1)">
  15. div
  16. <div class="box2" @click="showMag(2)">
  17. div2
  18. </div>
  19. </div>
  20. <!-- 只有event.target是当前操作的元素时才触发事件; -->
  21. <div class=""></div>
  22. </div>
  23. <script>
  24. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  25. const vm = new Vue({
  26. el:'#root',
  27. data:{
  28. name:'中国'
  29. },
  30. methods:{
  31. showInfo(e){
  32. alert('同学你好!')
  33. console.log(e.target)
  34. },
  35. showMag(msg){
  36. console.log(msg)
  37. }
  38. }
  39. })
  40. </script>

2、键盘事件

1.Vue中常用的按键别名:
回车 => enter
删除 => delete (捕获“删除”和“退格”键)
退出 => esc
空格 => space
换行 => tab (特殊,必须配合keydown去使用)
上 => up
下 => down
左 => left
右 => right

2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)

3.系统修饰键(用法特殊):ctrlaltshiftmeta
(1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2).配合keydown使用:正常触发事件。

4.也可以使用keyCode去指定具体的按键(不推荐)

5.Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名

  1. <div id="root">
  2. <h2>欢迎来到{{name}}学习</h2>
  3. <!-- <input type="text" placeholder="按下回车提示输入" @keyup="showInfo"> -->
  4. <!-- <input type="text" placeholder="按下回车提示输入" @keydown="showInfo"> -->
  5. <input type="text" placeholder="按下回车提示输入" @keydown.huiche="showInfo">
  6. </div>
  7. <script>
  8. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  9. Vue.config.keyCodes.huiche = 13 //定义了一个别名按键
  10. new Vue({
  11. el:'#root',
  12. data:{
  13. name:'中国'
  14. },
  15. methods: {
  16. showInfo(e){
  17. // console.log(e.key,e.keyCode)
  18. console.log(e.target.value)
  19. }
  20. },
  21. })
  22. </script>

七、计算属性

计算属性关键词: computed

1.定义:要用的属性不存在,要通过已有属性计算得来。
2.原理:底层借助了Objcet.defineproperty方法提供的gettersetter
3.get函数什么时候执行?
(1).初次读取时会执行一次。
(2).当依赖的数据发生改变时会被再次调用。
4.优势:与methods实现相比,内部有缓存机制(复用),效率更高,调试方便。
5.备注:
1.计算属性最终会出现在vm上,直接读取使用即可。
2.如果计算属性要被修改,那必须写set函数去响应修改,且set中要引起计算时依赖的数据发生改变。

  1. <div id="root">
  2. 姓:<input type="text" v-model="firstName"><br/><br/>
  3. 名:<input type="text" v-model="lastName"><br/><br/>
  4. 全名:<span>{{fullName}}</span>
  5. </div>
  6. <script>
  7. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  8. const vm = new Vue({
  9. el:"#root",
  10. data:{
  11. firstName:"张",
  12. lastName:"三",
  13. },
  14. computed:{
  15. //完整写法(原理)
  16. // fullName:{
  17. // get(){
  18. // console.log('get被调用了')
  19. // return this.firstName + '-' + this.lastName
  20. // },
  21. // set(value){
  22. // console.log('set' , value)
  23. // const arr = value.split('-')
  24. // this.firstName = arr[0]
  25. // this.lastName = arr[1]
  26. // }
  27. // }
  28. //简写
  29. fullName(){
  30. console.log('get被调用了')
  31. return this.firstName + '-' + this.lastName }
  32. }
  33. })
  34. </script>

八、监视属性

监视属性关键字:watch
1.当被监视的属性变化时, 回调函数自动调用, 进行相关操作
2.监视的属性必须存在,才能进行监视!!
3.监视的两种写法:
(1).new Vue时传入watch配置
(2).通过vm.$watch监视

深度监视:
(1).Vue中的watch默认不监测对象内部值的改变(一层)。
(2).配置deep:true可以监测对象内部值改变(多层)。
备注:
(1).Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以!
(2).使用watch时根据数据的具体结构,决定是否采用深度监视。

  1. <div id="root">
  2. <h2>今天天气很{{info}}</h2>
  3. <button @click="changWeaher">切换天气</button>
  4. <hr/>
  5. <h3>a的值是:{{numbers.a}}</h3>
  6. <button @click="numbers.a++">点我让a+1</button>
  7. <h3>b的值是:{{numbers.b}}</h3>
  8. <button @click="numbers.b++">点我让b+1</button>
  9. <h3>e的值是:{{numbers.c.d.e}}</h3>
  10. <button @click="numbers = {a:666,b:888}">彻底替换掉numbers</button>
  11. </div>
  12. <script>
  13. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  14. const vm = new Vue({
  15. el:'#root',
  16. data:{
  17. isHot:true,
  18. numbers:{
  19. a:1,
  20. b:1,
  21. c:{
  22. d:{
  23. e:100
  24. }
  25. }
  26. }
  27. },
  28. computed:{
  29. info(){
  30. return this.isHot ? '炎热' : '凉爽'
  31. }
  32. },
  33. methods: {
  34. changWeaher(){
  35. this.isHot = !this.isHot
  36. }
  37. },
  38. watch:{
  39. isHot:{
  40. // immediate:true, //初始化时让handler调用一下
  41. // handler什么时候调用?当isHot发生改变时。
  42. handler(newValue,oldValue){
  43. console.log('isHot被修改了',newValue,oldValue)
  44. }
  45. },
  46. //简写
  47. // isHot(newValue,oldValue){
  48. // console.log('isHot被修改了',newValue,oldValue,this)
  49. // },
  50. //监视多级结构某个属性的变化
  51. // 'numbers.a':{
  52. // handler(){
  53. // console.log('a被修改了')
  54. // }
  55. // }
  56. numbers:{
  57. // 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
  58. deep:true,
  59. handler(){
  60. console.log('numbers改变了')
  61. }
  62. }
  63. }
  64. })
  65. // 第二种写法
  66. // vm.$watch('isHot',{
  67. // immediate:true,//初始化时让handler调用一下
  68. // deep:true,//深度监视
  69. // handler(newValue,oldValue){
  70. // console.log('isHot被修改了',newValue,oldValue)
  71. // }
  72. // })
  73. //简写
  74. // vm.$watch('isHot',(newValue,oldValue)=>{
  75. // console.log('isHot被修改了',newValue,oldValue,this)
  76. // })
  77. </script>

九、computed和watch之间的区别

1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
两个重要的小原则:
1.所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm 或 组件实例对象。
2.所有不被Vue所管理的函数(定时器的回调函数、ajax的回调函数等、Promise的回调函数),最好写成箭头函数,
这样this的指向才是vm 或 组件实例对象。

  1. <div id="root">
  2. 姓:<input type="text" v-model="firstName"><br><br>
  3. 名:<input type="text" v-model="lastName"><br><br>
  4. 全名:<span>{{fullName}}</span>
  5. </div>
  6. <script>
  7. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  8. const vm = new Vue({
  9. el:'#root',
  10. data:{
  11. firstName:'张',
  12. lastName:'三',
  13. fullName:'张-三'
  14. },
  15. watch:{
  16. firstName(val){
  17. setTimeout(() => {
  18. console.log(this)
  19. this.fullName = val + "-" + this.lastName
  20. }, 1000);
  21. },
  22. lastName(val){
  23. this.fullName = this.firstName + '-' + val
  24. }
  25. }
  26. })
  27. </script>

十、绑定样式

  1. class样式
    写法:class="xxx" xxx可以是字符串、对象、数组。
    字符串写法适用于:类名不确定,要动态获取。
    对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
    数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用。
  2. style样式
    :style="{fontSize: xxx}"其中xxx是动态值。
    :style="[a,b]"其中a、b是样式对象。
  1. <div id="root">
  2. <!-- 绑定class样式--字符串写法,适用于:样式的类名不确定,需要动态指定 -->
  3. <div class="basic" :class="mood" @click="changeMood">{{name}}</div><br><br>
  4. <!-- 绑定class样式--数组写法,适用于:要绑定的样式个数不确定、名字也不确定 -->
  5. <div class="basic" :class="classArr">{{name}}</div><br><br>
  6. <!-- 绑定class样式--对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用 -->
  7. <div class="basic" :class="classObj">{{name}}</div><br><br>
  8. <!-- 绑定style样式--数组写法 -->
  9. <div class="basic" :style="styleArr">{{name}}</div><br><br>
  10. <!-- 绑定style样式--对象写法 -->
  11. <div class="basic" :style="styleObj">{{name}}</div><br><br>
  12. </div>
  13. <script>
  14. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  15. const vm = new Vue({
  16. el:'#root',
  17. data:{
  18. name:'中国',
  19. mood:'normal',
  20. classArr:['atguigu1','atguigu2','atguigu3'],
  21. classObj:{
  22. atguigu1:true,
  23. atguigu2:false,
  24. },
  25. styleArr:[
  26. {
  27. fontSize:'40px',
  28. color:'blue',
  29. },
  30. {
  31. backgroundColor:'gray'
  32. }
  33. ],
  34. styleObj:{
  35. fontSize:'40px',
  36. color:'red',
  37. },
  38. styleObj2:{
  39. backgroundColor:'orange'
  40. }
  41. },
  42. methods: {
  43. changeMood(){
  44. const arr = ['happy' , 'sad' , 'normal']
  45. const index = Math.floor(Math.random()*3)
  46. this.mood = arr[index]
  47. }
  48. },
  49. })
  50. </script>

十一、条件渲染

1.v-if
写法:
(1).v-if=”表达式”
(2).v-else-if=”表达式”
(3).v-else=”表达式”
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意:v-if可以和:v-else-ifv-else一起使用,但要求结构不能被“打断”。

2.v-show
写法:v-show=”表达式”
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉

3.备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。

  1. <div id="root">
  2. <h2>当前的n值是:{{n}}</h2>
  3. <button @click="n++">点我n+1</button>
  4. <!-- 使用v-show做条件渲染 -->
  5. <h2 v-show="false">欢迎来到{{address}}</h2>
  6. <h2 v-show="1 === 1">欢迎来到{{address}}</h2>
  7. <!-- 使用v-if做条件渲染 -->
  8. <h2 v-if="false">欢迎来到{{address}}</h2>
  9. <h2 v-if="1 === 1">欢迎来到{{address}}</h2>
  10. <!-- v-else和v-else-if -->
  11. <div v-if="n === 1">Angular</div>
  12. <div v-else-if="n === 2">React</div>
  13. <div v-else-if="n === 3">Vue</div>
  14. <div v-else>哈哈</div>
  15. <!-- v-if与template的配合使用 -->
  16. <template v-if="n === 1">
  17. <h2>你好</h2>
  18. <h2>中国</h2>
  19. <h2>北京</h2>
  20. </template>
  21. </div>
  22. <script>
  23. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  24. const vm = new Vue({
  25. el:'#root',
  26. data:{
  27. address:'中国',
  28. n:0
  29. },
  30. })
  31. </script>

十二、列表渲染

v-for指令:
1.用于展示列表数据
2.语法:v-for="(item, index) in xxx" :key="yyy"
3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)

  1. <div id="root">
  2. <!-- 便利数组 -->
  3. <h2>人员列表(便利数组)</h2>
  4. <ul>
  5. <li v-for="(p,index) of persons" :key="index">
  6. {{p.name}}-{{p.age}}
  7. </li>
  8. </ul>
  9. <!-- 遍历对象 -->
  10. <h2>汽车信息(遍历对象)</h2>
  11. <ul>
  12. <li v-for="(value,k) of car" :key="k">
  13. {{k}}-{{value}}
  14. </li>
  15. </ul>
  16. <!-- 遍历字符串 -->
  17. <h2>测试遍历字符串(用的少)</h2>
  18. <ul>
  19. <li v-for="(char,index) of str" :key="index">
  20. {{char}}-{{index}}
  21. </li>
  22. </ul>
  23. <!-- 遍历指定次数 -->
  24. <h2>测试遍历指定次数(用的少)</h2>
  25. <ul>
  26. <li v-for="(number,index) of 5" :key="index">
  27. {{index}}-{{number}}
  28. </li>
  29. </ul>
  30. </div>
  31. <script>
  32. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  33. const vm = new Vue({
  34. el:'#root',
  35. data:{
  36. persons:[
  37. {id:'001', name:'张三', age:18},
  38. {id:'002', name:'李四', age:19},
  39. {id:'003', name:'王五', age:20}
  40. ],
  41. car:{
  42. name:'奥迪',
  43. price:'70万',
  44. color:'黑色'
  45. },
  46. str:'hello'
  47. },
  48. })
  49. </script>

十三、表单

若:<input type="text"/>,则v-model收集的是value值,用户输入的就是value值。
若:<input type="radio"/>,则v-model收集的是value值,且要给标签配置value值。
若:<input type="checkbox"/>
1.没有配置inputvalue属性,那么收集的就是checked(勾选 or 未勾选,是布尔值)
2.配置inputvalue属性:
(1)v-model的初始值是非数组,那么收集的就是checked(勾选 or 未勾选,是布尔值)
(2)v-model的初始值是数组,那么收集的的就是value组成的数组
备注:v-model的三个修饰符:
lazy:失去焦点再收集数据
number:输入字符串转为有效的数字
trim:输入首尾空格过滤

  1. <div id="root">
  2. <form action="" @submit.prevent="demo">
  3. 账号:<input type="text" v-model.trim="userInfo.account"><br>
  4. 密码:<input type="password" v-model="userInfo.password"><br>
  5. 年龄:<input type="number" v-model.number="userInfo.age"><br>
  6. 性别:
  7. 男:<input type="radio" name="sex" value="1" v-model="userInfo.sex">
  8. 女:<input type="radio" name="sex" value="0" v-model="userInfo.sex">
  9. <br><br>
  10. 爱好:
  11. 学习:<input type="checkbox" value="1" v-model="userInfo.hobby">
  12. 打游戏:<input type="checkbox" value="2" v-model="userInfo.hobby">
  13. 吃饭:<input type="checkbox" value="3" v-model="userInfo.hobby">
  14. <br><br>
  15. 所属地区
  16. <select name="" id="" v-model="userInfo.city">
  17. <option value="">请选择地区</option>
  18. <option value="1">北京</option>
  19. <option value="2">上海</option>
  20. <option value="3">广州</option>
  21. <option value="4">深圳</option>
  22. </select>
  23. <br><br>
  24. 其他信息:
  25. <textarea name="" id="" cols="30" rows="10" v-model.lazy="userInfo.other"></textarea>
  26. <br><br>
  27. <input type="checkbox" v-model="userInfo.agree"><a href="#">阅读并接受</a>
  28. <button>提交</button>
  29. </form>
  30. </div>
  31. <script>
  32. Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
  33. new Vue({
  34. el:'#root',
  35. data:{
  36. userInfo:{
  37. account:'',
  38. password:'',
  39. age:18,
  40. sex:'0',
  41. hobby:[],
  42. city:'1',
  43. other:'',
  44. agree:''
  45. }
  46. },
  47. methods: {
  48. demo(){
  49. console.log(JSON.stringify(this.userInfo))
  50. }
  51. },
  52. })
  53. </script>
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议