Vue组件开发的属性

server/2024/10/23 22:33:18/

组件开发的属性:

1.ref属性:

如果在vue里,想要获取DOM对象,并且不想使用JS的原生语法,那么就可以使用ref属性

ref属性的用法:

1)在HTML元素的开始标记中,或者在Vue子组件中的开始标记中定义,相当于id的替代者

html元素上: <h1 ref="xxx"></h1> 
Vue组件上:  <School ref="xxx"></School>

2)获取方式: 在html标签上获取的是真实DOM元素,应用在组件标签上获取的是组件实例对象(vc)

this.$refs.ref属性的名字

2.scoped样式:就是让style样式只针对当前组件生效(是style标签的一个无值属性)

所有组件的style,都会被汇总到一起,如果style中设置的样式名有重复的,那么可能就会后引入的组件的样式会覆盖掉先引入组件的样式。

此时,我们可以在组件的style开始标记里,使用scoped属性,来设置style样式只针对当前组件生效,即局部生效。

3.组件通信属性

什么是组件通信:组件的数据是独立的,无法直接访问其他组件的数据,想使用其他组件的数据,就需要组件通信。组件通信,就是指组件与组件之间的数据传递

 通信解决方案:

 有父组件School和子组件Student

      父子通信流程:1.父组件School通过 props 将数据传递给子组件Student

<!-- 第一步: 先在子组件Student开始标记上添加属性和值 -->

      <!-- 注意:如果属性的值是表达式,需要在属性名前添加v-bind: 或者简写形式,  子组件会自动推断类型 -->

      <Student

        :name="schoolName"

        :address="schoolAddress"

        :age="age"

        :isMarry="isMarry"

      ></Student>

// 第二步:在子组件中添加props配置项, 配置在父组件中添加的各个属性名

  // 方式1:简单配置

  props: ["name", "address", "age", "isMarry"],

  //方式2:可以对属性进行约束类型,设置必要性,默认值

  //  props:{

  //     name:{

  //        type:String,

  //        required:true

  //     },

  //     age:{

  //        type:Number,

  //        default:100

  //     },

  //     isMarry:{

  //       type:Boolean,

  //       default:false

  //     }

  //   },

  // 第三步:可以直接在子组件中,使用props配置的各个属性名了。

methods: {

    showSchoolSendData() {

      console.log(this.name, this.address, this.age, this.isMarry);  //获取到父组件School发送过来的数据

    },

  },

2.子组件Student向父组件School发送数据

方式一:通过props方法向子组件传递一个函数

第一步:在子组件开始标签上通过props方法向子组件传递一个函数

<!-- 如果想要子组件传递过来的信息,可以向子组件通过props方法传递一个函数。该函数定义一些你想要的形参 -->

      <Student :getStudentData="getStudentData"></Student>

第二步:// 定义一个自己的函数,这个函数要传递给子组件,形参根据自己的需求来定义,

 methods: {

    getStudentData(name, age, gender, idcard) {

      console.log("----我是父组件--");

      console.log(name, age, gender, idcard);

    },

  },

第三步:

 //  获取父组件传递过来的函数属性

  props: ["getStudentData"],

第四步:

//定义一个方法来执行传过来的函数,也就是向父组件发送数据

 sendDataToSchool() {

        // 调用父组件传递过来的函数进行传参。

      this.getStudentData(this.studentName,this.studentAge,"abc",123);

    },

 方式二:  使用v-on或者简写方式绑定事件。

父组件监听:父组件通过在子组件的引用上使用v-on指令来监听子组件触发的事件。

绑定原理:

在编写的子组件标签上使用v-on或者@绑定自定义事件,实际上是将事件绑定到子组件实例对象的VueComponent上。当有人触发了子组件上的这个事件,就会回调绑定到该事件上的函数。

第一步:  使用v-on或者简写方式绑定事件。  注意:是在使用子组件的标签上,来绑定自定义事件    -->

      <Student @getStudentData="getStudentInfo"></Student>

第二步:

实现getStudentInfo函数,获取子组件传过来的数据

methods:{

            getStudentInfo(name,age){

                 console.log("我是父组件");

                console.log(name,age);

                this.sname=name

                this.sage=age

               

            }

        }

第三步:

