Vue组件——子组件向父组件传递数据以及路由

自定义事件

我们知道,父组件使用 prop 传递数据给子组件。但子组件怎么跟父组件通信呢?这个时候 Vue 的自定义事件系统就派得上用场了。

使用 绑定自定义事件v-on

每个 Vue 实例都实现了事件接口,即:

  • 使用 $on(eventName) 监听事件

  • 使用 $emit(eventName) 触发事件

Vue 的事件系统与浏览器的 EventTarget API 有所不同。尽管它们的运行起来类似,但是 $on 和 $emit 并不是addEventListener 和 dispatchEvent 的别名。

另外,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。
不能用 $on 侦听子组件释放的事件,而必须在模板里直接用 v-on 绑定,参见下面的例子。

//定义子组件
var Child = {
//获取data()中的数据,并添加一个点击事件
    template: ``,
    data(){
        return {
            counter: 0
        }
    },
    methods:{
        addCounter(){
            this.counter++;
            //自定义事件$emit传回根组件,同时调用根组件方法
            this.$emit('add-parent-total')
        }
    }
}
//根组件
var vm = new Vue({
    el: "#app",
    data:{
        total: 0
    },
    components: {
        Child
    },
    methods: {
//根组件中子组件改变根组件的方法
        addTotal(){
            this.total++
        }
    }
})

//html

使用插槽分发内容

注意两点:

  • 组件不知道它会收到什么内容。这是由使用 的父组件决定的。

  • 组件很可能有它自己的模板。

为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为内容分发 (即 Angular 用户熟知的“transclusion”)。Vue.js 实现了一个内容分发 API,参照了当前 Web Components 规范草案,使用特殊的 元素作为原始内容的插槽。

//slot插槽使其可以在html中传入数据,也可以在其中传入默认内容
var Child = {
    template: `
1 默认内容
` } var vm = new Vue({ el: "#app", components: { Child } }) html hello

有名slot

    //slot插槽使其可以在html中传入数据,也可以在其中传入默认内容
var Child = {
    template: `
1 header 默认内容 footer
` } var vm = new Vue({ el: "#app", components: { Child } }) html
头部内容
22222
底部内容

非父子组件

有时候,非父子关系的两个组件之间也需要通信。在简单的场景下,可以使用一个空的 Vue 实例作为事件总线:

    var bus = new Vue()
        var AppHead = {
        template: '
', methods: { add() { // 触发组件A中的事件 bus.$emit('change', 1) } } } var AppBody = { template: '
{ { counter }}
', data() { return { counter: 0 } }, created() { //在组件B创建的钩子中监听事件 bus.$on('change', count => { this.counter += count }) } } var vm = new Vue ({ el: '#app', components: { AppHead, AppBody } })

模态框实例




  
  
  
  Document
  


  

注册

登录

vue路由

对于大多数单页面应用,都推荐使用官方支持的 vue-router 库。更多细节可以看 vue-router 文档。

静态路由

不需要复杂的路由

首先需要
npm i -S vue-router 安装router库
        var NewsComponent = { template: `
新闻
`} var ShopComponent = { template: `
商场
`} var NotFoundComponent = { template: `
404
`} var routes = [ { path: '/', redirect: '/news'//默认根目录跳转 }, { path: '/news', component: NewsComponent }, { path: '/shop', component: ShopComponent }, { path: '*', component: NotFoundComponent } ] var router = new VueRouter({ routes }) // var app = new Vue({ // el: "#app", // router // }) var app = new Vue({ el: "#app", router })

动态路由

var Goods = {
      template: `
  • { { good.goods_name }} { { good.price }}
`, watch: { $route (to, from) { console.log(to.params.id); axios.get('http://h6.duchengjiu.top/shop/api_goods.php?cat_id='+to.params.id).then(res => { console.log(res.data.data) this.goods = res.data.data }) } }, data() { return { goods: [] } } } var router = new VueRouter({ routes: [ { path: '/cat/:id', component: Goods } ] }); var vm = new Vue({ el: '#app', router, data: { cats: [] }, created() { axios.get('http://h6.duchengjiu.top/shop/api_cat.php').then(res => { console.log(res) this.cats = res.data.data }) } });

你可能感兴趣的:(javascript,php)