写一个普通的点击事件向父组件发送消息

<button @click="sendDataToSchool">点我向School发送数据</button>

methods:{

            sendDataToSchool(){

               //当按钮被人点击时,会执行进入该方法,然后在该方法中,使用this.$emit来触发子组件身上的自定义事件getStudentData

                this.$emit("getStudentData",this.studentName,this.studentAge)

            }

        }

方式3:通过ref属性和$on绑定自定义事件

子组件触发:子组件通过调用vm.$emit来触发一个事件,该事件可以被父组件监听。

 第一步:给子组件实例直接绑定一个自定义事件,在mounted钩子函数中绑定

<!-- 子传父通信方式3:  在子组件实例上绑定一个自定事件    -->

      <Student ref="student"></Student>

配置项:

 mounted() {

    // 在该组件被挂在为真实DOM时,给子组件实例直接绑定一个自定义事件

    // 注意:不能使用匿名函数,因为匿名函数里的this是子组件实例

    // this.$refs.student.$on('getStudentData',function(name,age){

    //     console.log("------$on绑定事件--------");

    //     console.log(this);//this是子组件实例

    //     this.sname = name;

    //     this.sage = age;

    // })

    //  可以使用箭头函数,或者是methods里配置的方法, 这样的写法,方法体里的this都是本组件实例

    // this.$refs.student.$on('getStudentData',(name,age)=>{

    //     console.log("------$on绑定事件--------");

    //     console.log(this); //本组件实例

    //     this.sname = name;

    //     this.sage = age;

    // })

    this.$refs.student.$on('getStudentData',this.getStudentInfo)

  },

第二步:获取子组件传过来的数据

 methods: {

    getStudentInfo(name, age) {

      console.log("----我是父组件--");

      this.sname = name;

      this.sage = age;

    },

  },

第三步:

写一个普通的点击事件向父组件发送消息

<button @click="sendDataToSchool">点我向School发送数据</button>

//需要销毁自定义的事件 ,写一个按钮来自杀

<button @click="selfOff">移除自定义事件</button>

 methods: {

    sendDataToSchool() {

      // 当按钮被人点击时,会执行进入该方法,然后在该方法中,使用this.$emit来触发子组件身上的自定义事件

      this.$emit("getStudentData", this.studentName, this.studentAge);

    },

    selfOff() {

      this.$off("getStudentData");

    },

  },

//销毁自定义事件

  beforeDestroy() {

    this.$off("getStudentData");

  },

};

4. 自定义事件:

除了js中的内置事件,Vue还允许开发者自定义事件。在Vue实例上有以下四个方法,来完成自定义事件的各种操作:

  • vm.$on: 自定义事件监听的核心方法。它允许开发者在Vue实例上注册监听器,以响应特定的事件。

    -1).监听器注册通过vm.$on(eventName, callback)的形式,将callback函数注册为eventName事件的监听器。当事件被触发时,callback将被调用。(可以单独写callback,然后再进行调用   this.回调函数的名字)

    -2).执行顺序:事件触发时,所有注册的回调函数将按照它们注册的顺序依次执行。

  • vm.$emit: 自定义事件派发的核心方法。它允许开发者触发自定义事件,从而实现组件之间的通信。

    -1). 事件触发:通过vm.$emit(eventName)的形式,可以触发一个名为eventName的事件。
    -2). 参数传递:使用vm.$emit(eventName, arg1, arg2, ...)触发事件时,可以传递多个参数。这些参数将按顺序传递给监听器的回调函数callback。 

    ==vm.$emit在Vue组件系统中扮演着至关重要的角色,尤其是在子>父组件的通信中==

    -1).子组件触发:子组件通过调用vm.$emit来触发一个事件,该事件可以被父组件监听。
    -2).父组件监听:父组件通过在子组件的引用上使用v-on指令来监听子组件触发的事件。

  • vm.$off :移除自定义事件监听器的方法,它提供了一种机制来清理不再需要的事件监听,从而避免潜在的内存泄漏问题。

    -1) 移除机制:vm.$off([event, callback]),如果提供了事件名称和回调函数,则只移除特定的监听器;
    -2).如果没有提供参数,则移除所有事件的所有监听器。:   vm.$off()
    -3).灵活性:vm.$off的灵活性体现在可以根据实际情况选择移除单个监听器或全部监听器,以满足不同的开发需求。

    应用场景:

    -1).组件销毁:在Vue组件被销毁前,使用vm.$off移除所有注册的事件监听器,确保组件不会在销毁后继续触发事件,导致不可预期的行为。
    -2).条件性监听:在某些情况下,事件监听可能只在特定条件下需要,一旦条件不再满足,就应该使用vm.$off移除监听器,以避免不必要的资源占用。

  • vm.$once :提供了一种机制,允许事件只被监听一次,在事件触发后自动移除监听器。

    -1).场景应用:适用于那些只需要执行一次的事件处理,例如初始化操作或一次性资源的加载。
    -2).资源管理:通过确保监听器只触发一次,vm.$once有助于避免不必要的资源消耗和潜在的内存泄漏。

总结:组件的自定义事件

1)一种组件间通信的方式,适用于:子组件 ==发送数据==> 父组件通信

2)使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调函数在A中),在mounted钩子函数中绑定自定义事件

3)绑定自定义事件:

  • 第一种方式,在父组件中在子组件的开始标签中使用v-on或者@绑定自定义事件

  <Student @getStudentData="getStudentInfo"></Student>

  • 第二种方式,在父组件中: 使用ref和 $on  在mounted钩子函数中进行绑定

4)若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法

5)触发自定义事件:this.$emit('pClick',数据)

6)解绑自定义事件:this.$off('pClick')

7)组件上也可以绑定原生DOM事件,需要使用native修饰符

 <Demo @click.native=“f1()”>

注意:通过this.$refs.xxx.$on('pClick',回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!

5.全局事件总线: 任意组件之间通信

 两个并列组件的通信Teacher、Student组件

全局事件总线(GlobalEventBus)是一种可以在任意组件间通信的方式,本质上就是一个对象。它必须满足以下条件:

1. 所有的组件对象都必须能看见他  
2. 这个对象必须能够使用$on、$emit和$off方法去绑定、触发和解绑事件

步骤1)安装全局事件总线:

new Vue({
       ...
       beforeCreate() {     //vm实例出生之前
           Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
       },
    ...
})

 步骤2)使用事件总线:

Student给Teacher发送数据:

Student组件中:触发Teacher里绑定的事件

 <button @click="sendDataToTeacher">发送数据给Teacher</button>

 methods: {

    sendDataToTeacher() {

      // 应该触发Teacher里绑定的事件

      this.$bus.$emit("getStudentData", this.name, this.age);

    },

  },

 beforeDestroy() {   //销毁绑定事件

    this.$bus.$off("getStudentData");

  },

Teacher组件中:绑定事件,获取Student组件中的数据

 //   在mounted里绑定自定义事件

  mounted() {

    this.$bus.$on("getStudentData", this.getStudentData);

  },

methods: {

    getStudentData(name, age) {  把接收到的数据给自己的属性赋值

      this.sname = name;

      this.sage = age;

    },

  },

Teacher组件给Student组件发送数据:

在Teacher组件中:触发Student中绑定的事件

 <button @click="sendDataToStudent">发送数据给Student</button>

sendDataToStudent() {

      this.$bus.$emit("getTeacherData", this.name, this.age);

    },

 beforeDestroy(){

    this.$bus.$off("getTeacherData");

  }

Student组件中:

//   在mounted里绑定自定义事件,获取teacher里的数据

  mounted() {

    this.$bus.$on("getStudentData", this.getStudentData);

  },

methods: {

//把接收到的数据给自己的属性赋值

    getStudentData(name, age) {

      this.sname = name;

      this.sage = age;

    },

  },

6.消息订阅

装备工作:安装插件pubsub-js

在终端上输入如下命令:

npm i pubsub-js
或者
npm install pubsub-js

Teacher订阅消息,Student发布消息(即数据从Student到Teacher)

第一步:插件导入到想要使用的组件中

import PubSub from "pubsub-js";   

export default {      
  name: "Teacher",
  //....
};

第二步:Teacher订阅消息,一般在mounted里订阅

mounted() {

    // 使用subscribe("")来订阅消息,第一个参数表示主题,第二个参数是回调函数

    this.pubsubId = PubSub.subscribe("studentMessage", this.getStudentData);

  },

methods: {

    getStudentData(theme, data) {

      this.sname = data.name;

      this.sage = data.age;

    },

  },

需要取消订阅:

 beforeDestroy() {

    // 取消订阅

    PubSub.unsubscribe(this.pubsubId);

  },

第三步:Student发布者发布消息,别忘记也需要导入插件

<button @click="sendDataToTeacher">发送数据给Teacher</button>

// 导入消息订阅发布插件

import PubSub from "pubsub-js";

 methods: {

    // 该函数的第一个参数,就是用来描述主题的。 第二个参数用来获取对方发送过来的具体数据

    sendDataToTeacher() {

      PubSub.publish("studentMessage", { name: this.name, age: this.age });

    },

  },

Student订阅消息,Teacher发布消息(即数据从Teacher到Student)

第一步:导入插件

// 导入消息订阅发布插件

import PubSub from "pubsub-js";

第二步:Student订阅消息(Student组件中)

 mounted() {

    // 使用subscribe("")来订阅消息,第一个参数表示主题,第二个参数是回调函数

     this.pubsubId= PubSub.subscribe("teacherMessage", this.getTeacherData);

  },

 methods: {

    // 该函数的第一个参数,就是用来描述主题的。 第二个参数用来获取对方发送过来的具体数据    (回调函数    获取接受到的值,并且给属性赋值)

    getTeacherData(theme, data) {

      this.tname = data.name;

      this.tage = data.age;

    },

  },

//取消订阅

  beforeDestroy(){

    PubSub.unsubscribe(this.pubsubId)

  }

第三步:Teacher发布消息(即向Student发布数据),也要导入插件

<button @click="sendDataToStudent">发送数据给Student</button>  //发送数据给Student

import PubSub from "pubsub-js";

sendDataToStudent() {

      // 主动发布消息:  publish方法的解析:

      //  第一个参数:要写对方订阅的主题,

      //  第二个参数:准备发送的数据,最好使用对象形式,方便对方处理数据

      PubSub.publish("teacherMessage", { name: this.name, age: this.age });

    },

7.混入属性:mixins

混入,其实就是将多个组件共同的选项配置,单独封装起来,然后再引用回去。类似于java语言的静态方法封装,然后调用。

第一步:定义混入

export const mixin = {
    data(){ },
    methods: {},
    computed:{}
    //....
}

 第二步:应用混入

<script>
    //引入混入
    import {mixin} from '../mixin'
    
    export default {
        name:'School',
        data() {
            return {
                    name:'北京大学',
                        address:'海淀区颐和园路6号'
            }
        },
        mixins:[mixin]
    }
</script>

 混入的方式有两种:

  • 局部混入: 在组件中导入,然后使用选项 mixins:[…,…,..,]

  • 全局混入: 在main.js中导入,然后Vue.mixin(….)

特点:

1.组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”,在发生冲突时以组件优先

2.同名生命周期钩子将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。

8.plugins

第一步:定义插件,将插件内容写在一个plugins.js文件中

//可以写一些全局的配置,如过滤器,自定义事件

export default {   
   //因为涉及到全局配置,需要传参Vue
    install(Vue){
          //  全局配置过滤器
        Vue.filter('strFilter', function (value) {
            return value.substring(0, 4)
        })
    }
}

 第二步:引入插件,并应用。 在Vue创建实例之前

//引入插件文件
import plugins from './plugins'
//使用插件
Vue.use(plugins)

 第三步:使用插件中的一些功能即可

比如使用过滤器,自定义指令等

 9.slot插槽

插槽(Slot)是Vue提出来的一个概念。是Vue中常见的一种组件间的相互通信方式,作用是让父组件可以向子组件的指定位置插入html代码片段

父组件来决定要插入什么样的HTML代码片段(在使用子组件标签时,在标记体中给插槽slot赋值)。子组件使用<slot></slot>来决定传过来的HTML代码片段插入的具体位置(即子组件不写内容,使用slot占个位置)。

1.默认插槽:

-1. 在子组件的template中定义插槽
<template>
    <div>
      <!-- 定义插槽 -->
      <Slot>还没有被占用</Slot>
   <div>
</template>

-2. 在父组件的template中应用插槽
<template>
    <div>
      <子组件标签名>
         <!-- html代码片段 -->
       </子组件标签名>  
   <div>
</template>

 注意:默认插槽在子组件中只能使用一次,只能占据一个位置。如果重复使用默认插槽。那么父组件传过来的代码片段都会重复

2.具名插槽:就是在<Slot>标签中使用name属性指定了具体名字的插槽。这样在子组件中,就可以使用多个插槽来占位了。父组件中的HTML代码片段想要插入哪个插槽,就在代码的根标记上 使用 name='插槽的名字'就可以。

3.作用域插槽:

作用域插槽的特点,数据可以定义在子组件中,组件的使用者(父组件)来定义结构,并处理子组件传过来的数据或者部分自己的数据。

前两种插槽的特点是:数据和结构都是在父组件中定义的,只需要传入到子组件中的插槽位置即可。

子组件中:

<template>
    <div class="category">
        <h3>{{title}}分类</h3>
        <!-- 在插槽上自定义属性名以及data中的数据 
             :自定义属性名='data中的数据'
        -->

        <slot :gs="games">第一个插槽</slot>
    </div>
</template>

<script>
    export default {
        name:'Category',
        props:['title'],
        data() {        //子组件自己的数据
            return {
              games:["王者荣耀","和平精英","植物大战僵尸","黑神话:悟空"]
            }
        },
    }
</script>

父组件中:

<template>
  <div class="container">
      <Category title="游戏">
        <!-- 在template标签中使用slot-scope='{子组件中自定义属性名}' -->
        <template slot-scope="{gs}">

               //遍历数据
            <h4 v-for="(game,index) of gs" :key="index">{{game}}</h4>
            <a href="#">{{info}}</a>   //处理自己的数据
        </template>
      </Category>
  </div>
</template>
<script>
  import Category from './components/Category.vue'
  export default {
      name:'App',
      components: { Category },
      data() {
        return {
            info:"查看更多电影"
        }
      },
  }
</script>

10.Vue的axios

1.安装axios

npm install axios    (在vscode中)

2.引入axios

在script标签中:

import axios from 'axios';

 直接发送数据:会出现跨域的问题,即不能收到返回值

使用代理服务器:

第一种代理方式:

 devServer: {

            // 配置代理服务器,让代理服务器帮助我们访问另一个后端服务器,即8080

            // 第一种方式:简单配置一个单例,但是有缺点,不能配置多个,如果项目

            // public下有同名的文件路径,就不在执行代理服务器

             proxy: 'http://localhost:8088'     //要访问的服务器

}

axios发送数据:

//此时url访问的地址是代理服务器,也就是自己的服务器8080,(即前端自己的端口)

    f1(){

      axios({

        url:"http://localhost:8080/ssm_netctoss/fee/testVue",

        method:"post",

        headers:{'content-type':'application/x-www-form-urlencoded'},

        data:{"name": this.name, "age": this.age, "flag": this.flag},

      }).then(res=>{

        console.log("---res---");

        console.log(res.data);

      }).catch(error=>{

        console.log("------error-----");

        console.log(error);

      })

    },

第二种代理方式:

devServer: {        

         proxy:{

       

        //       // 可以配置多个

        //       // key:是一个url的过滤前缀,如果url上有key就执行对应的代理服务

        //       // http://localhost:8080/wang/ssm_netctoss/fee/testVue

               '/wang':{

              target:'http://localhost:8088',//用来配置最终的目标服务器的路径

               //http://localhost:8088/wang/ssm_netctoss/fee/testVue

               pathRewrite:{'^/wang':''},//将url里的前缀替换成空字符串,变成对应的正确路径

              //http://localhost:8088/ssm_netctoss/fee/testVue

              ws:true,//用于支持websocket。默认就是true

                 changeOrigin: true,//用于控制请求头中的host值。true表示使用代理目标服务器        的host。默认就是true

              },

              '/cong':{

                target:'https://api.oick.cn/yiyan/api.php',

                pathRewrite:{'^/cong':''},

              }

          }

}

发送数据:

//此时url访问的地址是代理服务器,也就是自己的服务器8080,(即前端自己的端口)

    f1(){

      axios({

        url:"http://localhost:8080/wang/ssm_netctoss/fee/testVue", 

        method:"post",

        headers:{'content-type':'application/x-www-form-urlencoded'},

        data:{"name": this.name, "age": this.age, "flag": this.flag},

      }).then(res=>{

        console.log("---res---");

        console.log(res.data);

      }).catch(error=>{

        console.log("------error-----");

        console.log(error);

      })

    },

    f2(){

      axios({

        url:"http://localhost:8080/cong",

        method:"post",

        headers:{'content-type':'application/x-www-form-urlencoded'},

        data:{"name": this.name, "age": this.age, "flag": this.flag},

      }).then(res=>{

        console.log("---res---");

        console.log(res.data);

      }).catch(error=>{

        console.log("------error-----");

        console.log(error);

      })

    }

  },


http://www.ppmy.cn/server/134273.html

相关文章

五、事务和并发控制及索引和性能优化

一. 事务和并发控制是数据库管理系统中用于处理多个用户并发访问共享数据的重要机制。 下面是对事务和并发控制的详细讲解和示例说明&#xff1a;事务&#xff1a; 事务是一组数据库操作的逻辑单元&#xff0c;它要么全部执行成功&#xff0c;要么全部回滚。事务通过保证数据操…

Win11 安装 PostgreSQL 报错解决方案

一、问题概述 在 Win11 系统中安装 PostgreSQL 时&#xff0c;可能会遇到“Problem running post-install”的报错情况。这一报错给用户带来了极大的困扰&#xff0c;使得安装过程无法顺利进行。 二、报错原因分析 &#xff08;一&#xff09;权限不足问题 在 Win11 中&…

windows免密ssh登录Linux

1.winr打开运行---- 输入&#xff1a;cmd&#xff08;命令提示符&#xff09; 查看系统是否自带openssh ssh -V 2.生成公钥私钥文件 ssh-keygen 3.进入秘钥存放目录 cd C:\Users\admin/.ssh/#查看秘钥文件 dir 4.将公钥文件长传至Linux服务器 scp .\id_rsa.pub root20.20.…

计算机网络基本架构实例1

家庭网络 1. 终端设备&#xff1a; - 家庭中的台式电脑、笔记本电脑、智能手机、平板电脑、智能电视等设备&#xff0c;用于上网、娱乐、学习等。 2. 通信链路&#xff1a; - 一般采用光纤接入互联网&#xff0c;通过光猫将光信号转换为电信号&#xff0c;然后连接到无线路由…

Linux 防火墙的开启、关闭、禁用命令

Linux 防火墙的开启、关闭、禁用命令 文章目录 Linux 防火墙的开启、关闭、禁用命令1.设置开机启用防火墙2.设置开机禁用防火墙3.启动防火墙4.关闭防火墙5.检查防火墙状态 1.设置开机启用防火墙 systemctl enable firewalld.service2.设置开机禁用防火墙 systemctl disable f…

深度学习——线性神经网络(三、线性回归的简洁实现)

目录 3.1 生成数据集3.2 读取数据集3.3 定义模型3.4 初始化模型参数3.5 定义损失函数3.6 定义优化算法3.7 训练 在上一节中&#xff0c;我们通过张量来自定义式地进行数据存储和线性代数运算&#xff0c;并通过自动微分来计算梯度。实际上&#xff0c;由于数据迭代器、损失函数…

首发Dell R730xd安装VMware Esxi 7.0U2A

哈喽大家好&#xff0c;欢迎来到虚拟化时代君&#xff08;XNHCYL&#xff09;。 “ 大家好&#xff0c;我是虚拟化时代君&#xff0c;一位潜心于互联网的技术宅男。这里每天为你分享各种你感兴趣的技术、教程、软件、资源、福利…&#xff08;每天更新不间断&#xff0c;福利…

从零开始学PHP之安装开发环境

前言 不整那些虚的&#xff0c;直接开始上干货&#xff0c;争取让小白也看得懂 环境选择 php开发环境一般分为集成环境和编译环境&#xff0c;由于编辑环境费时费力&#xff08;我没搞明白&#xff09;直接使用集成环境&#xff0c;市面上php的集成环境很多我这里用的是phps…